应使用哪种 Noda 时间类型来计算特定日期和今天之间的 years/months/days?

Which Noda Time type should be used to calculate years/months/days between a specific date and today?

我正在构建一个需要计算 'how many weeks/months/years are there between two dates' 之类的应用程序,我的所有用户都来自同一个时区。

我想知道,为此使用 LocalDateTime(因为我只使用一个时区)还是 ZonedDateTime(考虑到可能的 DST 和偏移量更改)更好?

还有,我做的对吗

LocalDateTime.FromDateTime(DateTime.UtcNow)

对于第一种情况,使用 LocalDate 类型以及 Period.Between 方法。

对于第二种情况,您 可以 构造一个类似的 LocalDateTime,但是结果值将反映 "UTC day" - 这是人为的构造。

只要你需要 "now":

  1. IClock 实施开始,例如 SystemClock.Instance
  2. 通过在时钟上调用 .Now 获得 Instant
  3. 确定您希望 "now" 反映的时区。立即使用 .InZone 投射到该区域的 ZonedDateTime
  4. 从那里开始,拆分满足您正在使用的场景所需的任何组件。例如,您可以调用 .Date 来获取 LocalDate 实例以用于您询问的第一个场景。

一般来说,尽量避免调用DateTime.NowDateTime.UtcNow。当然,有些地方您可以使用它作为捷径,但 API 不一定会引导您得出正确的结论。

总结这两种情况:

// assuming you start with a DateTime, perhaps from a db.
DateTime dt = new DateTime(2016,1,1);
LocalDate ldt = LocalDateTime.FromDateTime(dt).Date;

DateTimeZone tz = DateTimeZoneProviders.Tzdb["America/New_York"];
ZonedDateTime now = SystemClock.Instance.Now.InZone(tz);
LocalDate today = now.Date;

Period period = Period.Between(today, ldt, PeriodUnits.YearMonthDay);

int years = (int) period.Years;
int months = (int) period.Months;
int days = (int) period.Days;

此外,请注意,在 Noda Time 2.0(目前处于 alpha 阶段)中,它会变得更简单一些:

DateTime dt = new DateTime(2016, 1, 1);
LocalDate ldt = LocalDate.FromDateTime(dt); // 2.0

DateTimeZone tz = DateTimeZoneProviders.Tzdb["America/New_York"];
LocalDate today = SystemClock.Instance.InZone(tz).GetCurrentDate();  // 2.0

Period period = Period.Between(today, ldt, PeriodUnits.YearMonthDay);

int years = (int)period.Years;
int months = (int)period.Months;
int days = (int)period.Days;