{"id":112711,"date":"2026-09-21T07:00:00","date_gmt":"2026-09-21T14:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/oldnewthing\/?p=112711"},"modified":"2026-09-22T09:23:37","modified_gmt":"2026-09-22T16:23:37","slug":"20260921-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20260921-00\/?p=112711\/","title":{"rendered":"What&#8217;s the highest legal <CODE>FILETIME<\/CODE>? Is it safe to use?"},"content":{"rendered":"<p>A customer wanted to define a sentinel <code>FILETIME<\/code> that will be considered larger than another <code>FILETIME<\/code>. In other words, <code>Compare\u00adFile\u00adTime<\/code> should always say that the sentinel value is later. What&#8217;s a good value to use?<\/p>\n<p>Strictly according to the definition, the <code>FILETIME<\/code> consists of ticks since January 1, 1601, and it is an unsigned value, so the highest value is presumably <code>0xFFFFFFFF`FFFFFFFF<\/code>.<\/p>\n<p>On the other hand, the documentation for <code>FILETIME<\/code> itself notes that some functions consider the value <code>0xFFFFFFFF`FFFFFFFF<\/code> to have special meaning. For example, the <code>Set\u00adFile\u00adTime<\/code> function treats that value as meaning &#8220;Do not update the time for this handle.&#8221;<\/p>\n<p>Any values larger than <code>0x7FFFFFFF`FFFFFFFF<\/code> will also cause problems because functions like <code>Create\u00adWaitable\u00adTimer<\/code> treat <code>FILETIME<\/code>s with the high bit set as representing the negative of a relative duration rather than an absolute point in time. Also, some programs consider those values to represent times that comes <i>before<\/i> January 1, 1601.<\/p>\n<p>And then there are functions like <code>File\u00adTime\u00adTo\u00adSystem\u00adTime<\/code> which also reject <code>FILETIME<\/code> values greater than <code>0x7FFFFFFF`FFFFFFFF<\/code>. So you&#8217;re probably best off not going above <code>0x7FFFFFFF`FFFFFFFF<\/code>.<\/p>\n<p>But wait, you may also want to be concerned about code that does time zone adjustments or things like &#8220;One day later&#8221;. If you give them the value at the extreme end of the range, the adjustment may trigger an overflow into a negative value. Is that okay? I mean, you did try to go beyond the maximum value. It sort of depends on what you&#8217;re using this sentinel value for.<\/p>\n<p>Interestingly, you can ask <code>File\u00adTime\u00adTo\u00adSystem\u00adTime<\/code> to convert <code>0x7FFFFFFF`FFFFFFFF<\/code> to a <code>SYSTEMTIME<\/code>, and it will give you a date in the year 30828, but if you try to convert it back, <code>System\u00adTime\u00adTo\u00adFile\u00adTime<\/code>\u00a0fails. It can dish it out, but it can&#8217;t take it.<\/p>\n<p>The <code>System\u00adTime\u00adTo\u00adFile\u00adTime<\/code> function supports dates only through the end of the year 30827. If you try to get the last millisecond of the year 30827, you will get some value, but the precise number will depend on how many leap seconds have been stored in the leap second database.<\/p>\n<p>Meanwhile, the CLR <code>System.<wbr \/>DateTime<\/code> caps at the end of the year 9999. And some calendars like the ChineseLunisolarCalendar have an even lower maximum supported date. (For ChineseLunisolarCalendar, the maximum supported date is somewhere in early 2101 because <a href=\"https:\/\/github.com\/microsoft\/referencesource\/blob\/ec9fa9ae770d522a5b5f0607898044b7478574a3\/mscorlib\/system\/globalization\/chineselunisolarcalendar.cs#L277\"> that&#8217;s as far as the tables go<\/a>.) Other programming languages will have their own limits on the range of a date.<\/p>\n<p>Okay, so what value should you use?<\/p>\n<p>It depends on what you&#8217;re using it for.<\/p>\n<p>If you need a number that simply compares larger than any other value when compared with <code>Compare\u00adFile\u00adTime<\/code>, you can use <code>0xFFFFFFFF`FFFFFFFF<\/code>, which is the largest value supported by <code>Compare\u00adFile\u00adTime<\/code>.<\/p>\n<p>However, you shouldn&#8217;t let that value escape your code that understands the value&#8217;s special sentinel meaning. If you let that very large value escape, then somebody might do a time zone conversion or say &#8220;Great, let me set an alarm for 1 day later,&#8221; or try to convert it to a C# <code>System.<wbr \/>Date\u00adTime<\/code> and encounter an overflow.<\/p>\n<p>if you need a special value for use outside your code, you should find some other way of specifying that special value, like as a <code>std::optional<\/code> for C++ or a <code>Nullable&lt;DateTime&gt;<\/code> for C#. That way, each consumer can map the result to something appropriate for their specific language.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Being wary of how people use it and how it interacts with other types.<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-112711","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Being wary of how people use it and how it interacts with other types.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/112711","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=112711"}],"version-history":[{"count":1,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/112711\/revisions"}],"predecessor-version":[{"id":112716,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/112711\/revisions\/112716"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=112711"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=112711"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=112711"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}