6

I am having trouble figuring out why the timezone for the code below keeps showing UTC instead of EST. On my local computer it show EST, even if I am in MST time but on the actual server it keeps showing UTC. Any clue?

Mon Nov 9 2015 1:58:49 PM UTC


@JsonIgnore
    public String getDateCreatedFormatted() {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(getDateCreated());
        calendar.setTimeZone(TimeZone.getTimeZone("EST"));

        SimpleDateFormat format = new SimpleDateFormat("EEE MMM d yyyy h:mm:ss a z");      

        return format.format(calendar.getTime());
    }
Mike Flynn
  • 22,342
  • 54
  • 182
  • 341

2 Answers2

16

You've set the calendar to EST, but you haven't set the time zone on the SimpleDateFormat, which is the one use for formatting. Just use:

format.setTimeZone(TimeZone.getTimeZone("America/New_York"));

before you format the Date. You also don't need the Calendar at all, by the looks of it:

@JsonIgnore
public String getDateCreatedFormatted() {
    SimpleDateFormat format = new SimpleDateFormat("EEE MMM d yyyy h:mm:ss a z", Locale.US);
    format.setTimeZone(TimeZone.getTimeZone("America/New_York"));
    return format.format(getDateCreated());
}

Also I would strongly advise you to use full time zone IDs as above, rather than the abbreviations like "EST" which are ambiguous. (There are two problems there - firstly, EST can mean different things in different locations; secondly, the US EST should always mean Eastern standard time, whereas I assume you want to format using Eastern time, either standard or daylight depending on whether daylight saving time is in effect or not.)

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • I did have America/New_York, just switched it to see if that was it. Will try what you said. – Mike Flynn Dec 02 '15 at 15:28
  • That worked, any clue why some say EST and some say EDT? – Mike Flynn Dec 02 '15 at 16:49
  • 3
    @MikeFlynn: Well presumably the ones in standard time (i.e. the winter) say EST and the ones in daylight saving time (i.e. the summer) say EDT... – Jon Skeet Dec 02 '15 at 17:15
  • Anyway to just have it say EST all around? – Mike Flynn Dec 02 '15 at 17:30
  • @MikeFlynn: Why would you want it to? If you want it to reflect the local time in New York in the summer, it would simply be inaccurate to say EST. It's not clear who the consumer of this date will be, but personally I'd either format it with the UTC offset, or just format it in UTC anyway. But it does depend on why you're formatting it to start with. – Jon Skeet Dec 02 '15 at 17:41
  • It needs to say EST somehow. Is there a way to ignore day light savings? – Mike Flynn Dec 02 '15 at 17:58
  • 5
    @MikeFlynn: Yes, you could pass in a fixed time zone and then change the format to use `'EST'` at the end. But I would **very strongly** urge you not to do this. I've known a *lot* of people to get very confused by this, expecting "EST" to mean just "Eastern Time" (i.e. sometimes really EDT). If you show "Sat Mar 19 2016 10:00:00 AM EST" to two different people, they may well interpret it differently - if they were meant to meet up then, one of them may arrive an hour before the other. Surely that can't be a good thing. – Jon Skeet Dec 02 '15 at 18:04
  • 6
    @MikeFlynn: And if the reason for "it needs to say EST somehow" is because it's in a requirements document, I would push back and explain why it's a bad idea. If this were me, there'd have to be a really, *really* good reason for introducing such a large possibility of confusion. – Jon Skeet Dec 02 '15 at 18:09
  • @MikeFlynn: And for proof of the confusion: http://www.wordbits.net/2010/09/01/daylight-saving-time/ – Jon Skeet Dec 02 '15 at 19:08
0

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

Solution using java.time, the modern Date-Time API:

@JsonIgnore
public String getDateCreatedFormatted() {
    ZonedDateTime now = ZonedDateTime.now(ZoneId.of("America/New_York"));
    DateTimeFormatter dtf = DateTimeFormatter.ofPattern("EEE MMM d uuuu h:mm:ss a z", Locale.ENGLISH);
    return dtf.format(now);
}

ONLINE DEMO

Note: Never use SimpleDateFormat or DateTimeFormatter without a Locale.

Learn more about 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