0

I need to convert TimeZone in my project from UTC to IST and vice versa. For that purpose I am using Joda time jar in my project. But the problem occurs when I try to convert the string from UTC to IST, I am getting the same value instead of getting converted IST value. Kindly please mentor me in which part of code I am completely stuck up. My code is as follows:

public class JodaDemo {

    public static final String DATE_PATTERN_SERVICE = "yyyy-MM-dd HH:mm:ss";
    public static final String DATE_PATTERN_SERVICE_NO_SECONDS = "yyyy-MM-dd HH:mm";

    public static void main(String[] args) {

        getDateFromUTCtoIST("2015-08-23 10:34:40");

    }
private static void getDateFromUTCtoIST(String dateTime) {

        DateTimeFormatter dtf = DateTimeFormat.forPattern(DATE_PATTERN_SERVICE);
        DateTime jodatime = dtf.parseDateTime(dateTime);
        DateTimeZone indianTimeZone = DateTimeZone.forID("Asia/Kolkata");
        DateTime indianTime = jodatime.withZone(indianTimeZone);

        System.out.println(indianTime);

    }

OUTPUT:

2015-08-23T10:34:40.000+05:30

Expected output:

Converted TimeZone (+5:30 output) like in yyyy-MM-dd HH:mm:ss format

Chandru
  • 5,954
  • 11
  • 45
  • 85

2 Answers2

3

There are two problems here. Firstly, when you're parsing the value you're not specifying the time zone - so it's using your local time zone. Secondly, you're not using any formatter for the result - you're just calling DateTime.toString(), implicitly.

The simplest approach is actually to create two formatters for the same pattern, one in UTC and one in the relevant time zone - then you don't need to manually convert at all, as the formatter can do it for you:

import java.util.*;
import org.joda.time.*;
import org.joda.time.format.*;

public class Test {

  public static final String DATE_PATTERN_SERVICE = "yyyy-MM-dd HH:mm:ss";

    public static void main(String[] args) {        
        DateTimeFormatter utcFormatter = DateTimeFormat
            .forPattern(DATE_PATTERN_SERVICE)
            .withLocale(Locale.US)
            .withZoneUTC();
        DateTimeZone indianZone = DateTimeZone.forID("Asia/Kolkata");
        DateTimeFormatter indianZoneFormatter = utcFormatter.withZone(indianZone);

        String utcText = "2015-08-23 10:34:40";
        DateTime parsed = utcFormatter.parseDateTime(utcText);
        String indianText = indianZoneFormatter.print(parsed);
        System.out.println(indianText); // 2015-08-23 16:04:40
    }
}
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Thanks @Jon Skeet. This is simply awesome and it is working great. Also if possible can you please help me to do vice versa method (i.e from IST to UTC). I will accept this answer. Thanks for helping me! – Chandru Sep 25 '15 at 08:25
  • @Chandru: Well to do the reverse, just parse with `indianZoneFormatter` and print with `utcFormatter`... but note that in time zones which observe daylight saving time (I know the Indian time zone doesn't, at the moment) this can lead to ambiguities. – Jon Skeet Sep 25 '15 at 08:47
  • Thanks got it. Implemented successfully. – Chandru Sep 25 '15 at 08:51
1

java.time

Quoted below is a notice from the home page of Joda-Time:

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:

import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        String strDateTime = "2015-08-23 10:34:40";
        
        DateTimeFormatter parser = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss", Locale.ENGLISH);
        LocalDateTime ldt = LocalDateTime.parse(strDateTime, parser);
        
        ZonedDateTime zdtUtc = ldt.atZone(ZoneId.of("Etc/UTC"));

        ZonedDateTime zdtIndia = zdtUtc.withZoneSameInstant(ZoneId.of("Asia/Kolkata"));
        System.out.println(zdtIndia);

        OffsetDateTime odt = zdtIndia.toOffsetDateTime();
        System.out.println(odt);
    }
}

Output:

2015-08-23T16:04:40+05:30[Asia/Kolkata]
2015-08-23T16:04:40+05:30

ONLINE DEMO

Some important notes:

  1. If you are going to deal with JDBC, check this answer and this answer to learn how to use java.time API with JDBC.
  2. For any reason, if you need to convert this object of OffsetDateTime to an object of java.util.Date, you can do so as follows:
    Date date = Date.from(odt.toInstant());

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


* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.

Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110