应使用哪种 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":
- 从
IClock
实施开始,例如 SystemClock.Instance
。
- 通过在时钟上调用
.Now
获得 Instant
。
- 确定您希望 "now" 反映的时区。立即使用
.InZone
投射到该区域的 ZonedDateTime
。
- 从那里开始,拆分满足您正在使用的场景所需的任何组件。例如,您可以调用
.Date
来获取 LocalDate
实例以用于您询问的第一个场景。
一般来说,尽量避免调用DateTime.Now
或DateTime.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;
我正在构建一个需要计算 'how many weeks/months/years are there between two dates' 之类的应用程序,我的所有用户都来自同一个时区。
我想知道,为此使用 LocalDateTime
(因为我只使用一个时区)还是 ZonedDateTime
(考虑到可能的 DST 和偏移量更改)更好?
还有,我做的对吗
LocalDateTime.FromDateTime(DateTime.UtcNow)
对于第一种情况,使用 LocalDate
类型以及 Period.Between
方法。
对于第二种情况,您 可以 构造一个类似的 LocalDateTime
,但是结果值将反映 "UTC day" - 这是人为的构造。
只要你需要 "now":
- 从
IClock
实施开始,例如SystemClock.Instance
。 - 通过在时钟上调用
.Now
获得Instant
。 - 确定您希望 "now" 反映的时区。立即使用
.InZone
投射到该区域的ZonedDateTime
。 - 从那里开始,拆分满足您正在使用的场景所需的任何组件。例如,您可以调用
.Date
来获取LocalDate
实例以用于您询问的第一个场景。
一般来说,尽量避免调用DateTime.Now
或DateTime.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;