Java Date timezone printing different timezones for different years, Workaround needed Java Date timezone printing different timezones for different years, Workaround needed javascript javascript

Java Date timezone printing different timezones for different years, Workaround needed


This is likely the expected behaviour from Java (and not from JavaScript).

As implied by the comment by RobG above, programming languages may or may not support historical time rules (such as DST and timezone offsets). In your case, it appears that your Java runtime supports it, whereas your JavaScript runtime does not.

A list of historical timezones and DST rules for India can be found at timeanddate.com. The list confirms the timezone offsets of your Java dates:

  • Until 1941: UTC+5:53:20
  • 1941: UTC+6:30
  • 1942: UTC+5:30
  • 1943-44: UTC+6:30
  • From 1945: UTC+5:30

Checking your dates against Wolfram|Alpha further confirms your Java date UTC offsets: 1915, 1943, 1946

Wikipedia provides more information about time in India:

Calcutta time was officially maintained as a separate time zone until 1948

Calcutta time could either be specified as UTC+5:54 or UTC+5:53:20. The latter is consistent with your code example.

The Wikipedia entry further informs that the current IST timezone with an offset of UTC+5:30 was not in full effect in all of India until 1955.

As pointed out by Elliott Frisch and confirmed by the link to timeanddate.com above, DST was in effect during WWII. In your comment to his answer, you state:

is this the way we are supposed to save in database and use it in applications, or we use some workaround for it

I guess it depends. If you really need to distinguish dates as points in time accurately, you would need a timezone-independent representation such as UTC or unix time (or milliseconds since the unix epoch). If you just work with local dates from the same timezone, a simple string representation (e.g. YYYY-MM-DD hh:mm:ss) could suffice.


There was a war. From the wikipedia link, India observed DST during World War 2, from 1942-1945.


java.time

Avoid using the troublesome old date-time classes bundled with the earliest versions of Java. Now legacy, supplanted by the java.time classes.

ZoneId z = ZoneId.of( "Asia/Kolkata" );  // "Asia/Calcutta"LocalTime lt = LocalTime.of( 5 , 34 , 12 );ZonedDateTime zdt1943 = ZonedDateTime.of( LocalDate.of( 1943 , Month.APRIL , 12 ) , lt , z );ZonedDateTime zdt1945 = ZonedDateTime.of( LocalDate.of( 1945 , Month.APRIL , 12 ) , lt , z );ZonedDateTime zdt1946 = ZonedDateTime.of( LocalDate.of( 1946 , Month.APRIL , 12 ) , lt , z );ZonedDateTime zdt2016 = ZonedDateTime.of( LocalDate.of( 2016 , Month.APRIL , 12 ) , lt , z );

Dump to console.

System.out.println( "zdt1943: " + zdt1943 );System.out.println( "zdt1945: " + zdt1945 );System.out.println( "zdt1946: " + zdt1946 );System.out.println( "zdt2016: " + zdt2016 );

See live code in IdeOne.com.

When run. We see the same behavior as described in your Question, with an offset-from-UTC of six and a half hours during the war and five and a half after. We get the same behavior whether using Asia/Kolkata or Asia/Calcutta. The java.time classes use tzdata, formerly known as Olson Database.

zdt1943: 1943-04-12T05:34:12+06:30[Asia/Kolkata]

zdt1945: 1945-04-12T05:34:12+06:30[Asia/Kolkata]

zdt1946: 1946-04-12T05:34:12+05:30[Asia/Kolkata]

zdt2016: 2016-04-12T05:34:12+05:30[Asia/Kolkata]

In the Question…

When I put a date having the year before 1945, it changes the timezone.

No it does not change the time zone. The results say that in the earlier years “5:34” was defined as six and a half hours ahead of UTC while in later years the definition became five and a half hours ahead of UTC. Just as “5:34” means eight hours behind UTC in Seattle in the summer but seven hours in the winter, because of Daylight Saving Time (DST) nonsense.

But I suspect these may wrong values; read on.

Time in Calcutta

The behavior we are seeing does not seem to match my reading of this Wikipedia page, Time in Calcutta. That page describes odd offsets other than on-the-hour or on-the-half-hour, such as UTC+05:54, which we are not seeing in any of our respective code samples.

So I suspect tzdata does not contain this historical data for India. But just this layperson’s guess; I am no historian.

Do not use date-time types for historical values

While I do not know the specifics of time in this historical period of India and its handling in tzdata, it seems that none of our date-time libraries are handling these historical nuances.

But we should not expect such handling! Know that tzdata does not promise complete coverage of time zones before 1970.

When referring to historical date-time values, I suggest you use simply text rather than any of the date-time data types. The purpose of the data types is for validation and calculation. You are likely doing neither for historical values. I cannot imagine you are determining the number of days an invoice is overdue from 1943.

Perhaps you should edit your Question to describe why you are storing these historical date-time values in a database so precisely. If you were merely experimenting and noticed these issues, know that you should not expect precise date-time handling in the far past (before 1970) nor into the far future (past the few weeks notice politicians sometimes give about sudden time zone definition changes).

Upshot: Attempting to precisely handle historical date-time values is fraught with various issues and seems pointless to me.

what is the possible workaround for it

I suggest using “local” date-time values as text in ISO 8601 format without any time zone.