【问题标题】:Nodatime calculation of years/months/days in X daysNodatime 计算 X 天内的年/月/日
【发布时间】:2014-05-12 19:40:20
【问题描述】:

假设我有678天,如何计算从那一刻起有多少年、多少月、多少天?

Duration duration = Duration.FromStandardDays(678);
Instant now = SystemClock.Instance.Now;
Instant future = now + duration;

// I have to convert NodaTime.Instant to NodaTime.LocalDate but don't know how

Period period = Period.Between(now, future);
Console.WriteLine("{0} years, {1} months, {2} days", period.Years, period.Months, period.Days);

【问题讨论】:

标签: c# nodatime


【解决方案1】:

你只需要在当前时间加上天数:

var now = DateTime.Now;
var future = now.AddDays(678);

int years = future.Year - now.Year;
int months = future.Month - now.Month;
if (months < 0)
{
    years--;
    months += 12;
}
int days = future.Day + DateTime.DaysInMonth(now.Year, now.Month) - now.Day;

【讨论】:

  • 如果我加上 365 天,结果是 1 年、0 个月和 30 天!如果我加上 60 天,结果是 0 年、2 个月和 29 天!有什么不对劲!我该如何解决?
【解决方案2】:

Noda Time 确实可以做到这一点。

首先,您需要一个起点。这使用当地时区的当前日期。您可能希望使用不同的日期或不同的时区,具体取决于您的情况。

Instant now = SystemClock.Instance.Now;
DateTimeZone timeZone = DateTimeZoneProviders.Bcl.GetSystemDefault();
LocalDate today = now.InZone(timeZone).Date;

然后只需添加天数:

int days = 678;
LocalDate future = today.PlusDays(days);

然后您可以获得所需单位的期间:

Period period = Period.Between(today, future, PeriodUnits.YearMonthDay);
Console.WriteLine("{0} years, {1} months, {2} days",
                  period.Years, period.Months, period.Days);

重要的是要认识到结果代表“从现在开始的时间”。或者,如果您替换为不同的起点,则为“从 (起点)开始的时间”。在任何情况下,您都不应该认为结果是X days = Y years + M months + D days。这将是荒谬的,因为一年中的天数和一个月中的天数取决于您所谈论的年份和月份。

【讨论】:

  • 感谢您的回答!请原谅我的无知...我添加了 Noda 时间参考,但收到错误“错误 1 ​​'NodaTime.DateTimeZoneProviders' 不包含 'Bcl' 的定义”
  • 自第一个版本以来就一直存在。不知道为什么你会得到一个错误,除非它是一个简单的错字。 (docs here)。当然,您可以使用Tzdb 提供程序,或者选择与您的用例相关的任何时区。您确实需要时区,因为回答“今天是星期几”这个问题取决于时区,即使您只关心日期而不是时间。
  • Noda Time 的 PCL 版本中不提供 BCL 提供程序;这也可以解释错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多