1

I have the following code

    protected void amethod1() {
    String strDate = "Thu May 18 16:24:59 UTC 2017";
    String dateFormatStr = "EEE MMM dd HH:mm:ss zzz yyyy";
    DateFormat dateFormat = new SimpleDateFormat(dateFormatStr);

    Date formattedDate = null;
    try {
        formattedDate = dateFormat.parse(strDate);
    } catch (ParseException e) {
        e.printStackTrace();
    }
}

The resulting value of formattedDate is- "Thu May 18 11:24:59 CDT 2017" .

I am testing this code in Chicago and the local timezone is CDT.
I am not able to understand why the time value changes from 16:24:59 to 11:24:59 even though. Am I missing something in the defined format of the date?

Swift-Tuttle
  • 485
  • 3
  • 14
  • 25
  • 2
    You declare your date as UTC, and you get your result in CDT, so the difference is logical. Were you trying to get the result in UTC? – Turtle May 23 '17 at 09:52
  • @Nathan - yes thats correct. I would want the result to be in UTC. – Swift-Tuttle May 23 '17 at 09:57
  • 3
    `java.util.Date` converts the time into your system's timezone. To get it in UTC you may convert your date into [ZonedDateTime](https://docs.oracle.com/javase/8/docs/api/java/time/ZonedDateTime.html). – Stefan Warminski May 23 '17 at 09:59
  • You should [set your date timezone](https://docs.oracle.com/javase/7/docs/api/java/text/DateFormat.html#setTimeZone(java.util.TimeZone)) first. – Turtle May 23 '17 at 10:04

7 Answers7

4

Class Date doesn't contain any timezone at all. It's just a number of milliseconds since 01.01.1970 00:00:00 GMT. If you try to see, what formattedDate contains with System.out.println or debugger, you'll get formatted date for your local timezone. 11:24:59 CDT and 16:24:59 UTC are the same time, so result is correct.

Is java.util.Date using TimeZone?

It is better to use jodatime or Java 8 Time API in order to better manage time and timezones.

Feedforward
  • 4,521
  • 4
  • 22
  • 34
  • A `Date` object contains the number of *milliseconds* since 01-01-1970, 00:00:00 GMT (not seconds, which is Unix time). – Jesper May 23 '17 at 10:06
  • 1
    [The JodaTime homepage](http://www.joda.org/joda-time/) says “Users are now asked to migrate to java.time (JSR-310).” So The Java 8 date and time API is most recommended. – Ole V.V. May 23 '17 at 10:07
2

First, you are getting the correct time. When Daylight Savings Time is in use in Chicago (which it is on May 18), the time is 11:24:59 when it’s 16:24:59 in UTC. So your Date value represents the same point in time. This is all you can expect from a Date.

I understand that you want not just a point in time, but also the UTC time zone. Since Axel P has already recommended Java 8 date and time API, I just wanted to fill in the details:

    DateTimeFormatter parseFormatter = DateTimeFormatter.ofPattern(dateFormatStr, Locale.US);
    ZonedDateTime dateTime = ZonedDateTime.parse(strDate, parseFormatter);

The result is

2017-05-18T16:24:59Z[UTC]

If you always want the UTC time zone, the Instant class is just right for it, so you will probably want to convert to it:

    Instant instant = dateTime.toInstant();

Instants are always in UTC, popularly speaking.

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
0

SimpleDateFormat myFmt=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date now=new Date(); System.out.println(myFmt.format(now)); I hope I can help you. If you can,please adopt.Thank you

Jack
  • 111
  • 5
0

The resulting value of formattedDate is- "Thu May 18 11:24:59 CDT 2017" . Why? because your time zone running -5 hour from UTC time you will find in below link wiki time zone abbreviations, if you want result in same timezone you need to specify timezone in formater Hope you get my concern

https://en.wikipedia.org/wiki/List_of_time_zone_abbreviations

public static void amethod1() {
        String strDate = "Thu May 18 16:24:59 UTC 2017";
        String dateFormatStr = "EEE MMM dd HH:mm:ss zzz yyyy";
        SimpleDateFormat dateFormat = new SimpleDateFormat(dateFormatStr);
        dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));

        Date formattedDate = null;
        try {
            formattedDate = dateFormat.parse(strDate);
        } catch (ParseException e) {
            e.printStackTrace();
        }

        System.out.println("formattedDate: "+dateFormat.format(formattedDate));

    }
Piyush Patel
  • 371
  • 1
  • 5
  • 13
0

You specified timezone, that's why after parsing time on current timezone (where you are), SimpleDateFormat sets UTC timezone. When you try to output your date, it is displayed on your current timezone

nikelyn
  • 518
  • 3
  • 13
0

It appears you would need to specify the TimeZone as well when you format the Date For eg. .TimeZone.setDefault(TimeZone.getTimeZone("PST")); Have a look at this discussion TimeZone

0

The output of a Date depends on the format specified, where you can specify the timezone, as shown in the example below:

protected void amethod2() {
    String strDate = "Thu May 18 16:24:59 UTC 2017";
    String dateFormatStr = "EEE MMM dd HH:mm:ss zzz yyyy";
    DateFormat dateFormat = new SimpleDateFormat(dateFormatStr);

    Date formattedDate = null;
    try {
        formattedDate = dateFormat.parse(strDate);
    } catch (ParseException e) {
        e.printStackTrace();
    }
    System.out.println("Date: " + formattedDate);
    // Thu May 18 17:24:59 BST 2017, BST is my system default timezone

    // Set the time zone to UTC for the calendar of dateFormat
    dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
    System.out.println("Date in timezone UTC: " + dateFormat.format(formattedDate));
    // Thu May 18 16:24:59 UTC 2017

    // Set the time zone to America/Chicago
    dateFormat.setTimeZone(TimeZone.getTimeZone("America/Chicago"));
    System.out.println("Date in timezone America/Chicago: " + dateFormat.format(formattedDate));
    // Thu May 18 11:24:59 CDT 2017
}

As for the IDs, such as "UTC" and "America/Chicago" in the example, you can get a complete list of them via TimeZone.getAvailableIDs(). You can print them out to have a look:

Arrays.stream(java.util.TimeZone.getAvailableIDs()).forEach(System.out::println);

And you'll have:

Africa/Abidjan
Africa/Accra
Africa/Addis_Ababa
Africa/Algiers
Africa/Asmara
Africa/Asmera
Africa/Bamako
Africa/Bangui
Africa/Banjul
Africa/Bissau
Africa/Blantyre
...
Yuci
  • 27,235
  • 10
  • 114
  • 113