If run this code in windows machine, its works properly:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(sdf.format(new Date()));
It shows date & time same as clock, but the same code if I run on Windows Server it's showing -2hrs of clock time.
I tried by the setting the timezone as,
TimeZone timeZone = TimeZone.getTimeZone("Europe/Vienna");
sdf.setTimeZone(timeZone);
Then, it shows same as clock time.
My doubt is why is it not taking the clock time zone by default in Windows Server.
It should always take the time zone of the running machine but in some case it fails as reported here and here. If you are sure that your server time zone is correct but Java uses a different one, you can force a default time zone of your choice from the command line:
-Duser.timezone="YOUR_TIME_ZONE_HERE"
or by code. You can also try with the Timezone Updater Tool by Oracle.
To see the time zone used by Java:
System.out.println(TimeZone.getDefault());
Time zone settings have no effect on a time value as the computer sees it. See my answer here for details. So long as the system time is set properly (regardless of time zone) and you don't need to display the time as text or parse the time from text, java will have no trouble and its calculations will be correct. If you do need to display/parse a time value, setting the default time zone is safe and it won't effect how times are stored, except of course Java will use that time zone to parse text representations of time that don't explicitly specify the time zone (like if you used the SimpleDateFormat in your example to parse, since the format string doesn't include the time zone).
As for why Java has this problem on your server box but not your desktop box, what version of Windows Server is it, and what version Java is running on the server? My guess is that the JVM can't unambiguously identify the OS version and therefore can't know for sure how to get the local time zone, so uses UTC as a fallback. Try updating your java version to the latest.
Another possibly is that the time zone on the server is set on a per-user basis. Verify that the time zone for the user/process that is running the app on the server is set properly.
There is a bug open at Oracle about that problem: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7044727. Basically it's because Java pulls the timezone out of the registry. And Windows saves it in HKLocalMachine, which is not the Client time but the time of the machine.
I had this issue after upgrading from 2003 server to 2008 server. Java keeps using GMT timezone instead of Windows Timezone setting. The solution is simple, go to Windows control panel and change to a different Timezone(whatever timezone is fine), then change it back. Took me hours to figure it out but it worked as charm.
My thought: the change triggerred something in Java, which correct the issue.
Related
Canada/Yukon timezone no longer observe DST (source https://www.timeanddate.com/time/change/canada/yukon) and is now permanently GMT-7. But when I tried this:
ZonedDateTime nowZoned = LocalDateTime.parse("2021-02-03T08:04:00").atZone(ZoneOffset.UTC).toInstant().atZone(ZoneId.of("Canada/Yukon"));
nowZoned is shown as 2021-02-03T00:04-08:00[Canada/Yukon].
Does it mean that java.time library does not update when some timezones have decided not to observe DST or decided to move ahead of the clock permanently? What are some ways to work around this issues? I thought about manually checking for these but there are simply way too many timezones to handle them manually. Thanks!
Yes indeed, the Yukon time zone rules changed in early 2020. The politicians there decided to stay on Daylight Saving Time (DST) indefinitely, using an offset of -07:00 year-round. So the sun will never again be overhead at noon.
Staying on DST year-round is the new fad among politicians around the world. Countries such as Morocco and Turkey have gone that way. Others are headed that way, such as Washington State in the United States.
Your code:
ZonedDateTime nowZoned = LocalDateTime.parse("2021-02-03T08:04:00").atZone(ZoneOffset.UTC).toInstant().atZone(ZoneId.of("Canada/Yukon"));
… is overwrought. Simply put a Z at the end of your input string if that date and time is intended to be a moment as seen in UTC.
ZonedDateTime zdt =
Inatant
.parse("2021-02-03T08:04:00Z")
.atZone(
ZoneId.of( "Canada/Yukon" )
)
;
You asked:
Does it mean that java.time library does not update when some timezones have decided not to observe DST or decided to move ahead of the clock permanently?
Politicians around the world have shown a predilection towards changing the rules of the time zones in their jurisdiction. They do so with surprising frequency. And some do so with astonishingly little forewarning.
The rules are stored in a tzdata file. When politicians change the rules, ICANN/IANA publishes a new updated version of the tzdata. This typically happens a few times a year.
And, no, there is no automatic immediate updating on your computer. As a SysAdmin or DBA, you are responsible for these updates. Of course, you need not update unless a time zone of interest to your company changes.
You will find at least two or three of these on your machines.
Your JVM has one embedded. Updates to the JVM will typically include the latest tzdata. But that Java update may not come soon enough. So you may need to manually obtain a tzdata file, ad replace the one in your JVM. Oracle provides a tool to assist. But I’m not aware of its current licensing terms, so study their terms. Or check with the vendor of your JVM such as Azul Systems, Adoptium, SAP, Amazon, Microsoft, BellSoft, Red Hat/IBM, etc.
Your host operating system such as macOS, BSD, Linux, Windows, etc. has a copy of the tzdata. While updating this tzdata does not affect your Java apps, you’ll want to update it for other apps.
Sophisticated database servers such as Postgres also keep their own internal copy of tzdata. Update as needed by either manual replacement or through an updated version of the DBMS.
Every SysAdmin & DBA should consider subscribing to the tzdata announcement mailing list.
I know that is required because of changes that occurs after the release of the jdk/jre, but why don't get those informations from the server?
As "from the server" i mean from OS. The question is: "Why doesn't Java use the time zone system from the operating system instead of having its own copy of the time zone database"?
Here is my rough understanding. I believe it should at least give you the main reasons.
When Java was designed in the 1990s, a main design goal was that your Java program should be write once run anywhere, popularly abbreviated WORA. At that time cross-platform programs were not that commonplace. Porting your Windows program to a Mac or vice versa required quite some effort. Sun, the company that developed Java, was selling an operating system called Solaris, a Unix variant that not that many wanted to port to or from.
Different operating systems have different time zone data: different structure, different names for the time zones, different amounts of detail. Windows, for example, hasn’t got the full history of offsets for all time zones. What Mac and Unix had in the 1990s I don’t know. There were many Unix variants back then, and I am not even sure whether they all had built-in time zone information.
So relying on the operating system would mean that a program doing for example TimeZone.getTimeZone("America/Sao_Paulo") (using the time zone class from back then, now long outdated) would not be portable because on another operating system the time zone would not be called that. The write once run anywhere idea would be seriously harmed.
I suppose that this was the main reason for choosing that Java needed to have its own built-in time zone database, the same on all operating systems. I also believe that the choice of the Olson database, also known as tzdata, the zoneinfo database or IANA time zone database, was rather obvious. And from this choice came also the need for being able to update the timezone data, since the database is constantly evolving, especially since politicians around the globe are constantly (and eagerly, it would appear) deciding on new time zone rules.
Links for comparison:
List of tz database time zones
Windows Default Time Zones
Please notice that the former uses time zone IDs like America/Sao_Paulo, that is the region/city format, while the latter instead uses names like E. South America Standard Time.
This question already has answers here:
How to get the TimeZone of the local machine in JodaTime?
(2 answers)
Closed 4 years ago.
I want to get DateTime of own machine not considering the server time it's connected to. How can I achieve this?
DateTimeZone zone = DateTimeZone.getDefault();
System.out.println(zone);
On my computer I got
Europe/Copenhagen
This agrees with the computer’s time zone setting.
What it really gives me is the time zone setting of the JVM. This may not always agree with the computer’s setting since the JVM may have been launched with a different setting on the command line and/or its setting may have been changed later from within your program or another program running in the same JVM.
I am running Three Quartz servers(as java wrapper services) from one Linux Virtual Server machine. My requirement is to run these servers in different time zone in one machine. e.g. Say there are three servers name A, B and C then A should schedule job based on Central Time zone, B should schedule jobs based on Eastern Time zone and so on. Is there any way we could achieve this?
Time zones are but concepts in Unix land. Each system clock should run with UTC, calculating displayed times based on the timezone you configure within the system.
Depending on which software should deal with that, it might be totally sufficient to set the TZ environment variable correctly.
I created three users for three different servers and set the desired time zones in .bashrc file. Say user name is user1 then do the following:
Open file /home/user1/.bashrc usinf any editor.
Modify and enter this line:
export TZ="/usr/share/zoneinfo/{TIMEZONE-DIRECTORY}/{TIMEZONE_FILE}"
Save the file.
Timezone is set for the user now.
I am starting an application with remote debug and suspend on start turned on.
When I connect remotely to the process, I getting stopped in an uncaught FileNotFoundException in ZoneInfo.getTimeZone()
It is cause by the line: new PatternLayout("[%d{HH:mm:ss}] %-5p: %m%n").
apparently java is not finding timezone for Israel in jre/lib/zi directory.
I appreciate if you know how to fix it.
Thanks.
Edit: It appears the problem is that time zone is defined as "Israel" and Java only have "Asia/Jerusalem" time zone.
How can It be changed on linux machine?
Israeli time zone should be Asia/Jerusalem. I see it under my jre/lib/zi.
I believe that there can be 2 reasons for failure of your program:
this file does not exist on your system.
something is wrong in definition of time zone on your computer.
So,
Check if the file Jerusalem is there
Check what is the default time zone returned by TimeZone.getDefault() and what is configured on control panel.
From what I found so far this is an inconsistency between suse 10 os and java. the os calls the time zone "(GMT+2:00) Israel" while java expects "(GMT+2:00) Jerusalem".
There is a workaround - starting java with the flag -Duser.timezone=Asia/Jerusalem or -Duser.timezone=GMT+2. the second option is not good for daylight savings. more details on this blog.