从代表自纪元以来的天数的整数创建 joda DateTime 的实例?

Create instance of joda DateTime from integer representing # of days since epoch?

在我的应用程序中,它保存了一个偏好,它是一个整数,表示自纪元以来的天数。 (不相关但用于每 x 天创建备份)

鉴于此值,我如何才能可靠地创建 joda DateTime 的实例?

我很想通过乘法将其转换为毫秒 value * 24 * 60 * 60 * 1000 但由于天文学/太阳时,这将是错误的?

According to the FAQ:

Joda-Time does not support leap seconds. Leap seconds can be supported by writing a new, specialized chronology, or by making a few enhancements to the existing ZonedChronology class. In either case, future versions of Joda-Time will not enable leap seconds by default. Most applications have no need for it, and it might have additional performance costs.

这表明您不必担心这方面的问题。

但我不做数学运算,而是使用 DateTime#plusDays or MutableDateTime#addDays,以 The Epoch 为起点。

不过,我假设您的 "days since The Epoch" 允许飞跃 (并且您使用的是公历年表,所以 JodaTime 也是)。

如果使用库函数,将天数乘以毫秒数可能更具可读性。我强烈推荐使用 Joda。 :)

自纪元 (GMT) 以来您有许多天数,并且您想要一个 DateTime(日期 + 时间 + 时区)。至少,在您进一步了解之前,您需要指定您希望如何处理时间和时区计算。

最简单的方法(这可能不是您想要的)是在本地时区创建一个代表纪元开始的时刻,然后使用 plusDays 添加正确的天数:

// in class - note that this will cache the current default timezone
private static final DateTime EPOCH_START_INSTANT = new DateTime(0);

// West of Greenwich, this will actually represent the "day" before.
// Day 0 will be Dec 31, 1969, local time.
DateTime localTime = EPOCH_START_INSTANT.plusDays(yourDayCount);

为了每 X 天创建一次备份,您可能需要一个在纪元(1970 年 1 月 1 日)初始化的 LocalDate,加上您想要的天数。然后可以相对轻松地将其更改为指定的当地时间。

// in class
private static final EPOCH_LOCALDATE = new LocalDate(1970, 1, 1);
private static final THREE_AM = new LocalTime(3, 0);

LocalDate localDate = EPOCH_LOCALDATE.plusDays(yourDayCount);

// Midnight (or closest valid time thereto) in the default time zone
DateTime startOfDay = localDate.toDateTimeAtStartOfDay();

// 3 AM in the default time zone
DateTime threeAM = localDate.toDateTime(THREE_AM);

Jeff Bowman 的 是正确的。

我将在 java.time 框架中展示相同的想法,旨在接替 Joda-Time。

java.time

Java 8 及更高版本内置了新的 java.time 框架。这些新的 classes 取代了旧的 java.util.Date/.Calendar classes。它们的灵感来自 Joda-Time,由 JSR 310 定义,并由 ThreeTen-Extra 项目扩展。

我假设您的从纪元开始的天数在 UTC. So we can use the Instant class 中,基本上是从 1970 年第一时刻开始的纳秒计数(UTC)。

long myCountOfDays = 16_721L;
Instant instant = Instant.EPOCH.plus ( myCountOfDays , ChronoUnit.DAYS );

让我们调整到一个时区。随意选择蒙特利尔。使用 proper time zone name,不要使用像 "EST" 或 "IST".

这样的 3-4 字母代码
ZoneId zoneId = ZoneId.of ( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant ( instant , zoneId );

转储到控制台。

System.out.println ( "myCountOfDays: " + myCountOfDays + " from epoch: " + Instant.EPOCH + " in UTC is: " + instant + " and in Montréal is: " + zdt + "." );

当运行.

myCountOfDays: 16721 from epoch: 1970-01-01T00:00:00Z in UTC is: 2015-10-13T00:00:00Z and in Montréal is: 2015-10-12T20:00-04:00[America/Montreal].