我正在使用以下代码。为了简单起见,值(小时、分钟、秒、日期、月、年、星期几)被硬编码。
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/