0

I want to convert a date to GMT.

I get a date in BST, I want to convert it to GMT without time zone conversion. Example: **If the BST date is: Wed June 26 13:30:13 BST 2019

I want to convert it to Wed 26 Jun 2019 13:30:13 GMT**

I want to ignore the timezone info and return the same date as GMT.

For this I am trying

        private SimpleDateFormat dateFormatLocal = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
            private SimpleDateFormat dateFormatGmt = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
            private SimpleDateFormat dateFormatGmtText = new SimpleDateFormat("EEE dd MMM yyyy HH:mm:ss 'GMT'");

              dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));
          String textDate = dateFormatLocal.format(date);

//Date is Wed June 26 13:30:13 BST 2019
    private Date toGMTDate(final Date date) {
            String textDate = dateFormatLocal.format(date);
            try {
                String[] dateParts = textDate.split("\\+");
                textDate = dateParts[0] + "+0000";
                return dateFormatGmt.parse(textDate);
            } catch (ParseException e) {
                return null;
            }
        }

        private String toGMT(final Date date) {
            return dateFormatGmtText.format(toGMTDate(date));
        }

When I call toGMT it returns Wed 26 Jun 2019 14:30:13 GMT

I am not sure why it is so? What is wrong here?

Ashwani K
  • 7,880
  • 19
  • 63
  • 102
  • 4
    A `Date` is just a number of milliseconds since the unix epoch. It doesn't have a time zone. It's unclear where your data is coming from, or in what format, but this sounds like something which is better fixed earlier on. I'd also strongly recommend using java.time rather than `Date`, `SimpleDateFormat` etc. – Jon Skeet Jun 26 '19 at 12:32
  • 3
    I recommend you don’t use `SimpleDateFormat` and `Date`. Those classes are poorly designed and long outdated, the former in particular notoriously troublesome. Instead use `ZonedDateTime`, `OffsetDateTime` and `DateTimeFormatter`, all from [java.time, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/). – Ole V.V. Jun 26 '19 at 12:38
  • You don’t get a `Date` in BST and you cannot convert to a `Date` in GMT. An old-fashioned `Date` object can have neither time zone nor GMT offset. – Ole V.V. Jun 26 '19 at 12:39
  • I think this is a duplicate of [SimpleDateFormat returns wrong time zone during parse](https://stackoverflow.com/questions/16107898/simpledateformat-returns-wrong-time-zone-during-parse) and other questions. – Ole V.V. Jun 26 '19 at 12:42
  • Since you want it as a String anyway, why not just replace the String "BST" with "GMT" and be done with it? – Tom Jun 26 '19 at 12:42
  • @OleV.V. Thanks for the comment. I am aware of the new time library, but for some reasons I can't use them. – Ashwani K Jun 26 '19 at 12:47

1 Answers1

2

java.time

You said you can’t use the modern date and time API, but for other readers I should like to present that option first. SimpleDateFormat and Date are poorly designed and long outdated, the former in particular notoriously troublesome, so I recommend avoiding them.

I am assuming that BST is for British Summer Time (other interpretations exist). And I am assuming that you cannot avoid getting an old-fashioned Date object.

private static DateTimeFormatter formatter
        = DateTimeFormatter.ofPattern("EEE dd MMM yyyy HH:mm:ss z", Locale.UK);
private static ZoneId britain = ZoneId.of("Europe/London");
private static ZoneId gmt = ZoneId.of("Etc/GMT");

private static String toGMT(final Date date) {
    ZonedDateTime britishTime = date.toInstant().atZone(britain);
    ZonedDateTime gmtTime = britishTime.withZoneSameLocal(gmt);
    return gmtTime.format(formatter);
}

Try it out with your Date of Wed Jun 26 13:30:13 BST 2019:

    String textDate = dateFormatLocal.format(date);
    System.out.println(textDate);

    System.out.println(toGMT(date));

Output is:

2019-06-26T13:30:13+0100
Wed 26 Jun 2019 13:30:13 GMT

Whenever you get an old-fashioned Date, the first thing to do is to convert it to Instant. Then do any further conversions from there. The key to changing time zone and keeping the date and time of day (hour-minute-second of day) is the withZoneSameLocal method of the ZonedDateTime class.

I recommend specifying locale for the formatter.

I am not sure why it is so? What is wrong here?

A Date hasn’t got, as in cannot have a time zone. It’s a point in time, nothing more. YourtoGMTDate method returns a point in time that is an hour later: The time you gave it was 13:30:13+0100, and it returned 13:30:13+0000, which is the same point in time as 14:30:13+0100. Next you formatted this point in time using a formatter that used your default time zone, Europe/London, and therefore produced 14:30:13, but at the same time printed GMT in the string — the result you reported.

…the new time library, but for some reasons I can't use them.

If you really have got an evil boss that either forces you to use Java 1.4 or 1.5 and/or forbids the use external dependencies, the pretty simple hack is:

private String toGMT(final Date date) {
    return dateFormatGmtText.format(date);
}

The cheating is: Your dateFormatGmtText uses your default time zone, Europe/London, but lies and prints GMT in the formatted string. This gives the same output as above — the output you asked for. Compared to your code I am just leaving out the date conversion.

Link: Oracle tutorial: Date Time explaining how to use java.time.

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