【问题标题】:Joda Time - Convert UTC DateTime to Date - Using a Version 1.2.1.1 of JodaJoda Time - 将 UTC DateTime 转换为日期 - 使用 Joda 的 1.2.1.1 版本
【发布时间】:2015-09-18 17:52:58
【问题描述】:

大家早上好。

我想帮助您了解如何使用 1.2.1.1 版本的 Joda Time 完成 org.joda.time.DateTime 到 java.util.Date 的转换。

为什么选择 Joda 1.2.1.1 ?因为目前我“不幸”只能使用这个版本的 Joda。

我的测试>

    System.out.println("JODA Version : 2.8.2 - UTC TIME to Date " + new DateTime().withZone(DateTimeZone.UTC).toLocalDateTime().toDate());;
    System.out.println("JODA Version : 1.2.1.1 - UTC TIME to Date " + new DateTime().withZone(DateTimeZone.UTC).toDate());;


JODA Version : 2.8.2 - UTC TIME to Date Fri Sep 18 17:34:36 BRT 2015
JODA Version : 1.2.1.1 - UTC TIME to Date Fri Sep 18 14:34:36 BRT 2015

我的问题是,在 1.2.1.1 版本中,日期在我的本地设置中,而在这个版本中,没有 toLocalDateTime() 方法。

我希望您能提供帮助和经验以发现最佳实践,以便在 JODA 版本:1.2.1.1 中执行此转换

在旧版本的 JODA 中,我如何执行此转换为 UTC 中的小时:分钟:秒?

我进行了很多研究,发现有人说这样做会是一个好习惯吗?

public  static Date converterDateTimeToUTCDate(final DateTime dateTime) throws ParseException {
    DateTime dat = dateTime.withZone(DateTimeZone.UTC);
    return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS").parse(dat.toString("yyyy-MM-dd HH:mm:ss:SSS"));
}

public static void main(String[] args) throws ParseException {
    System.out.println("TODO DATE UTC TIME : " + new DateTime().withZone(DateTimeZone.UTC));
    System.out.println("TODO DATE Convertion Direct Date: " + new DateTime().withZone(DateTimeZone.UTC).toDate());

    Date converterUTCDateTimeToDate = converterDateTimeToUTCDate(new DateTime());

    System.out.println("TODO DATE UTC with Parse : " + converterUTCDateTimeToDate);

}

结果:

TODO DATE UTC TIME : 2015-09-18T22:33:57.353Z
TODO DATE Convertion Direct Date: Fri Sep 18 19:33:57 BRT 2015
TODO DATE UTC with Parse : Fri Sep 18 22:33:57 BRT 2015

编辑 为什么选择 Joda 1.2.1.1 ?因为目前我“不幸”只能使用这个版本的 Joda。

我在一家公司工作,在项目中更改 API 的版本需要很长时间,而我的项目没有等待时间来使用新版本

更新:

我看了java Date没有TimeZone,这个BRT是从我本机在类的toString()方法中抓到的,那我可以认为是转换对了吗?

更新 2

我编辑了我的答案示例:

见:

package joda;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;

import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;

public class ConverterDateTimeToDate {
    public static final String BASE_FORMAT = "yyyy-MM-dd HH:mm:ss.SSS z";

    public static void main(String[] args) {

        // Different display time zones

        SimpleDateFormat formatUTC = new SimpleDateFormat( BASE_FORMAT );
        formatUTC.setTimeZone(TimeZone.getTimeZone("UTC"));

        SimpleDateFormat formatBrazil = new SimpleDateFormat( BASE_FORMAT );
        formatBrazil.setTimeZone(TimeZone.getTimeZone("America/Sao_Paulo"));

        SimpleDateFormat formatCentralEurope = new SimpleDateFormat( BASE_FORMAT );
        formatCentralEurope.setTimeZone(TimeZone.getTimeZone("Europe/Amsterdam"));

        // Get a date in UTC

        String dateString = "2015-09-19 10:45:00.000 UTC";
        Date javaDate = null;
        try {
            DateTime dateTime = new DateTime().withZone(DateTimeZone.forID("America/Mexico_City"));
System.out.println("MEX TIME IN JODA : " + dateTime); //new Test
            System.out.println("MEX TIME IN JODA CONVERTER : " + dateTime.toDate()); // new Test
            System.out.println("Now in MEX Time Zone DateTime : " + dateTime);

            javaDate = formatUTC.parse(dateTime.toString(BASE_FORMAT));
        } catch (ParseException e) {
            e.printStackTrace(); // Shouldn't happen.
        }

        // Now let's print it in various time zones. It's the same date - 10:45 in UTC!

        System.out.println("In UTC:             " + formatUTC.format(javaDate));
        System.out.println("In Brazil:          " + formatBrazil.format(javaDate));
        System.out.println("In the Netherlands: " + formatCentralEurope.format(javaDate));

    }
}

我的输出:在 UTC:2015-09-19 12:10:56.731 CDT,我的转换有问题吗?因为我在 System 中的 DateTime 已经消失了

我的输出:

MEX TIME IN JODA : 2015-09-21T21:17:46.781-05:00
MEX TIME IN JODA CONVERTER : Mon Sep 21 23:17:46 BRT 2015
Now in MEX Time Zone DateTime : 2015-09-21T21:17:46.781-05:00
In UTC:             1732-01-11 02:17:46.781 UTC
In Brazil:          1732-01-10 23:17:46.781 BRT
In the Netherlands: 1732-01-11 03:17:46.781 CET

