为什么WinForms DateTimePicker支持最大12/31/9998 23:59:59,而不是12/31/9999 23:59:59

时间:2014-06-13 14:26:06

标签: winforms datetimepicker

有谁知道为什么控件不支持像12/31/9999这样的更高值?我正在寻找这个的特殊原因。

3 个答案:

答案 0 :(得分:5)

从DateTimePicker.cs源代码文件中可以看到ReferenceSource site

    [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
    public static readonly DateTime MaxDateTime = new DateTime(9998, 12, 31);

    [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
    public static readonly DateTime MinDateTime = new DateTime(1753, 1, 1);

在将属性控件设置为日期之前,会在Value属性设置器中检查这些限制。

不是100%确定这些限制的来源。他们确实遵循共同模式,程序员采取捷径以避免处理尴尬的问题。一些常见的例子:

  • COM日期不能低于1900.这是Lotus程序员采用的捷径,处理曾经占主导地位的电子表格程序“123”。他没有处理1900年不是闰年。 Microsoft必须在Excel中复制该错误,以使其与Lotus电子表格兼容。
  • 1753年,在DateTimePicker.MinDateTime中使用的是Sybase程序员(启动SQL Server的公司)所采用的快捷方式。那是英格兰从朱利安换到格里高利日历的那一年。这导致了15天的迷失,朱利安约会因未适当处理闰年而徘徊的数量。不必处理无效日期显然是可取的。将此限制纳入DTP可避免数据绑定问题。
  • DateTime.MinDate是年份0是不必处理负DateTime.Tick值的快捷方式。
  • DateTime.MaxDate是10,000年是TimeSpan.TotalMilliseconds问题的捷径。返回 double ,这是一个最多包含15位有效数字的值类型。超过10,000需要更多数字。

这激发了对9998年的解释,有很多icky问题接近DateTime.MaxDate。例如,SQL Server在午夜前3毫秒,在午夜前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属性。

答案 1 :(得分:2)

这是另一个非答案,但也许对某人有用。在我的评论中遵循WINAPI路线,SYSTEMTIME仅限于1601和30827之间的日期,因为它基于FILETIME结构,该结构将时间存储为自#1/1/1601以来的64位计数100ns刻度# 。它进一步只允许values less than 0x8000000000000000,这导致30827年的上限。

.NET DateTimePicker控件基于WINAPI Date and Time Picker control,因此它至少具有这些限制是有意义的。文档提到了1753年从Julian到Gregorian日历的转换,这可以解释编码到.NET控件中的#1/1/1753#限制。

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

{编辑:1601 date for SYSTEMTIME的理由似乎是在公历前的公历中,这是400年周期的开始。仍然没有帮助解释#12/31/9998#。}

答案 2 :(得分:0)

这不是一个正确的答案(尽管我还在努力挖掘)。查看源代码,DateTimePicker

中定义了一个字段
[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;
  }
}

因此,最大日期实际上由当前文化定义的最大支持日期或DateTimePicker支持的绝对最大值定义,以年份为准。对于" en-US"文化支持的最大日期等于DateTime.MaxValue,因此MaxDateTime字段用于insteam。

同样,这并不意味着回答为什么使用特定值,而是要更深入地了解如何在DateTimePicker内使用它。