使用 Joda 时间库从 UTC 到 IST 的转换在 JAVA 中返回相同的值

Conversion from UTC to IST returning same value in JAVA using Joda time library

我需要将项目中的时区从 UTC 转换为 IST,反之亦然。为此,我在我的项目中使用了 Joda time jar。但是当我尝试将字符串从 UTC 转换为 IST 时出现问题,我得到的是相同的值而不是转换后的 IST 值。请指导我在代码的哪一部分中完全陷入困境。我的代码如下:

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);

    }

输出:

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

预期输出:

转换时区(+5:30 输出),如 yyyy-MM-dd HH:mm:ss 格式

这里有两个问题。首先,当您解析值时,您没有指定时区 - 所以它使用的是您当地的时区。其次,您没有为结果使用任何格式化程序 - 您只是隐式调用 DateTime.toString()

最简单的方法实际上是为同一模式创建两个格式化程序,一个在 UTC 中,一个在相关时区中 - 然后您根本不需要手动转换,因为格式化程序可以为您完成:

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
    }
}

java.time

下面引用的是来自 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.

解决方案使用 java.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);
    }
}

输出:

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

ONLINE DEMO

一些重要说明:

  1. 如果您要处理 JDBC,请查看 this answer and this answer 以了解如何将 java.time API 与 JDBC 一起使用。
  2. 出于任何原因,如果您需要将OffsetDateTime的这个对象转换为java.util.Date的对象,您可以按如下方式进行:
    Date date = Date.from(odt.toInstant());

Trail: Date Time.

了解有关现代日期时间 API 的更多信息

* 无论出于何种原因,如果您必须坚持Java 6 或Java 7,您可以使用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