为什么TimeSpan没有Age属性?

问题描述 投票:11回答:5

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

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();
    }
}

我发现在Years上没有TimeSpan属性是由两个DateTime对象的减法产生的。我对此感到有些惊讶。我想到为什么可能没有Years。我认为可能是因为闰日,但按照这个逻辑,由于夏令时,不应该有Days

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

我能够写一些不同的代码来获得正确的年龄,但我仍然想知道为什么在Years上没有WeeksTimeSpan属性。有谁知道原因?

c# datetime timespan
5个回答
7
投票

程序员的生活真的很难。

年份的长短是多变的。有些年有365天,有些有366天。 According to the calendar,有些年甚至可能有失踪的日子。如果谈论文化,由于中国农历一年可以有13个月,因此变得更加困难。

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

由于夏令时,一天的长度是可变的,这不仅取决于文化,还取决于地理。

由于leap seconds,小时和分钟的长度是可变的。

似乎唯一可靠的是一秒钟的长度。因此在内部,时间跨度以秒(或毫秒,相同)存储。

但时间单位的变化使答案“n秒的数量(年/月/日/小时/分钟)?”永远不准确。

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


10
投票

TimeSpan仅包含两个DateTime值之间的差异。不知道这个TimeSpan在哪一年。这也是为什么它没有Months财产。

例:

TimeSpan.FromDays(60)

那几个月了? 1还是2?


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

由于闰年,没有标准的年份长度。

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

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


4
投票

修辞问题:没有参考点,一年有多长?

由于TimeSpan没有固定的时间点,因此无法明确说明未知时间每年会持续多长时间。在最简单的情况下,它可能是365或366天。有更多的案例会影响结果。


2
投票

我认为这可能是因为闰日,但按照这个逻辑,因为夏令时不应该有天。

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

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

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

TimeSpan没有多年的原因是年份的长度不同。夏令时问题是你如何计算TimeSpan并且可以被规避的结果,但是没有“线性年”可以用来规避闰年。


1
投票

Timespan只存储毫秒数。如果你有(1000 * 60 * 60 * 24 * 365.5)365.5天的毫秒数,那么就不可能知道这个毫秒数是否会跨越一整年并进入下一年,如果它只是短短一年,或者跨越一年三年。相同的是30.5天的毫秒,可能会持续到第二个月,可能不到一个月,可能跨越三个月。

© www.soinside.com 2019 - 2024. All rights reserved.