java - 日历类在不同设备上给出不同的日期

标签 java android date calendar

我正在使用以下代码。为了简单起见,值(小时、分钟、秒、日期、月、年、星期几)被硬编码。

Calendar c = Calendar.getInstance();
c.set(Calendar.HOUR_OF_DAY, 10);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
c.set(Calendar.DATE, 2);
c.set(Calendar.MONTH, Calendar.APRIL);
c.set(Calendar.YEAR, 2018);
c.setFirstDayOfWeek(Calendar.MONDAY);
c.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);

String date = String.format(Locale.US, "%1$tA %1$tb %1$td %1$tY at %1$tI:%1$tM %1$Tp", c);
Log.e("date", date);

观察1

此代码在 Titanium S1 (Android 4.1.2) 上打印以下内容

E/date: Monday Mar 26 2018 at 10:00 AM

此代码在 Moto G4+ (Android 7.0)、Moto G5+ (Android 7.0) 上打印以下内容

E/date: Monday Apr 02 2018 at 10:00 AM

观察2 据我所知,这种差异仅出现在 4 月 2 日和 7 月 2 日。我看到四月和七月的第一天都是星期日。其余时间都可以正常工作

问题 1)每月的第一天(星期一)是否会导致这种差异?改成SUNDAY 看来这两天可行。但我不确定这是否适用于所有场景。

这会影响我的应用程序的用户。请帮忙。谢谢。

最佳答案

我在 JDK 7 中做了一些测试,结果似乎不受 setFirstDayOfWeek 的影响。实际上,它似乎与 JVM 默认语言环境(java.util.Locale)有关。

当默认区域设置为日语或泰语时,最终结果为三月。不知何故,JVM 默认区域设置以某种神秘的方式影响了 Calendar 的内部结构,我必须承认,这超出了我的理解范围。但无论如何,解决此问题的一种方法是在日历中设置与输出中使用的相同区域设置:

Calendar c = Calendar.getInstance(Locale.US);

这解决了我的问题。

java.time API

这种奇怪的行为是不使用旧的 Calendar API 的原因之一(顺便说一句,有 many others)。

在 Android 中,可以使用 java.time API 。在 API 级别 26 中,java.time classes可用。对于较低级别,您可以使用 this backport - 并在 this link有在 Android 中配置它的说明。

使用这个新的 API,可以更轻松地获得您想要的内容,并且更不容易出错。要构建特定的日期/时间,请使用 ZonedDateTime 类和 DateTimeFormatter 将其转换为特定格式的 String:

// April 2nd 2018, 10 AM
ZonedDateTime dt = ZonedDateTime.of(2018, 4, 2, 10, 0, 0, 0, ZoneId.systemDefault());
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("EEEE MMM dd yyyy 'at' hh:mm a", Locale.US);
String formattedDate = dt.format(fmt); // Monday Apr 02 2018 at 10:00 AM

请注意,星期几会根据提供的日/月/年值自动调整。

要获取当前日期/时间,只需使用 ZonedDateTime.now(ZoneId.systemDefault()) (获取 JVM 默认时区中的当前日期/时间),或使用 ZoneId .of("zone name") 使用特定时区 - 将“zone name”替换为 any valid IANA zone's names .

关于java - 日历类在不同设备上给出不同的日期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49610104/

相关文章:

java - 需要帮助访问 Jar 文件中的数据文件

java - Selenium : How to solve org. openqa.selenium.InvalidElementStateException: 无效元素状态

Android:如何将从 SQL 数据库返回的每个元组作为文本放在按钮上?

android - 如何使用 Android Studio 运行单元测试

java - onOptionsItemSelected 发生致命异常

Javascript 根据新日期仅获取偶数小时周期

java - 来自用户的字符串输入在 case 语句中没有被接受?

java - Json Deserializer - 如何从父 JSON 对象获取数据

c# - 查找年日期的 dd/mm 格式的算法?

java - 时间减法有什么问题?