【问题讨论】:

  • 问题是不同的,我在问如何在保持 UTC 时区的情况下执行转换的最佳方式,因为它是旧版本不提供这种支持我
  • 我不明白您为什么需要使用旧版本。你能edit进一步解释吗?
  • 好吧,似乎没有 toLocalDateTime() 的版本是正确的,因为它打印了实际正确的时间。问题出在哪里?
  • 我需要 UTC 时间的日期,而不是我当前的时间

标签: java datetime jodatime utc


【解决方案1】:

正确的方法是使用toDate()

DateTime 类中的方法,即使在旧的 JodaTime 中,也是正确的方法。这是一个解释:


解释java.util.Date 的工作原理

您似乎对java.util.Date 有误解。它不包含时区。它表示自 1970 年 1 月 00:00 UTC 以来的时间偏移。

当您打印 Date 对象时,您的 JVM 会采用您的 默认时区 并向您显示该时区的 Date。因此,当您打印日期时,如果您想在不同的时区查看日期,则应始终使用 DateFormat 对象。例如,如果要查看 UTC 中的日期,则必须使用将时区设置为 UTC 的日期格式。这是一个例子:

public static final String BASE_FORMAT = "yyyy-MM-dd HH:mm:ss.SSS z";

public static void main(String[] args) {

    // Different display time zones

    SimpleDateFormat formatUTC = new SimpleDateFormat( BASE_FORMAT );
    formatUTC.setTimeZone(TimeZone.getTimeZone("UTC"));

    SimpleDateFormat formatBrazil = new SimpleDateFormat( BASE_FORMAT );
    formatBrazil.setTimeZone(TimeZone.getTimeZone("America/Sao_Paulo"));

    SimpleDateFormat formatCentralEurope = new SimpleDateFormat( BASE_FORMAT );
    formatCentralEurope.setTimeZone(TimeZone.getTimeZone("Europe/Amsterdam"));

    // Get a date in UTC

    String dateString = "2015-09-19 10:45:00.000 UTC";
    Date javaDate = null;
    try {
        javaDate = formatUTC.parse(dateString);
    } catch (ParseException e) {
        e.printStackTrace(); // Shouldn't happen.
    }

    // Now let's print it in various time zones. It's the same date - 10:45 in UTC!

    System.out.println("In UTC:             " + formatUTC.format(javaDate));
    System.out.println("In Brazil:          " + formatBrazil.format(javaDate));
    System.out.println("In the Netherlands: " + formatCentralEurope.format(javaDate));

}

这个程序的输出是:

UTC 时间:2015-09-19 10:45:00.000 UTC
在巴西:2015-09-19 07:45:00.000 BRT
在荷兰:2015-09-19 12:45:00.000 CEST

您可以看到我们打印了相同的日期 - 根据格式的时区显示不同。


从 Joda TimeStamp 正确转换为 java.util.Date

同样的逻辑也适用于 Joda 的 DateTime 对象,但它更复杂,因为它还包括一个时区,尽管它并不用于所有操作。在内部,它还表示与 UTC 的偏移量。

当您使用它的 toDate() 方法时,它依赖于与 UTC 的内部偏移量,因此它根据 java.util.Date 合约为您提供正确的 Date 对象

让我们通过将上述程序中获取日期的方式替换为:

DateTime jodaDateTime = new DateTime( 2015, 9, 19, 10, 45, 0, 0, DateTimeZone.UTC);

Date javaDate = jodaDateTime.toDate();

现在,运行与以前相同的打印,我们再次得到:

UTC 时间:2015-09-19 10:45:00.000 UTC
在巴西:2015-09-19 07:45:00.000 BRT
在荷兰:2015-09-19 12:45:00.000 CEST

所以你看,如果 Joda DateTime 设置得当,那么使用它的 toDate 会给你正确的 Date 对象。


显示使用toLocalDateTime()是错误的

现在,如果我们使用您的第一种方法,您认为正确的方法,仅存在于 Joda 2.0 及更高版本中,我们会得到什么?

我们把代码改成:

DateTime jodaDateTime = new DateTime( 2015, 9, 19, 10, 45, 0, 0, DateTimeZone.UTC);
Date javaDate = jodaDateTime.toLocalDateTime().toDate();

Joda DateTime 和之前一样,我们只是添加了仅存在于 Joda 2 中的 toLocalDateTime()

假设您系统上的默认时区是 BRT,您会得到结果:

UTC 时间:2015-09-19 13:45:00.000 UTC
在巴西:2015-09-19 10:45:00.000 BRT
在荷兰:2015-09-19 15:45:00.000 CEST

这显然不是正确的日期! toLocalDateTime() 部分获取您的本地时间偏移并将其添加到日期以形成“本地”日期。只要您保持在 Joda 时间结构内,这很好,但会违反 java.util.Date 的合同,因为它设置了与 UTC 的错误偏移量。


结论

您在旧 Joda 中使用的旧方法是从 org.joda.time.DateTime 获得合适的 java.util.Date 的最佳方法。但是您必须非常小心如何打印java.util.Date,因为它将在您的默认时区默认打印。

最后一条建议:如果您想在公司开始升级过程,请不要打扰 Joda 时间。要求他们开始将系统升级到 Java 8,这是目前 Oracle 维护的唯一 Java 版本。 Java 8 包含一个合适的日期/时间库,Joda 的创建者建议改用它。

【讨论】:

  • 对不起,但仍然不清楚我应该如何进行这种转换,因为 BASE_FORMAT,不适合 DateTime,我再次更新了问题结束 UPDATE 2
猜你喜欢
  • 2021-07-19
  • 2018-09-21
  • 2011-09-09
  • 1970-01-01
  • 1970-01-01
  • 2016-06-19
  • 2011-06-07
  • 1970-01-01
  • 2020-06-24
相关资源
最近更新 更多