{"id":131,"date":"2014-12-11T18:54:59","date_gmt":"2014-12-11T18:54:59","guid":{"rendered":"http:\/\/www.baruchyoussin.com\/?p=131"},"modified":"2015-02-08T18:11:47","modified_gmt":"2015-02-08T18:11:47","slug":"java-incorrect-time-zone-bug-windows","status":"publish","type":"post","link":"https:\/\/baruchyoussin.com\/en\/java-incorrect-time-zone-bug-windows.html","title":{"rendered":"Java incorrect time zone bug on Windows"},"content":{"rendered":"<br \/>\n<h2><span id=\"current_time_zone_in_java\">Current time zone in Java<\/span><\/h2>\n<p> \t\tMany programs need to be able to find out the current time of the \t\tcomputer they are running on, and its time zone, without hard coding \t\tit. For this purpose Java has the concept of default time zone which \t\tis an instance of \t\t<code>TimeZone<\/code> \t\tclass which is returned by \t\t<code>java.util.TimeZone.getDefault()<\/code> \t\t. However, this time zone has often been incorrect on Windows \t\tcomputers. I first bumped into this problem in the beginning of 2014. \t\tI developed a Java desktop application which involved displaying the \t\tcurrent time. On Linux, the displayed time was fine but on Windows XP \t\tthe Java default time zone was incorrect, not Asia\/Jerusalem but \t\trather America\/Bahia which was 5 hours off. \t<\/p>\n<p> \t\tAn internet search showed a long history of similar complaints on Java \t\tincorrectly reading the default time zone on Windows. The <a \t\t\thref=\"http:\/\/techtavern.wordpress.com\/2010\/04\/15\/java-and-incorrect-timezone-on-windows-xp\/\"> \t\t\tmost clear and comprehensive account I have found<\/a>, was due to Daniel \t\tFerbers of Brasil, dated 2010. Among other things, this account \t\tdetails how time zone information in the registry is getting corrupt. \t\tAmong other accounts are <a \t\t\thref=\"http:\/\/www.java-forums.org\/new-java\/24123-time-zone-problem-windows.html\"> \t\t\ta Java Forums report of 2009<\/a> and <a \t\t\thref=\"http:\/\/oraclesoon.blogspot.co.il\/2010\/04\/windows-7-and-java-jdk-16-timezone.html\"> \t\t\ta discussion of Sun and Oracle bugs (2010, Syngapore)<\/a>. Here is a more \t\trecent <a \t\t\thref=\"http:\/\/www.coderanch.com\/t\/571854\/java\/java\/Time-Zone-Issues-Windows\"> \t\t\t2012 report from India<\/a> and <a \t\t\thref=\"http:\/\/stackoverflow.com\/questions\/18979861\/timezone-value-changes-per-jdk-version\"> \t\t\t2013 report<\/a>. \t<\/p>\n<p> \t\tI have found also a <a \t\t\thref=\"http:\/\/www-01.ibm.com\/support\/docview.wss?uid=swg21250503\"> \t\t\tbrief IBM report<\/a> of 2009. \t<\/p>\n<p>In June &#8211; July 2014 this bug stopped showing up any more on my \t\tWindows XP computer, apparently, due to a Java update from Oracle.<\/p>\n<p> \t\tThere is a similar problem with time redirection on terminals running \t\ton Windows 2008 servers which is reported <a \t\t\thref=\"http:\/\/stackoverflow.com\/questions\/16302342\/time-zone-is-not-working-properly-in-windows-server\"> \t\t\there<\/a> and it has an <a \t\t\thref=\"http:\/\/bugs.java.com\/bugdatabase\/view_bug.do?bug_id=7044727\"> \t\t\tunresolved bug report on Oracle<\/a>, (reported 2011, unresolved as I \t\twrite it in July 2014). \t<\/p>\n<p>What happens, in brief, is that Java maintains its own time zone \t\tdatabase (containing the info about all daylight savings time changes \t\tin all regions of the world) and goes to Windows registry to find \t\twhich time zone the computer is using; this is the picture that \t\ttranspires from Daniel Ferbers&#8217; account.<\/p>\n<p>There are two issues here: (1) how to find the current time zone \t\ton a Windows computer, and (2) the overall design of Java time zones \t\tattempting to be smarter than the computer they run on. We shall \t\tconsider each issue separately.<\/p>\n<h2><span id=\"how_to_find_the_current_time_zone_on_windows\"> \t\t<span id=\"CurrentTimeZoneOnWindows\">How to find the current \t\t\ttime zone on Windows<\/span> \t<\/span><\/h2>\n<p>Microsoft specifications mention three different ways to do \t\tthis:<\/p>\n<ol>\n<li>The time zone information is written in the registry.<\/li>\n<li>There are time zone functions in the native API, the C \t\t\truntime library.<\/li>\n<li>There are time zone functions in managed API which is based \t\t\ton .NET Framework \u2013 Microsoft Common Language Runtime (CLR).<\/li>\n<\/ol>\n<p>It appears that none of these approaches is good for Java \t\tpurposes, as I shall try to explain below.<\/p>\n<h2><span id=\"time_zone_in_windows_registry\">Time zone in Windows registry<\/span><\/h2>\n<p>The first way to find out the current time zone on Windows is \t\tthrough the registry.<\/p>\n<p> \t\tMicrosoft has a <a \t\t\thref=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/ms725481%28v=vs.85%29.aspx\"> \t\t\tspecification<\/a> how time zone information is written in the registry; \t\tsee also <a \t\t\thref=\"http:\/\/blogs.msdn.com\/b\/bclteam\/archive\/2007\/06\/07\/exploring-windows-time-zones-with-system-timezoneinfo-josh-free.aspx\"> \t\t\there<\/a>. (The place where the current time zone information is written \t\tin the registry is indicated in <a \t\t\thref=\"http:\/\/techtavern.wordpress.com\/2010\/04\/15\/java-and-incorrect-timezone-on-windows-xp\/\"> \t\t\tDaniel Ferber&#8217;s account<\/a>.) \t<\/p>\n<p>However, the past shows that this method is unreliable (see \t\tDaniel Ferbers&#8217; account), and it is not clear whether it will be \t\treliable in the future, as, on one hand, Microsoft may change the \t\tspecifications, and on the other, letting us use the registry time \t\tzone information is clearly not a priority for Microsoft.<\/p>\n<p>On the other hand, we see that Windows computers show their \t\tlocal times consistently according to the time zone that is set on \t\tthem; this shows that Windows do not go to registry to get the current \t\ttime, or go in some limited circumstances (e.g., when the system \t\tstarts up \u2013 I am just guessing).<\/p>\n<p>This takes us to other approaches that use Windows API.<\/p>\n<h2><span id=\"native_api\">Native API<\/span><\/h2>\n<p>The second way to find out the current time zone on Windows is \t\tthe native API.<\/p>\n<p> \t\tI tried to create a workaround of this bug using JNI which allows \t\tcalling a native library from Java code.<br \/> In Java code it is \t\teasy to find out the operating system name and the platform (32 or 64 \t\tbit).<br \/> If it turns out that the system is Windows, one can use \t\tJNI to call a native library that would call Windows API functions to \t\tfind out the current time zone offset.<br \/> In fact, there is a <a \t\t\thref=\"http:\/\/www.codeproject.com\/Articles\/144159\/Time-Format-Conversion-Made-Easy\"> \t\t\tpublished C code for finding the current time zone offset, due to \t\t\tpeterchen<\/a> which uses just three function calls: \t\t<code>gmtime(..)<\/code> \t\t, \t\t<code>mktime(..)<\/code> \t\tand \t\t<code>difftime(..)<\/code> \t\t. \t<\/p>\n<p> \t\tThe native API that provides the time and time zone functions, is \t\tMicrosoft Visual C runtime library; it is implemented in <a \t\t\thref=\"http:\/\/en.wikipedia.org\/wiki\/Microsoft_Windows_library_files\"> \t\t\tmsvcrt.dll in its various versions<\/a>.<br \/> For Visual C\/C++ \t\tversions 4.2 to 6, the operating system and the user programs called \t\tthe same DLL for C run-time library functions \u2013 which is the most \t\treasonable solution since the functions are the same.<br \/> \t\tBeginning with Visual C\/C++ 7.0 (Visual Studio .NET), Microsoft \t\tseparated the libraries, <a \t\t\thref=\"http:\/\/support.microsoft.com\/kb\/326922\"> declaring that \t\t\tmsvcrt.dll is for operating system usage only and users should use \t\t\tanother library, msvcr70.dll, msvcr71.dll, etc, through msvcr110.dll, \t\t\tand either package it with their own files or install side-by-side<\/a>. \t\tThe reason for this divergence is that Microsoft included other \t\tfunctionalities in msvcrt \u2013 such as structured exception handling, see \t\t<a \t\t\thref=\"http:\/\/kobyk.wordpress.com\/2007\/07\/20\/dynamically-linking-with-msvcrtdll-using-visual-c-2005\/\"> \t\t\tthis article on kobyk.wordpress.com<\/a>. \t<\/p>\n<p> \t\tOne of gcc compilers on Windows is provided by MinGW, <a \t\t\thref=\"http:\/\/en.wikipedia.org\/wiki\/MinGW\"> Minimalist GNU for \t\t\tWindows<\/a>; it links user programs with the system copy of msvcrt.dll \t\t(and other similar DLLs that existed before msvcrt.dll on Windows 9x) \t\tthus removing the need for developers to include msvcrxx.dll in their \t\tdistributions. In this way it also resolves GPL-related legal problems \t\t(any code licenced under GPL needs to include the source of all its \t\tdistributions and thus cannot distribute any Microsoft DLLs). For this \t\tpurpose, they perform admirable work of keeping track of various \t\tversions of msvcrt.dll released by Microsoft, and testing against \t\tthem. \t<\/p>\n<p> \t\tPeople say on the net that msvcrt is unreliable, see, e.g., the answer \t\tto <a \t\t\thref=\"http:\/\/stackoverflow.com\/questions\/15822048\/using-mingw-to-build-a-windows-dll-that-depends-on-visual-studio-crt-msvcr110-d\"> \t\t\tthis Stack Overflow question<\/a> and, unfortunately, I can confirm this \t\tas you will see below. \t<\/p>\n<p> \t\tI tried to implement the simple solution for finding the current time \t\tzone offset as suggested by peterchen, see above. On my Windows XP SP3 \t\tcomputer running Eclipse 4.3.2 with MinGW this solution worked fine. \t\tHowever, when I tried to implement the same solution on a Windows \t\tServer 2008 Datacenter v 6.0 (build 6002 SP2) 64 bit on Amazon Web \t\tServices with Microsoft Windows SDK 7.1 64 bit, I found that \t\t<code>gmtime()<\/code> \t\toperated incorrectly (it subtracted two hours from my current \t\tJerusalem time to get GMT while Daylight Savings Time was in effect \t\tand the current offset was actually three hours; my desktop on that \t\tcomputer showed the correct time). \t<\/p>\n<p> \t\tPeople (and Microsoft) suggest finding a good version of msvcrt.dll \t\t(or msvcrxx.dll) and packaging it with their programs, or compiling \t\tagainst it statically. <br \/>However, my gut feeling is pessimistic \t\tas we do not know where the problem is, in msvcrt or in some other \t\tMicrosoft dll it calls. <br \/>For this reason one would have to \t\ttest the good version against all operating systems that people use \t\t(and that still starts at least with Windows XP). <br \/>It is \t\tlikely that one version of msvcrt.dll would not work with all \t\toperating systems, so that one would need a few versions that would \t\tcover different operating systems. <br \/>All this would still not \t\tguarantee forward compatibility: a next version of Windows might not \t\twork with any of these. \t<\/p>\n<p>My conclusion is that I cannot say that the native API is a \t\treliable solution to find the current time zone from Java.<\/p>\n<p> \t\tThe big question is, how could Microsoft consistently release buggy \t\tmsvcrt.dll without so much public outcry? <br \/>The only answer I \t\thave, is that all time-related functions of the C runtime library are \t\tnot used that much; instead, people write their code that deals with \t\tany time-related issues in some higher-level languages such as C# or \t\tVisual Basic (both based on .NET framework of Microsoft), or Java. <br \/> \t\tMicrosoft, on their side, encourage transition to .NET-based \t\tlanguages, and for this reason it is not in its interest to invest in \t\tthe C runtime library. \t<\/p>\n<h2><span id=\"managed_net_api\">Managed (.NET) API<\/span><\/h2>\n<p> \t\tWith all these explanations, it appears that the only reliable method \t\tto find out the current time zone on Microsoft might be by using its \t\t.NET API.<br \/> This can be done easily by using \t\t<code>TimeZone.CurrentTimeZone<\/code> \t\tproperty to get the current time zone, and then calling \t\t<code>TimeZone.GetUtcOffset(DateTime.Now)<\/code> \t\tto get the current UTC offset; all this runs on all versions of .NET \t\tstarting with version 1.1. \t<\/p>\n<p> \t\tThe problem with this approach is that .NET is not forward compatible: \t\tone needs a few versions of the code to run on all existing versions \t\tof .NET starting with 1.1, and when the next version of .NET is \t\treleased, none of these versions of your code will run on it: even if \t\tone of them can run, one needs to declare its number in \t\t<code>app.config<\/code> \t\tas explained <a \t\t\thref=\"http:\/\/stackoverflow.com\/questions\/2816914\/backwards-compatibility-of-net-framework-4\"> \t\t\there<\/a>. \t<\/p>\n<p>An alternative solution is to require all the clients install a \t\tcertain version of .NET but that really contradicts the idea of \t\tportability of Java.<\/p>\n<h2><span id=\"what_to_do\"> \t\t<span id=\"what-to-do\">What to do?<\/span> \t<\/span><\/h2>\n<p>We are now left with the question: what to do if I develop a \t\tJava application (or an applet) that needs to know the current time \t\tzone? \t<\/p>\n<p> \t\tIt seems that the easiest way for a Java program on Windows to use the \t\tcurrent time reliably is to use the Java&#8217;s default time zone &#8211; from \t\twhich we have started this discussion &#8211; and give the user a \t\tpossibility to change the time zone if the program detects it \t\tincorrectly. <br \/> E.g., a GUI button that would give a choice of \t\ttime zones known to Java, or a possibility to enter the current time \t\tzone offset, or both. \t<\/p>\n<p> \t\t<small>&copy;Baruch Youssin 2014<\/small> \t<\/p>\n<p> \t\t<strong>Read also: <\/strong> \t<\/p>\n<ul style=\"list-style-type: none\">\n<li><a \t\t\thref=\"time-zone-design-in-java-olson-time-zone-database.html\">Time \t\t\t\tzones in Java: design discussion<\/a><\/li>\n<li><a \t\t\thref=\"daylight-savings-time-in-israel-politics-reasons-interests.html\">Daylight \t\t\t\tSavings Time in Israel: politics, reasons, interests<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Current time zone in Java Many programs need to be able to find out the current time of the computer they are running on, and its time zone, without hard coding it. For this purpose Java has the concept of default time zone which is an instance of TimeZone class which is returned by java.util.TimeZone.getDefault() [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"_links":{"self":[{"href":"https:\/\/baruchyoussin.com\/en\/wp-json\/wp\/v2\/posts\/131"}],"collection":[{"href":"https:\/\/baruchyoussin.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/baruchyoussin.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/baruchyoussin.com\/en\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/baruchyoussin.com\/en\/wp-json\/wp\/v2\/comments?post=131"}],"version-history":[{"count":7,"href":"https:\/\/baruchyoussin.com\/en\/wp-json\/wp\/v2\/posts\/131\/revisions"}],"predecessor-version":[{"id":303,"href":"https:\/\/baruchyoussin.com\/en\/wp-json\/wp\/v2\/posts\/131\/revisions\/303"}],"wp:attachment":[{"href":"https:\/\/baruchyoussin.com\/en\/wp-json\/wp\/v2\/media?parent=131"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/baruchyoussin.com\/en\/wp-json\/wp\/v2\/categories?post=131"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/baruchyoussin.com\/en\/wp-json\/wp\/v2\/tags?post=131"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}