5

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

Cœur
  • 37,241
  • 25
  • 195
  • 267
Thang Pham
  • 38,125
  • 75
  • 201
  • 285

6 Answers6

7

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.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • I have another question about time. http://stackoverflow.com/questions/5968842/compare-the-current-est-to-2pm-est-how . You think you can help me out as well? – Thang Pham May 11 '11 at 18:28
  • I want to highlight that recommendation about built-in libraries is not actual. Now we have lovely java.time API in standard JDK library. – turbanoff Mar 18 '21 at 13:06
  • 1
    @turbanoff: By "not actual" do you mean "no longer appropriate, 10 years later"? (I've edited the answer, but I can't really be expected to keep every one of my 35,000+ answers up to date...) – Jon Skeet Mar 18 '21 at 13:13
1

according this post you habe to write TimeZone.getTimeZone("ETS") instead of TimeZone.getTimeZone("ET")

Community
  • 1
  • 1
Reporter
  • 3,897
  • 5
  • 33
  • 47
1

TimeZone.getTimeZone("ET").getRawOffset() is returning 0 this is why

VirtualTroll
  • 3,077
  • 1
  • 30
  • 47
1

The time zone you're looking for is "EST" or "EDT" (for Daylight time), not "ET". See http://mindprod.com/jgloss/timezone.html.

Adrian
  • 42,911
  • 6
  • 107
  • 99
1

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.

Michael
  • 34,873
  • 17
  • 75
  • 109
1

Unknowingly, you have introduced two major problems in your code:

  1. Not using the proper timezone name: The two/three/four letter timezone names (e.g. ET, EST, CEST etc.) are error-prone. The proper way of naming a timezone is Region/City e.g. Europe/London. In most cases, the Region is the name of the continent to which the City belongs.
  2. Not using 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

ONLINE DEMO

java.time

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*.

A demo using 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]

ONLINE DEMO

Need output string in a different format?

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

ONLINE DEMO

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.

Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110