为什么使用WinForms DateTimePicker';s支持12/31/9998 23:59:59的最大值,而不是12/31/9999 23:59:59

为什么使用WinForms DateTimePicker';s支持12/31/9998 23:59:59的最大值,而不是12/31/9999 23:59:59,winforms,datetimepicker,Winforms,Datetimepicker,有人知道为什么控件不支持更高的值,如12/31/9999吗?我正在寻找这个问题的具体原因。这不是一个正确的答案(尽管我仍在努力挖掘)。查看源,在日期时间选择器中定义了一个字段: [Browsable(false)] [EditorBrowsable(EditorBrowsableState.Never)] public static readonly DateTime MaxDateTime = new DateTime(9998, 12, 31); 在你的问题中,你会问为什么它是“12/31

有人知道为什么控件不支持更高的值,如12/31/9999吗?我正在寻找这个问题的具体原因。

这不是一个正确的答案(尽管我仍在努力挖掘)。查看源,在
日期时间选择器中定义了一个字段:

[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
public static readonly DateTime MaxDateTime = new DateTime(9998, 12, 31);
在你的问题中,你会问为什么它是“12/31/9998 23:59:59”,而实际上它只是“12/31/9998 00:00:00”,这几乎更为奇怪

然后我寻找这个领域的用途。它似乎仅用作日期时间选择器的绝对界限,而不是其他任何东西。实际上,
MaximumDateTime
属性如下所示:

public static DateTime MaximumDateTime
{
  get
  {
    DateTime supportedDateTime = CultureInfo.CurrentCulture.Calendar.MaxSupportedDateTime;
    if (supportedDateTime.Year > DateTimePicker.MaxDateTime.Year)
      return DateTimePicker.MaxDateTime;
    else
      return supportedDateTime;
  }
}
因此,最大日期实际上是由当前区域性定义的支持的最大日期或
日期时间选择器支持的绝对最大日期定义的,以年份部分中较小的日期为准。对于“en-US”区域性,支持的最大日期等于
DateTime.MaxValue
,因此在Team中使用
MaxDateTime
字段


同样,这并不是为了回答为什么要使用特定值,而是为了更深入地了解它在
DateTimePicker
本身中的使用方式。

来自DateTimePicker.cs源代码文件,如下所示:

这些限制在值属性设置器中检查,然后再由本机控件设置日期

无法100%确定这些限制来自何处。他们确实遵循共同的模式,程序员走捷径以避免处理棘手的问题。一些常见的例子:

  • COM日期不能低于1900。这是一个Lotus程序员所走的捷径,他正在开发曾经占主导地位的电子表格程序“123”。他没有提到1900年不是闰年。微软不得不在Excel中复制该缺陷,以使其与Lotus电子表格兼容
  • 1753年,DateTimePicker.MinDateTime中使用的是Sybase程序员所走的捷径,这是一家创建SQL Server的公司。那一年,英格兰从儒略历改为格里高利历。这导致了15天的损失,朱利安的日期由于没有正确处理闰年而漂移。不必处理无效日期显然是可取的。将该限制放入DTP可以避免数据绑定问题
  • DateTime.MinDate为0年是不必处理负DateTime.Tick值的快捷方式
  • DateTime.MaxDate是10000年,这是解决TimeSpan.Total毫秒问题的快捷方式。它返回一个double,该值类型最多有15个有效数字。超过10000需要更多的数字
这激发了对9998年的解释,在接近DateTime.MaxDate时有很多令人讨厌的问题。例如,SQL Server在午夜前3毫秒关闭,.NET在午夜前100纳秒关闭。DateTimePicker使用本地时间,这会导致在12月31日的一天中,不同时区的MaxDate被超过。因此,这位微软程序员做了他之前大多数程序员做的事情,他走了一条捷径:

    public static DateTime MaximumDateTime {
        get {
             DateTime maxSupportedDateTime = CultureInfo.CurrentCulture.Calendar.MaxSupportedDateTime;
             if (maxSupportedDateTime.Year > MaxDateTime.Year)
             {
                 return MaxDateTime;
             }
             return maxSupportedDateTime;
         }
    }

当然,这从来都不是一个真正的问题,处理如此遥远的未来是没有意义的。如果您需要在自己的代码中进行某种有效性检查,请使用MaximumDateTime属性。

这是另一个非答案,但可能对某些人有用。按照我的评论中的WINAPI路径,
SYSTEMTIME
被限制在1601到30827之间的日期,因为它基于一个文件时间结构,该结构将时间存储为自#1/1/1601#以来的64位计数100ns。它进一步只允许,这导致了30827年的上限

NET DateTimePicker控件基于,因此它至少有这些限制是合理的。文档中提到1753年从儒略历到公历的转换,这可能解释了.NET控件中编码的
\1/1/1753
限制

这可能有助于解释下限,但仍然不能解释上限。除非开发团队有人插话,否则“为什么?”的唯一答案可能是“因为它是”


{编辑:这似乎是公历400年周期的前一个开始。这仍然无助于解释#12/31/9998#。}

因为这是yyyy可以保持的最大值?我本以为是这样的obvious@RachelGallen我不确定我是否同意你的评论
DateTime.MaxValue
毕竟是“12/31/9999 11:59:59 PM”。这并不是对这个问题的真正回答,但一个相关的问题是类似的:我不是问你的目的是什么,而是问你为什么不能使用9999。有一篇博文建议你可以使用反射改变最大值,但作者表示,他不确定存在限制的原因以及导致这种攻击的副作用:我认为这可能是WINAPI的潜在限制,因为值#1/1/1753#和#12/31/9998#是在DateTimePicker源代码中硬编码的。DateTimePicker确实在幕后引用了一个SYSTEMTIME结构,但该结构支持从1601年到30827年的时间,所以这似乎不是原因。好帖。非常感谢。
    public static DateTime MaximumDateTime {
        get {
             DateTime maxSupportedDateTime = CultureInfo.CurrentCulture.Calendar.MaxSupportedDateTime;
             if (maxSupportedDateTime.Year > MaxDateTime.Year)
             {
                 return MaxDateTime;
             }
             return maxSupportedDateTime;
         }
    }