【问题标题】:Get java.util.Calendar from days since epoch从纪元以来的天数获取 java.util.Calendar
【发布时间】:2011-05-23 07:57:24
【问题描述】:

我有一个变量,其中包含自 1970-01-01epoch reference date 到某个日期以来的天数。

有人知道将此变量转换为java.util.Calendar 的方法吗?

【问题讨论】:

标签: java date calendar


【解决方案1】:

在 Java 8 及更高版本中使用 java.time 类。一行:

LocalDate date = LocalDate.ofEpochDay(1000);

调用ofEpochDay(long epochDay)从纪元日计数中获取LocalDate的实例。

【讨论】:

  • 仅供参考:java.time 的大部分功能都在ThreeTen-Backport 中向后移植到 Java 6 和 7。在ThreeTenABP 项目中进一步适用于Android。
  • 你知道API为什么要为epochDay写这么复杂的逻辑吗?看起来很混乱
  • 我不明白你的评论。
  • 如果你查看方法 api,它的编写逻辑有点庞大。
  • 大部分that source code 用于处理leap year
【解决方案2】:

以下应该有效:

Calendar c = new GregorianCalendar();
c.setTime(new Date(0));

c.add(Calendar.DAY_OF_YEAR, 1000);

System.err.println(c.getTime());

关于时区的说明:

使用运行程序的系统的默认时区创建一个新的GregorianCalendar 实例。由于 Epoch 与 UTC(Java 中的 GMT)相关,因此必须小心处理任何不同于 UTC 的时区。下面的程序说明了这个问题:

TimeZone.setDefault(TimeZone.getTimeZone("GMT-1"));

Calendar c = new GregorianCalendar();
c.setTimeInMillis(0);

System.err.println(c.getTime());
System.err.println(c.get(Calendar.DAY_OF_YEAR));

c.add(Calendar.DAY_OF_YEAR, 1);
System.err.println(c.getTime());
System.err.println(c.get(Calendar.DAY_OF_YEAR));

打印出来

Wed Dec 31 23:00:00 GMT-01:00 1969
365
Thu Jan 01 23:00:00 GMT-01:00 1970
1

这表明仅使用 e.g. 是不够的。 c.get(Calendar.DAY_OF_YEAR)。在这种情况下,必须始终考虑到它是一天中的什么时间。这可以通过在创建GregorianCalendar:new GregorianCalendar(TimeZone.getTimeZone("GMT")) 时显式使用 GMT 来避免。如果日历是这样创建的,则输出为:

Wed Dec 31 23:00:00 GMT-01:00 1969
1
Thu Jan 01 23:00:00 GMT-01:00 1970
2

现在日历返回有用的值。 c.getTime() 返回的Date 仍然“关闭”的原因是toString() 方法使用默认的TimeZone 来构建字符串。在顶部,我们将其设置为 GMT-1,因此一切正常。

【讨论】:

  • 与到目前为止的所有其他答案一起,这将为 UTC 之前(西部)的时区提供不正确的日期,除非您在评估结果时考虑时区(添加一天)。
  • @jarnbjo:我无法在测试中确认这一点。能举个小例子吗?
  • 添加"TimeZone.setDefault(TimeZone.getTimeZone("GMT-1"));"在您的代码之前添加一天而不是 1000(以使问题显而易见)。输出将是 1970 年 1 月 1 日,但预计会在 1 月 2 日。
  • @jarnbjo:为什么不出所料? Date 的输出是 Thu Jan 01 23:00:00 GMT-01:00 1970。这与另一个 TZ 中的时间完全相同。 Unix 时间总是相对于 UTC(相关维基百科文章中提到的所有警告)。
  • 我必须承认这个问题有点模棱两可,但我很难接受 1970 年 1 月 1 日之后的一天应该是 1970 年 1 月 1 日。
【解决方案3】:
Calendar cal = new GregorianCalendar();
cal.setTimeInMillis(0);
cal.add(Calendar.DAY_OF_MONTH, daysSinceEpoch);

【讨论】:

    猜你喜欢
    • 2012-12-24
    • 2010-09-13
    • 2013-05-02
    • 2021-08-10
    • 2012-12-11
    • 2016-05-14
    • 2016-12-23
    • 2017-02-20
    相关资源
    最近更新 更多