0

I have a trouble on the timezone changer. I use the code

for (int i = 0; i < data.size(); i++) {
        try {
            String time = (String) data.get(i).get("time_utc_8");
            time = time.replace('+', '-');

            String pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSSSSXXX";
            SimpleDateFormat sdf = new SimpleDateFormat(pattern);
            TimeZone tz = TimeZone.getTimeZone("UTC+8");
            sdf.setTimeZone(tz);
            Date dateTime = sdf.parse(time);

            String pattern_2 = "yyyy-MM-dd HH:mm:ss.SSSSSS";
            SimpleDateFormat sdf_2 = new SimpleDateFormat(pattern_2);
            String d = sdf_2.format(dateTime);

            data.get(i).put("time_utc_8", d);

            // System.out.println(data.get(i).get("time"));

        } catch (JSONException e) {
            e.printStackTrace();
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

to parse and change the timezone.

This is my example input:

2016-06-26T16:32:31.654120+00:00

And I get the output:

2016-06-27 00:43:25.000120

But the correct output must be:

2016-06-27 00:32:31.654120

How can I resolve the problem?

Zi-yan Tseng
  • 184
  • 1
  • 1
  • 14
  • 1
    I cannot more strongly advise against using the legacy `java.util.Date`. You should instead look in the `java.time` package for the most appropriate class for your needs. – Joe C Jun 10 '17 at 20:46
  • @JoeC hence, the problem is the `java.util.Date` ? – Zi-yan Tseng Jun 10 '17 at 20:48
  • 1
    @Zi-yanTseng `java.util.Date` is outdated and has tons of bugs: https://stackoverflow.com/questions/1969442/whats-wrong-with-java-date-time-api - And it's being replaced by the new API, that I showed how to use in my answer below –  Jun 10 '17 at 21:05

1 Answers1

1

First of all, take a look at the javadoc for SimpleDateFormat: the S pattern is for the milliseconds field, and its maximum value is 999.

To parse 6 digits as a fraction-of-second, you can use the new java.time classes (if you use Java >= 8) or the ThreeTen Backport (for Java <= 7) - these new classes support more than 3 digits in fraction-of-second field.

The code below works for both, the only difference is the package names (java.time and java.time.format for Java >= 8 or org.threeten.bp and org.threeten.bp.format for Java <= 7). But the classes and methods names are the same:

// parser (format with 6 digits in fraction of second)
DateTimeFormatter parser = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSSSSXXX");
// parse input, use UTC+8 (ZoneOffset.ofHours(8))
ZonedDateTime dt = ZonedDateTime.parse("2016-06-26T16:32:31.654120+00:00", parser)
    .withZoneSameInstant(ZoneOffset.ofHours(8));

// formatter for output, using your format
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSSS");
System.out.println(formatter.format(dt)); // 2016-06-27 00:32:31.654120

The output will be:

2016-06-27 00:32:31.654120