0
SimpleDateFormat from = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
SimpleDateFormat to = new SimpleDateFormat("MM/dd/yyyy Z");
Date date = from.parse("2017-08-10T00:00:00.000+0000");
String newDateStr = to.format(date);

The newDateStr is 08/09/2017 -0500. I expect that newDataStr can have the same timezone as the original date string(0000) -- 08/10/2017 -0000. What should I do to achieve this?

user2777473
  • 3,736
  • 5
  • 26
  • 39
  • Your question isn't very clear.. Could you please explain further? – GalAbra Jan 29 '18 at 20:39
  • Which Java Version do you need to use? The new Java 8 Date API is much more convenient. Do you need to convert exactly to this format. Otherwise I would recommend to use the ISO 8601 representation of a date. – Stefan Großmann Jan 29 '18 at 20:51
  • @StefanGroßmann I am using Java 8. I need to convert to MM/dd/yyyy format. Could you please provide more details on the suggested API you mentioned? – user2777473 Jan 29 '18 at 20:58
  • @GalAbra I want to convert "2017-08-10T00:00:00.000+0000" to "08/10/2017 +0000". I don't know how to achieve this. Hope this makes the question clear. Thanks – user2777473 Jan 29 '18 at 21:00
  • 1
    It’s not supposed to work that way. A `Date` doesn’t have a time zone or offset, so there’s no way to preserve it in what you are doing. See [How to set offset of a java.util.Date?](https://stackoverflow.com/questions/39557374/how-to-set-offset-of-a-java-util-date) Much easier to solve your task with [`java.time`, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/). – Ole V.V. Jan 29 '18 at 21:08

2 Answers2

3

Preserving the offset from the original string is much easier with java.time, the modern Java date and time API:

    DateTimeFormatter from = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSSZ");
    DateTimeFormatter to = DateTimeFormatter.ofPattern("MM/dd/yyyy Z");
    String newDateStr = OffsetDateTime.parse("2017-08-10T00:00:00.000+0000", from)
            .format(to);
    System.out.println(newDateStr);

This prints

08/10/2017 +0000

This is not the only reason for recommending changing to the modern API. The Date class that you are using is long outdated, and SimpleDateFormat in particular is renowned for being troublesome to work with. I always recommend staying away from those classes in 2018. The modern API is generally much nicer. And since you are already using Java 8, there is absolutely no reason why you shouldn’t want it (for anyone reading along and using Java 6 or 7, the new API has been backported to those Java versions too).

What went wrong?

An old-fashioned Date object is just a point in time, it doesn’t hold a time zone or offset in it. So after you had parsed your string into a Date, the offset information was no longer there. So neither the Date nor to, the new formatter, had any way of knowing which offset or time zone had been in the original string. Instead, the new formatter used its own time zone. Since you had not explicitly set a time zone on the formatter, its time zone was that of your JVM, which apparently was a time zone that was on offset -5 from UTC on these days of September 2017.

There are tricky ways to solve the problem with the outdated classes, but as I have probably said already, I wouldn’t want to bother.

"Call requires API Level 26" for Android

@Ponomarenko Oleh in a comment writes:

Pay attention: "Call requires API Level 26" for Android.

However, java.time works nicely on both older and newer Android devices. It just requires at least Java 6.

  • In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in. This is also the intended meaning of the message quoted in the comment.
  • In non-Android Java 6 and 7 get the ThreeTen Backport, the backport of the modern classes (ThreeTen for JSR 310; see the links at the bottom).
  • On (older) Android use the Android edition of ThreeTen Backport. It’s called ThreeTenABP. And make sure you import the date and time classes from org.threeten.bp with subpackages.

Links

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

You could use the Java 8 Date API which provides a good set of functionality to convert dates into strings (including timezone support).

An example:

    ZonedDateTime dateTime = ZonedDateTime.parse("2017-08-10T00:00:00.000+0000", DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ"));
    String newDateStr = dateTime.format(DateTimeFormatter.ofPattern("dd/MM/yyyy Z"));

For more information you can look at:

Stefan Großmann
  • 866
  • 9
  • 20