我正在编写一个转换器,它可以记录一个人的出生日期并生成他们多年的年龄。我写了一些看起来像这样的东西:
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
上没有Weeks
或TimeSpan
属性。 有谁知道原因?
答案 0 :(得分:10)
TimeSpan
仅包含两个DateTime
值之间的差异。不知道这个TimeSpan
在哪一年。这也是它没有Months
属性的原因。
示例:强>
TimeSpan.FromDays(60)
这是几个月? 1 或 2 ?
没有月份是有意义的,因为没有标准的月份长度。
由于闰年,没有标准的年份长度。
解决方法:如果您确实要显示近似值,那么执行TimeSpan.TotalDays / 365
就可以了。
编辑:但仅限于粗略估计而非生日。在生日计算中,Henk Holterman在评论中指出,闰日将每4年累积一次。看一下here来计算生日。
答案 1 :(得分:7)
程序员的生活真的很难。
年份的长短是可变的。有些年份有365
天,有些则有366
天。 According to the calendar,有些年甚至可能错过了几天。如果谈论文化,由于中国农历一年可以有13个月,因此变得更加困难。
月份的长度是可变的,这是众所周知的。这也是要知道在其他日历中事情会变得更糟。
由于夏令时,一天的长度是可变的,这不仅取决于文化,还取决于地理位置。
小时和分钟的长度是可变的,因为leap second s。
似乎唯一可靠的是一秒钟的长度。所以在内部,时间跨度存储在几秒钟内(或毫秒,这是相同的)。
但是时间单位的变化使答案“n
秒钟的数量(年/月/日/小时/分钟)?”总是不准确。
这就是为什么开发人员最终会得到一个实用但不精确的解决方案。他们完全忽略了夏令时和闰秒。然而,由于人们几乎不会问几年和几个月,他们只是决定不回答这些问题。
答案 2 :(得分:4)
修辞问题:没有参考点,一年有多长?
由于TimeSpan没有固定的时间点,因此无法明确说明未知时间的一年多长时间。在最简单的情况下,它可能是365或366天。有更多的案例会影响结果。
答案 3 :(得分:2)
我认为这可能是因为闰日,但按照这个逻辑, 因为夏令时不应该有天。
你有一点意见;减去两个日期并不能理想地处理夏令时。如果日期是当地时间,您可能会得到意想不到的结果。
夏令时的变化意味着当地时间的差距或重叠,如果您使用日期进行计算,则会忽略该变化。因此,如果您想获得本地时间的两个DateTime
值之间的确切差异,则应首先将它们转换为UTC,因为它具有线性时间:
TimeSpan diff = date1.ToUniversalTime() - date2.ToUniversalTime();
TimeSpan
没有多年的原因是年份的长度不同。夏令时问题是您计算TimeSpan
的方式的结果,可以被规避,但是没有“线性年”可以用来规避闰年。
答案 4 :(得分:1)
Timespan只存储毫秒数。如果你有(1000 * 60 * 60 * 24 * 365.5)365.5天毫秒的时间,那么就不可能知道这个毫秒数是否会跨越一整年并进入下一年,如果它只是短于一年,或者如果它跨越三年。相同的是30.5天的毫秒,可能会持续到第二个月,可能不到一个月,可能跨越三个月。