Miracle
Miracle

Reputation: 61

Java 8 timezone for Instant.EPOCH is incorrect

I have a linux machine, and its time zone is set as Asia/Qatar. When I am printing Instant.EPOCH with formatter its giving me wrong zone information while for Instant.now() the zone information is correct. Below is my code and its output. Can anyone please help me, why is this discrepancy?

import java.util.Date;
import java.time.format.DateTimeFormatter;
import java.time.Instant;
import java.time.ZoneId;

public class DateTest {
   public static void main(String[] args) {
      String pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS Z";
      Instant myInstant = Instant.EPOCH;
      Instant myInstantNow = Instant.now();
      DateTimeFormatter formatter =  DateTimeFormatter.ofPattern(pattern).withZone(ZoneId.systemDefault());
      System.out.println(formatter.format(myInstant));
      System.out.println(formatter.format(myInstantNow));
   }
}

The output of the code is:

1970-01-01T04:00:00.000 +0400
2019-09-29T18:30:14.766 +0300

Java version: "1.8.0_181"

Same code if I run in windows, its working fine. I am getting +0300 for Instant.EPOCH as well.

Upvotes: 6

Views: 870

Answers (2)

Anonymous
Anonymous

Reputation: 86379

TL;DR: Your results from Linux are correct and as expected.

In 1970 Qatar was at offset +04:00 from GMT. The epoch is January 1, 1970. In 1972 Qatar changed from offset +04:00 to +03:00. Source: On Time Zone in Doha, Qatar (Ad Dawhah), in the Time zone changes for: dropdown select 1970–1979.

What went wrong on your Windows computer, then? It’s a guess on my part: The way I read Default Time Zones in the Windows documentation, Windows does not offer an Asia/Qatar time zone as a setting in Windows. So my guess is that your Windows is set to Arab Standard Time according to the table I just linked to, which in turn translates to UTC+03:00. Arab Standard Time (or Arabia Standard Time; abbreviated AST) is used in for example Kuwait, Iraq and Yemen too. But those countries have been on offset +03:00 all the time since 1970 and before. So when Java tries to pick up the default time zone from Windows, it could easily get a time zone with this history rather than the correct history for Qatar. As I said, it’s a guess for now. But you can easily verify. On your Windows computer try:

    System.out.println(ZoneId.systemDefault());

If it prints Asia/Qatar, my guess was wrong. If it prints something like GMT+03:00, I was right. If it prints something else, I may or may not be.

Edit: A couple of further links: AST – Arabia Standard Time (Standard Time) gives Kuwait as an example city. Time Changes in Kuwait City Over the Years infomrs us that Kuwait too has been on offset +03:00 since 1950.

Further edit: Thanks for confirming that Java on your Windows computer prints Asia/Riyadh as its default time zone. Riyadh, Saudi Arabia, has been on offset +03:00 since 1947. This at least partly explains why you get this offset even though it’s not correct for Qatar. Source

Upvotes: 8

Nikolas
Nikolas

Reputation: 44496

At the first observation I though the daylight saving time difference takes place since your dates show January (wintertime) and September (summertime), however as far as I see Qatar doesn't use this system nowadays.

However, when we take a look into the past, we can find out that Qatar changed the UTC zone on the 1st of July 1972 from GST (-04:00) to AST (-03:00) so I guess the results are correct. This information might be found at Time Zone & Clock Changes in Doha, Qatar.

The problem is that the Windows machine uses the current Qatari UTC since Windows-based platform tracks some history. Read more at Are Windows timezone written in registry reliable?.

Upvotes: 1

Related Questions