为什么 TimeSpan 没有 Years 属性?

Why does TimeSpan not have a Years property?

我正在编写一个转换器,它可以获取一个人的出生日期并生成他们的年龄(以年为单位)。我写了一些看起来像这样的东西:

public class DateOfBirthToAgeConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var date = value as DateTime?;
        if (date == null) return null;
        return (DateTime.Now - date).Years;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

我发现 TimeSpan 上没有 Years 属性 是两个 DateTime 对象相减的结果。对此我有些意外。我想了想为什么可能没有Years。我想这可能是因为闰日,但按照这个逻辑,不应该有 Days 因为夏令时。

没有 Months 是有道理的,因为没有标准的月份长度。

我能够编写一些不同的代码来获取正确的年龄,但我仍然很想知道为什么 [=13] 上没有 YearsWeeks 属性 =]. 有谁知道原因吗?

反问:没有参照点,一年有多久?

因为TimeSpan没有固定的时间点,所以无法在未知的时间明确地说出一年有多长。在最简单的情况下,它可能是 365 或 366 天。影响结果的案例要多得多。

A TimeSpan 仅包含两个 DateTime 值之间的 差异。这个 TimeSpan 是哪一年是未知的。这也是它没有 Months 属性.

的原因

示例:

TimeSpan.FromDays(60)

那是几个月? 12?


The absence of Months made sense since there is no standard month length.

因为闰年也没有标准的年份长度。

解决方法:如果你真的想显示一个近似值,那么TimeSpan.TotalDays / 365.2425就可以了。

编辑:但仅用于粗略估计,不适用于生日。在生日计算中,正如 Henk Holterman 在评论中指出的那样,闰日将每 4 年累积一次。看看here生日计算

I figured that it might be because of the leap day, but by that logic, there shouldn't be Days because of daylight savings.

你说得有道理;减去两个日期不能理想地处理夏令时。如果日期是当地时间,您可能会得到意想不到的结果。

夏令时的变化意味着当地时间的差距或重叠,如果您对日期进行计算,则会忽略这一点。因此,如果您想获得两个本地时间 DateTime 值之间的确切差异,您应该先将它们转换为 UTC,因为它具有线性时间:

TimeSpan diff = date1.ToUniversalTime() - date2.ToUniversalTime();

TimeSpan 没有年份的原因是年份的长度不同。夏令时问题是您如何计算 TimeSpan 的结果,可以规避,但没有 "linear years" 可以用来规避闰年。

Timespan 只存储毫秒数。如果您有 (1000 * 60 * 60 * 24 * 365.5) 365.5 天的毫秒数,则无法知道该毫秒数是否跨越一整年和下一年,是短于一年,还是跨越三年。与 30.5 天的毫秒数相同,可能跨越第二个月,可能不到一个月,可能跨越三个月。

程序员的生活真的很辛苦

年的长度是可变的。有些年份有 365 天,有些年份有 366 天。 According to the calendar,有些年份甚至会缺天。如果谈论文化就更难了,因为中国农历一年有 13 个月。

月的长度是可变的,这是众所周知的。这也是要知道在其他日历中事情会变得更糟。

白天的长度是可变的,因为夏令时,这不仅取决于文化,还取决于地理位置。

小时和分钟的长度是可变的,因为 leap seconds。

似乎只有一秒的长度是可靠的。所以在内部,时间跨度以秒(或毫秒,相同)为单位存储。

但是时间单位的可变性使得答案"how many (years/months/days/hours/minites) for n seconds?"总是不准确。

这就是为什么开发人员最终得到了一个实用但不精确的解决方案。他们只是忽略了夏令时和闰秒。但是,由于人们几乎不问年和月,所以他们决定不回答这些问题。