我正在使用以下代码。为简单起见,值(小时,分钟,秒,日期,月份,年份,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似乎在这两天工作。但我不确定这是否适用于所有场景。
这会影响我的应用上的用户。请帮忙。谢谢。
答案 0 :(得分:2)
我在JDK 7中进行了一些测试,结果似乎没有受到setFirstDayOfWeek
的影响。实际上,它似乎与JVM默认语言环境(java.util.Locale
)有关。
当默认语言环境为日语或泰语时,最终结果为March。不知何故,JVM默认语言环境会影响Calendar
的内部,以某种神秘的方式,我必须承认,这超出了我的理解范围。但无论如何,解决它的一种方法是在Calendar
中设置你在输出中使用的相同语言环境:
Calendar c = Calendar.getInstance(Locale.US);
这解决了我的问题。
这种奇怪的行为是不使用旧的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。