Java Time Zone is messed up
It's a "quirk" in the way the JVM looks up the zoneinfo file. See Bug ID 6456628.
The easiest workaround is to make /etc/localtime a symlink to the correct zoneinfo file. For Pacific time, the following commands should work:
# sudo cp /etc/localtime /etc/localtime.dist
# sudo ln -fs /usr/share/zoneinfo/America/Los_Angeles /etc/localtime
I haven't had any problems with the symlink approach.
Edit: Added "sudo" to the commands.
java incorrect timezone
Ensure you set the timezone for the JVM when starting the application:
-Duser.timezone="Australia/Sydney"
TimeZone problem in Java
I'm not sure if this answers your question, but this is one way to get "now" in GMT.
import java.text.*
import java.util.*
Calendar cal = new GregorianCalendar();
Date date = cal.getTime();
SimpleDateFormat formatter = new SimpleDateFormat("yyyy.MM.dd G 'at' HH:mm:ss z");
formatter.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println(formatter.format(date));
See the Javadoc on SimpleDateFormat for different patterns. Also, you may want to consider Joda Time as it is far superior for dates and times.
Java: Fix incorrect timezone in date object
tl;dr ⇒ use ZonedDateTime
for conversion
public static void main(String[] args) {
// use your date here, this is just "now"
Date date = new Date();
// parse it to an object that is aware of the (currently wrong) time zone
ZonedDateTime wrongZoneZdt = ZonedDateTime.ofInstant(date.toInstant(), ZoneId.of("CET"));
// print it to see the result
System.out.println(wrongZoneZdt.format(DateTimeFormatter.ISO_ZONED_DATE_TIME));
// extract the information that should stay (only date and time, NOT zone or offset)
LocalDateTime ldt = wrongZoneZdt.toLocalDateTime();
// print it, too
System.out.println(ldt.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
// then take the object without zone information and simply add a zone
ZonedDateTime correctZoneZdt = ldt.atZone(ZoneId.of("GMT"));
// print the result
System.out.println(correctZoneZdt.format(DateTimeFormatter.ISO_ZONED_DATE_TIME));
}
Output:
2020-01-24T09:21:37.167+01:00[CET]
2020-01-24T09:21:37.167
2020-01-24T09:21:37.167Z[GMT]
Explanation:
The reason why your approach did not just correct the zone but also adjusted the time accordingly (which is good when desired) is your use of a LocalDateTime
created from an Instant
. An Instant
represents a moment in time which could have different representations in different zones but it stays the same moment. If you create a LocalDateTime
from it and put another zone, the date and time are getting converted to the target zone's. This is not just replacing the zone while keeping the date and time as they are.
If you use a LocalDateTime
from a ZonedDateTime
, you extract the date and time representation ignoring the zone, which enables you to add a different zone afterwards and keep the date and time as it was.
Edit: If the code is running in the same JVM as the faulty code, you can use ZoneId.systemDefault()
to get the same time zone as the faulty code is using. And depending on taste you may use ZoneOffset.UTC
instead of ZoneId.of("GMT")
.
How to set time zone of a java.util.Date?
Use DateFormat. For example,
SimpleDateFormat isoFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
isoFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
Date date = isoFormat.parse("2010-05-23T09:01:02");
Java Calendar returns wrong hour in MS Windows for `America/Santiago` zone
Summary
The authorities in Chile changed this year’s (2016) time zone rules at the last minute. The tz
database in Java is not yet updated.
Details follow.
java.time
You are using the old date-time classes bundled with early Java that have proven to be troublesome. In Java 8 and later those classes were supplanted by the java.time framework (inspired by the Joda-Time library). Avoid the old classes.
Focus on UTC
Programmers should think first in UTC. Always verify the current time in UTC to be sure the computer even has the correct time. Flipping around time zones and Daylight Saving Time (DST) changes will make your brain hurt, and UTC is your aspirin.
In Java 8 and later, the Instant
class represents a moment on the timeline in UTC with a resolution in nanoseconds.
Instant now = Instant.now();
System.out.println( "Instant.now(): " + now );
Always include the UTC value in a post such as this Question.
Time zone of host OS does not matter
The JVM holds it own representation of its current default time zone. By default in most implementations that zone is picked up from the host OS’ time zone setting. But Java launch configurations can override that default. And any Java code in any thread of any app within the JVM can change the JVM’s current default time zone during runtime with a call to TimeZone.setDefault
.
So the current time zone setting of the host OS is irrelevant. What matters is the current setting in your JVM.
The part of your host OS that does matter is if its hardware clock knows the current moment correctly. In most JVM implementations, the current moment is determined from the host hardware clock, and then the JVM applies its own current default time zone.
Time Zone redefined for Chile in early 2016
Politicians enjoy fiddling with time zones and Daylight Saving Time (DST). Chile is no exception. See the Wikipedia article, Time in Chile.
From what I could discern… Last year, 2015, Chile stayed on DST permanently at -03:00
and deciding to never revert back to the standard time of -04:00
. Then they changed their minds again, announcing in March 2016 that they would re-introduce standard time for their winter (southern hemisphere, winter being now, late May, June, July). On 2016-05-15 midnight (a couple weeks ago), the old standard offset of -04:00
kicked in. That standard/winter time will endure until 2016-08-14 (or until they change their minds again). [Take all that with a grain of salt. Please verify that I got the facts correct.]
These frequent changes wreak havoc with computers which need to have their tz
time zone database files updated in order to reflect the latest fiddling.
Your operating system has its own copy of the time zone definitions. Java has its own copy. And other software such as your database engine may have its own copy.
Current Java 8 Update 92 lacks recent Chile changes
So let's run a test in Java 8 Update 92 to see if the Java copy of tz
is up-to-date.
long millis = 1464645007120L;
Instant instant = Instant.ofEpochMilli ( millis ); // UTC, always.
ZoneId zoneId = ZoneId.of ( "America/Santiago" );
ZonedDateTime zdt = ZonedDateTime.ofInstant ( instant , zoneId );
Dump to console.
System.out.println ( "millis: " + millis + " | instant: " + instant + " | zoneId: " + zoneId + " | zdt: " + zdt );
millis: 1464645007120 | instant: 2016-05-30T21:50:07.120Z | zoneId: America/Santiago | zdt: 2016-05-30T18:50:07.120-03:00[America/Santiago]
You can see the offset in the last part is -03:00
. So it seems to me that the current version of Java released mid-April is unfortunately not up-to-date with the Chile changes announced in March.
From my readings it seems that today’s (2016-05-30) correct offset for America/Santiago
should be -04:00
as seen here on time.is/Santiago.
Usually I would suggest using the Java tzupdater
tool. But the current download is labeled with the word 2015
so I presume it is not up-to-date either.
I suggest filing a bug report at the Java team at Oracle.
Workaround
It may be a while before you can obtain a corrected version of the tz
database (though perhaps you could hack your own update -- I do not know). Until then, as a workaround, perhaps you could specify your own offset in Java code using the ZoneOffset
class, a subclass of ZoneId
that represents only the offset-from-UTC without any rules for adjusting for anomalies such as DST. I’ve not thought through the implications; be wary.
ZoneOffset zoneOffset = ZoneOffset.of( -4 ); // Negative four hours for '-04:00'.
java program reports wrong timezone on linux(shows IST for Europe/Dublin)
Irish Standard Time, which is the correct timezone for Dublin, is abbreviated as IST.
Unfortunately timezone abbreviations are not unique, as you can see in this table - IST can be resolved into (at least) two other timezones. Timezone abbreviations are not part of the related ISO standard and their use is not generally recommended.
In general, UTC timestamps should be preferred when multiple timezones are involved. With UTC each party only needs to keep track of at most one timezone apart from their own. In addition, UTC is not affected by DST practices, which are normally a source of confusion even for locations with the same longitude.
Related Topics
How to Allow All Network Connection Types Http and Https in Android (9) Pie
Check Orientation on Android Phone
Android: Internet Connectivity Change Listener
How to Stop Repeated Keypressed()/Keyreleased() Events in Swing
How to Fix Java.Lang.Unsupportedclassversionerror: Unsupported Major.Minor Version
How to Declare and Initialize an Array in Java
Manipulating an Access Database from Java Without Odbc
Java Url Encoding of Query String Parameters
Java: Maintaining Aspect Ratio of Jpanel Background Image
How to "Scan" a Website (Or Page) For Info, and Bring It into My Program
Why Doesn't Recyclerview Have Onitemclicklistener()
Android: How to Use Alarmmanager
Parsing Query Strings on Android
Relation Between Memory Host and Memory Arguments Xms and Xmx from Java
How to Generate Random Integers Within a Specific Range in Java
What Is the Reason Behind "Non-Static Method Cannot Be Referenced from a Static Context"