Reputation: 38705
I live in North Carolina, btw, which is on the East Side. So I compile and run this code and it print out the same thing. The documentation say that java.util.date try to reflect UTC time.
Date utcTime = new Date();
Date estTime = new Date(utcTime.getTime() + TimeZone.getTimeZone("ET").getRawOffset());
DateFormat format = new SimpleDateFormat("dd/MM/yy h:mm a");
System.out.println("UTC: " + format.format(utcTime));
System.out.println("ET: " + format.format(estTime));
And this is what I get
UTC: 11/05/11 11:14 AM
ET: 11/05/11 11:14 AM
But if I go to this website which try to reflect all different time, UTC and ET are different. What did I do wrong here
Upvotes: 5
Views: 4319
Reputation: 78965
Locale
with SimpleDateFormat
: A parsing/formatting type e.g. the legacy, SimpleDateFormat
or the modern, DateTimeFormatter
are Locale
-sensitive and therefore you should always use a Locale
to avoid surprises. You can check this answer to learn more about it.Also, note that a java.util.Date
object is not a real Date-Time object like the modern Date-Time types; rather, it represents the number of milliseconds since the standard base time known as "the epoch", namely January 1, 1970, 00:00:00 GMT
(or UTC). Since it does not hold any format and timezone information, it applies the format, EEE MMM dd HH:mm:ss z yyyy
and the JVM's timezone to return the value of Date#toString
derived from this milliseconds value. If you need to print the Date-Time in a different format and timezone, you will need to use a SimpleDateFormat
with the desired format and the applicable timezone e.g.
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
public class Main {
public static void main(String[] args) {
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yy hh:mm a zzz", Locale.ENGLISH);
sdf.setTimeZone(TimeZone.getTimeZone("America/New_York"));
System.out.println(sdf.format(date));
sdf.setTimeZone(TimeZone.getTimeZone("Etc/UTC"));
System.out.println(sdf.format(date));
}
}
A sample output:
05/06/21 08:29 AM EDT
05/06/21 12:29 PM UTC
The java.util
Date-Time API and their formatting API, SimpleDateFormat
are outdated and error-prone. It is recommended to stop using them completely and switch to the modern Date-Time API*.
java.time
, the modern API:import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
public class Main {
public static void main(String[] args) {
Instant now = Instant.now();
System.out.println(now);
ZonedDateTime zdtUTC = now.atZone(ZoneId.of("Etc/UTC"));
System.out.println(zdtUTC);
ZonedDateTime zdtNewYork = now.atZone(ZoneId.of("America/New_York"));
System.out.println(zdtNewYork);
}
}
A sample output:
2021-06-05T12:19:58.092338Z
2021-06-05T12:19:58.092338Z[Etc/UTC]
2021-06-05T08:19:58.092338-04:00[America/New_York]
You can use DateTimeFormatter
for the output string in a different format e.g.
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
Instant now = Instant.now();
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd/MM/uu hh:mm a zzz", Locale.ENGLISH);
ZonedDateTime zdtUTC = now.atZone(ZoneId.of("Etc/UTC"));
System.out.println(dtf.format(zdtUTC));
ZonedDateTime zdtNewYork = now.atZone(ZoneId.of("America/New_York"));
System.out.println(dtf.format(zdtNewYork));
}
}
A sample output:
05/06/21 12:34 PM UTC
05/06/21 08:34 AM EDT
Here, you can use yy
instead of uu
but I prefer u
to y
.
Learn more about java.time
, the modern Date-Time API* from Trail: Date Time.
* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.
Upvotes: 1
Reputation: 1499770
That's because getRawOffset()
is returning 0 - it does that for me for "ET" as well, and in fact TimeZone.getTimeZone("ET")
basically returns GMT. I suspect that's not what you meant.
The best Olson time zone name for North Carolina is "America/New_York", I believe.
Note that you shouldn't just add the raw offset of a time zone to a UTC time - you should set the time zone of the formatter instead. A Date
value doesn't really know about a time zone... it's always just milliseconds since January 1st 1970 UTC.
So you can use:
import java.text.; import java.util.;
Date date = new Date();
DateFormat format = new SimpleDateFormat("dd/MM/yy h:mm a zzz");
format.setTimeZone(TimeZone.getTimeZone("America/New_York"));
System.out.println("Eastern: " + format.format(date));
format.setTimeZone(TimeZone.getTimeZone("Etc/UTC"));
System.out.println("UTC: " + format.format(date));
Output:
Eastern: 11/05/11 11:30 AM EDT
UTC: 11/05/11 3:30 PM UTC
I'd also recommend that you look into using java.time
now - which is much, mnuch better than the java.util
classes.
Upvotes: 7
Reputation: 35331
The proper abbreviation for Eastern Standard Time is "EST", not "ET". It looks like the getRawOffset()
method returns 0 if it is passed an unknown time zone.
TimeZone.getTimeZone("EST").getRawOffset()
Also, when you output the utcTime
variable, you are not outputting the UTC time. You are outputting EST time because you live in that timezone. From what I understand, the Date
class internally stores the time in UTC...but when you format it in order to output it as a human-readable string, it takes the current locale/timezone into account.
Upvotes: 1
Reputation: 46413
The time zone you're looking for is "EST"
or "EDT"
(for Daylight time), not "ET"
. See http://mindprod.com/jgloss/timezone.html.
Upvotes: 1
Reputation: 3091
TimeZone.getTimeZone("ET").getRawOffset() is returning 0 this is why
Upvotes: 1