gpt4 book ai didi

Java:为什么 Calendral.setTimeInMillis(0) 设置错误的时间

转载 作者:行者123 更新时间:2023-12-02 01:00:10 24 4
gpt4 key购买 nike

我的 Android 应用程序(在 Java 中,在 Android Studio 中)使用类“Calendar”。之后

Calendar cal=Calendar.getInstance();
cal.setTimeInMillis(0);
Log.i("Interim",cal.getTime().toString());

此类输出正在生成:I/Interim: Thu Jan 01 03:00:00 GMT+02:00 1970。我的时区是 GMT+02:00(乌克兰基辅),不适用一月的夏令时。为什么日历时间设置为 03:00?我期望 00:00(不考虑时区)或 02:00(考虑时区),但为什么是 03:00?

预先感谢您的任何想法

PS 为了澄清情况,我将 Calendar 时区设置为 GMT 并获取小时值:

Calendar cal=Calendar.getInstance(TimeZone.getTimeZone("GMT"));
cal.setTimeInMillis(0);
Log.i("Interim hours",Integer.toString(cal[i].get(Calendar.HOUR)));
Log.i("Interim",cal.getTime().toString());

与预期相反,输出是:

I/Interim hours: 0

I/Interim: Thu Jan 01 03:00:00 GMT+02:00 1970

因此,小时字段的值为 0,但时间为 03:00。我刚刚听说 1975 年 6 月 13 日大约有 1 小时轮类(请参阅下面的答案),但这似乎只涉及越南 TZ,不是吗?

最佳答案

请区分时区偏移。您的时区是欧洲/基辅(时区 ID 中地名的英文拼写适用于存在英文拼写的地方)。欧洲/基辅一月份的偏移量为 +02:00。 10 月 27 日之前偏移量为 +03:00,由于夏令时(夏令时,DST),从 3 月 29 日起再次偏移。可能会让一些人感到惊讶的是,从 1944 年到 1980 年,它的偏移量永久为 +03:00。因此,在该纪元(UTC 时间 1970 年 1 月 1 日 00:00),乌克兰的时间为 3:00。因此,对于乌克兰来说,这部分输出是正确的。

简而言之:时区包含该时区使用的 UTC/GMT 的历史、当前和已知 future 偏移量。 GMT+02:00 是一个偏移量,它不是一个时区。

java.time 和 ThreeTenABP

这是获得我认为您想要的东西的现代方法:

    ZonedDateTime epochInUkraine = Instant.EPOCH.atZone(ZoneId.of("Europe/Kiev"));
System.out.println(epochInUkraine);

这些行的输出是:

1970-01-01T03:00+03:00[Europe/Kiev]

如果您想要类似于打印老式 java.util.Date 对象的打印输出:

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern(
"EEE MMM dd HH:mm:ss zzz yyyy", Locale.ROOT);
System.out.println(epochInUkraine.format(formatter));

Thu Jan 01 03:00:00 EET 1970

不过,您也许可以找到更适合您的受众的输出格式。我把这部分留给你自己。

出了什么问题?

Why does Calendar.setTimeInMillis(0) set incorrect time?

事实并非如此。 Calendar 类及其子类设计不佳且早已过时,但 setTimeInMillis(0) 可以设置正确的时间。您还已经注意到,当您的日历采用UTC时,其上午或下午的时钟时间(0到11)为0。您如何获得03:00:00 GMT的输出+02:00 03:00 和 +02:00 之间存在矛盾吗?可能的解释包括:

  • 很可能是您这边的错误。这要么不是来自您设置为 0 的日历,要么是您在输入问题时不准确地复制了输出。如果您再次检查是否可以重现该输出,我很想听听。
  • Date.toString() 中不太可能存在错误,当您打印从 cal.getTime() 获取的 Date 时,该错误会被隐式调用
  • Calendar.getTime() 中的错误不太可能为您提供 Calendar 中错误的 Date 对象。

问题:java.time 不需要 Android API 级别 26 吗?

java.time 在旧版和新版 Android 设备上都能很好地工作。它只需要至少 Java 6

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

链接

关于Java:为什么 Calendral.setTimeInMillis(0) 设置错误的时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60771089/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com