首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么WinForms DateTimePicker最多支持12/31/9998 23:59:59,而不是12/31/9999 23:59:59

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

Stack Overflow用户
提问于 2014-06-13 22:26:06
回答 3查看 1.2K关注 0票数 3

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

EN

回答 3

Stack Overflow用户

发布于 2014-06-13 23:07:41

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

代码语言:javascript
复制
    [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属性设置器调用本机控件来设置日期之前,会在Value属性设置器中检查这些限制。

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

  • COM日期不能低于1900。这是Lotus程序员在开发曾经占主导地位的电子表格程序"123“时采用的捷径。他没有处理1900年不是闰年的问题。微软不得不在Excel中复制这个bug,以保持它与Lotus电子表格的兼容性。
  • 1753年,在DateTimePicker.MinDateTime中使用,是Sybase程序员的捷径,也就是开发SQL Server的公司。那一年,英国从儒略历改为公历。这导致了15天的迷失,由于没有正确处理闰年,导致儒略日期漂移的数量。不需要处理无效的日期显然是可取的。将这个限制放到DTP中可以避免数据绑定problems.
  • DateTime.MinDate成为0年,这是不必处理负DateTime.Tick值的捷径。
  • DateTime.MaxDate是10000年,这是绕过TimeSpan.TotalMilliseconds问题的捷径。它返回一个双精度值,这是一种最多具有15位有效数字的值类型。超过10,000需要更多的数字。

这启发了对9998年的解释,在接近DateTime.MaxDate的时候有很多令人讨厌的问题。例如,SQL Server在午夜前3毫秒死机,.NET在午夜前100纳秒死机。DateTimePicker使用的是本地时间,这会导致在整个12月31日的各个时区都会超过MaxDate。因此,这位微软程序员做了大多数其他程序员在他之前做过的事情,他走了一条捷径:

代码语言:javascript
复制
    public static DateTime MaximumDateTime {
        get {
             DateTime maxSupportedDateTime = CultureInfo.CurrentCulture.Calendar.MaxSupportedDateTime;
             if (maxSupportedDateTime.Year > MaxDateTime.Year)
             {
                 return MaxDateTime;
             }
             return maxSupportedDateTime;
         }
    }

当然,这从来不是一个真正的问题,处理那么久以后的日期是没有意义的。如果需要在自己的代码中进行某种有效性检查,请使用MaximumDateTime属性。

票数 5
EN

Stack Overflow用户

发布于 2014-06-13 23:11:55

这是另一个不能回答的问题,但可能对某些人有用。根据我的评论中的WINAPI路由,SYSTEMTIME被限制为1601年到1601年之间的日期,因为它基于FILETIME结构,该结构将时间存储为自#1/1/ 30827 #以来100 as的64位计数。它进一步只允许values less than 0x8000000000000000,这导致了30827年的上限。

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

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

{编辑:1601 date for SYSTEMTIME的理由似乎是它是公历中400年周期的前一个开始。仍然无助于解释#12/31/9998#。}

票数 2
EN

Stack Overflow用户

发布于 2014-06-13 22:58:55

这不是一个恰当的答案(尽管我仍在努力挖掘)。查看源代码,在DateTimePicker中定义了一个字段

代码语言:javascript
复制
[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属性如下所示:

代码语言:javascript
复制
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字段。

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24207679

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档