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

时间:2018-04-02 11:08:11

标签: java android date calendar

我正在使用以下代码。为简单起见,值(小时,分钟,秒,日期,月份,年份,day_of_week)都是硬编码的。

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日。我看到月份的第一天是4月和7月的周日。它在剩下的时间里工作正常

问题 1)月份的第一天(星期一)会导致这种差异吗?将它改为SUNDAY似乎在这两天工作。但我不确定这是否适用于所有场景。

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

1 个答案:

答案 0 :(得分:2)

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

当默认语言环境为日语或泰语时,最终结果为March。不知何故,JVM默认语言环境会影响Calendar的内部,以某种神秘的方式,我必须承认,这超出了我的理解范围。但无论如何,解决它的一种方法是在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")使用特定时区 - 替换“区域名称”与any valid IANA zone's names