Harish Gupta
Harish Gupta

Reputation: 402

converting one time zone to another using joda time

i have made a function to convert from one time zone to another by using joda time but the function is not accepting the date
i have passed the following parameters to this function "Asia/Kolkata", "UTC", "12-Dec-2014 12:30". It is throwing the following exception:

Exception in thread "main" java.lang.IllegalArgumentException: Invalid format: "12-Dec-2014 12:32" is malformed at "-Dec-2014 12:32"
at org.joda.time.format.DateTimeFormatter.parseMillis(DateTimeFormatter.java:752)
at org.joda.time.convert.StringConverter.getInstantMillis(StringConverter.java:65)
at org.joda.time.base.BaseDateTime.<init>(BaseDateTime.java:150)
at org.joda.time.DateTime.<init>(DateTime.java:265)
at Dtime.convertTimeZones(Dtime.java:17)
at Dtime.main(Dtime.java:9) 

Here is the code:

public static String convertTimeZones( String fromTimeZoneString, 
    String toTimeZoneString, String fromDateTime) {
         DateTimeZone fromTimeZone = DateTimeZone.forID(fromTimeZoneString);
         DateTimeZone toTimeZone = DateTimeZone.forID(toTimeZoneString);
         DateTime dateTime = new DateTime(fromDateTime, fromTimeZone);

         DateTimeFormatter outputFormatter = 
             DateTimeFormat.forPattern("dd-MMM-yyyy HH:mm").withZone(toTimeZone);
         return outputFormatter.print(dateTime);
}

DST (day light savings )
i am passing the parameters as ("America/Denver","GMT","09-Mar-2014 02:00")on this date the DST will start
for denver
Sunday, 9 March 2014, 02:00:00 clocks are turned forward 1 hour to
Sunday, 9 March 2014, 03:00:00 local daylight time instead
but it is throwing the exception
Exception

Exception in thread "main" java.lang.IllegalArgumentException: Cannot parse "09-Mar-2014 02:00": Illegal instant due to time zone offset transition (America/Denver)
    at org.joda.time.format.DateTimeParserBucket.computeMillis(DateTimeParserBucket.java:390)
    at org.joda.time.format.DateTimeFormatter.parseDateTime(DateTimeFormatter.java:849)
    at timeZone.convertTimeZones(timeZone.java:23)
    at timeZone.main(timeZone.java:14)

Upvotes: 3

Views: 3203

Answers (2)

Arvind Kumar Avinash
Arvind Kumar Avinash

Reputation: 78945

java.time

Shown below is a notice on the Joda-Time Home Page:

Note that from Java SE 8 onwards, users are asked to migrate to java.time (JSR-310) - a core part of the JDK which replaces this project.

Solution using java.time, the modern date-time API in Java

You can do it with the following steps:

  1. Your date-time string e.g. 12-Dec-2014 12:30 does not have timezone information. Therefore parse it to a LocalDateTime using an appropriate DateTimeFormatter.
  2. Add the source ZoneId to the obtained LocalDateTime to make it a ZonedDateTime.
  3. Use ZonedDateTime#withZoneSameInstant to convert the source ZonedDateTime to the target ZonedDateTime.
  4. Format and return the obtained ZonedDateTime with the same DateTimeFormatter.

Demo:

class Main {
    private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern(
            "dd-MMM-uuuu HH:mm", Locale.ENGLISH);

    public static void main(String[] args) {
        // Tests
        System.out.println(convertTimeZones(
                "Asia/Kolkata", "UTC", "12-Dec-2014 12:30"));
        System.out.println(convertTimeZones(
                "America/Denver", "GMT", "09-Mar-2014 02:00"));
        System.out.println(convertTimeZones(
                "America/Denver", "Europe/Berlin", "09-Mar-2014 02:00"));
    }

    public static String convertTimeZones(
            String fromTimeZoneString, String toTimeZoneString, String fromDateTime) {

        ZoneId sourceZone = ZoneId.of(fromTimeZoneString);
        ZoneId targetZone = ZoneId.of(toTimeZoneString);

        LocalDateTime ldt = LocalDateTime.parse(fromDateTime, FORMATTER);

        ZonedDateTime sourceZdt = ldt.atZone(sourceZone);
        ZonedDateTime targetZdt = sourceZdt.withZoneSameInstant(targetZone);

        return targetZdt.format(FORMATTER);
    }
}

Output:

12-Dec-2014 07:00
09-Mar-2014 09:00
09-Mar-2014 10:00

Try it on Ideone

Note: Your date-time string has alphabets in English; therefore, do not forget to use an English Locale e.g. Locale.ENGLISH with your DateTimeFormatter. Check Always specify a Locale with a date-time formatter for custom formats to learn more about it.

Learn more about the modern Date-Time API from Trail: Date Time.

Upvotes: 2

Elliott Frisch
Elliott Frisch

Reputation: 201399

You need to parse your date with an inputFormatter (like the outputFormatter you've already defined). Something like this

DateTimeFormatter inputFormatter = DateTimeFormat.forPattern(
    "dd-MMM-yyyy HH:mm").withZone(fromTimeZone);
DateTime dateTime = inputFormatter.parseDateTime(fromDateTime);

Which I tested, and it outputs

12-Dec-2014 07:00

Upvotes: 2

Related Questions