Calendar.setTimeInMillis 錯誤 - 為什麼會這樣?



日历得到错误的Unix时间,就像我得到的那样。

long millis = 1568814839L;
System.out.println(millis); //1568814839
Calendar.getInstance(TimeZone.getTimeZone("Asia/Tashkent"));
calendar.setTimeInMillis(millis);
System.out.println(calendar.get(Calendar.MILLISECOND));//839

我该怎么办?日历.YEAR应该是2019年,这个毫秒。但是,日历给了我1970年,为什么?

该错误是由于您将时间(以毫秒为单位(和时间(以秒为单位(混淆所致。1568814839L是自 1970 年 1 月 1 日以来的秒数,但您将其视为毫秒。 这很容易检查:

long millis = 1568814839L;
System.out.println(millis); //1568814839
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("Asia/Tashkent"));
System.out.println(calendar.getTimeInMillis()); //1568820981321
calendar.setTimeInMillis(millis);
System.out.println(calendar.get(Calendar.YEAR));//839

这将产生:

1568814839
1568820981321
1970

如您所见,您的数字相差 3 个数量级。 在米利斯数的末尾加上三个 0:

long millis = 1568814839000L;
...
System.out.println(calendar.get(Calendar.YEAR));

现在你得到:

1568814839000
1568821211006
2019

java.time

现代代码将使用java.time,即现代Java日期和时间API。

将自 1970-01-01T00:00Z 以来的整数秒数输入到Instant类:

ZonedDateTime zdt = Instant.ofEpochSecond(1_568_814_839L)
.atZone(ZoneId.of("Asia/Tashkent"));
System.out.println(zdt);
System.out.println("Year: " + zdt.getYear());
System.out.println("Millisecond of second: "
+ zdt.get(ChronoField.MILLI_OF_SECOND));

输出为:

2019-09-18T18:53:59+05:00[Asia/Tashkent]
Year: 2019
Millisecond of second: 0

正如其他人所说,你的数字是自纪元以来的秒数,而不是毫秒。

问:我可以在 Android 上使用 java.time 吗?

是的,java.time在较旧和较新的Android设备上运行良好。它只需要至少Java6

  • 在 Java 8 及更高版本以及较新的 Android 设备(从 API 级别 26(中,内置了现代 API。
  • 在Java 6和7中获取ThreeTen Backport,现代类的反向移植(JSR 310的ThreeTen;请参阅底部的链接(。
  • 在(较旧的(Android上使用Android版本的ThreeTen Backport。它被称为ThreeTenABP。并确保从带有子包的org.threeten.bp导入日期和时间类。

链接

  • Oracle 教程:日期时间解释如何使用 java.time。
  • Java 规范请求 (JSR( 310,其中首次描述了java.time
  • ThreeTen Backport 项目,将java.time向 Java 6 和 7 的反向移植(ThreeTen 用于 JSR-310(。
  • ThreeTenABP,ThreeTen Backport 的安卓版
  • 问:如何在Android项目中使用ThreeTenABP,并进行了非常详尽的解释。

最新更新