JodaTime - 如何让UTC当前时间

问题描述 投票:22回答:7

我想在UTC当前时间。我这样做多远以下(只是为了测试目的):

    DateTime dt = new DateTime();
    DateTimeZone tz = DateTimeZone.getDefault();
    LocalDateTime nowLocal = new LocalDateTime();
    DateTime nowUTC = nowLocal.toDateTime(DateTimeZone.UTC);

    Date d1 = nowLocal.toDate();
    Date d2 = nowUTC.toDate();

    L.d("tz: " + tz.toString());
    L.d("local: " + d1.toString());
    L.d("utc: " + d2.toString());
  • d1是我的本地时间,这很好
  • d2是我的本地时间+ 1,而应该是本地时间 - 1 ...

我的本地时区为UTC + 1(根据调试输出,在此列出:https://www.joda.org/joda-time/timezones.html)...

如何正确地从一个时区转换成另一种(包括毫秒表示)?

编辑

我需要的日期/毫秒......这不是正确显示时间....

编辑2

现在,随着评论的帮助和答案,我想以下几点:

    DateTimeZone tz = DateTimeZone.getDefault();
    DateTime nowLocal = new DateTime();
    LocalDateTime nowUTC = nowLocal.withZone(DateTimeZone.UTC).toLocalDateTime();
    DateTime nowUTC2 = nowLocal.withZone(DateTimeZone.UTC);

    Date dLocal = nowLocal.toDate();
    Date dUTC = nowUTC.toDate();
    Date dUTC2 = nowUTC2.toDate();

    L.d(Temp.class, "------------------------");
    L.d(Temp.class, "tz    : " + tz.toString());
    L.d(Temp.class, "local : " + nowLocal +     " | " + dLocal.toString());
    L.d(Temp.class, "utc   : " + nowUTC +       " | " + dUTC.toString()); // <= WORKING SOLUTION
    L.d(Temp.class, "utc2  : " + nowUTC2 +      " | " + dUTC2.toString());

OUTPUT

tz    : Europe/Belgrade
local : 2015-01-02T15:31:38.241+01:00 | Fri Jan 02 15:31:38 MEZ 2015
utc   : 2015-01-02T14:31:38.241 | Fri Jan 02 14:31:38 MEZ 2015
utc2  : 2015-01-02T14:31:38.241Z | Fri Jan 02 15:31:38 MEZ 2015

我想要的是,本地时间显示15点和UTC日期显示14点钟......现在,这似乎工作...

----- EDITZ - 最终的解决方案-----

我们希望,这是一个很好的解决方案。我想,我尊重所有的窍门我有...

    DateTimeZone tz = DateTimeZone.getDefault();
    DateTime nowUTC = new DateTime(DateTimeZone.UTC);
    DateTime nowLocal = nowUTC.withZone(tz);

    // This will generate DIFFERENT Dates!!! As I want it!
    Date dLocal = nowLocal.toLocalDateTime().toDate();
    Date dUTC = nowUTC.toLocalDateTime().toDate();

    L.d("tz    : " + tz.toString());
    L.d("local : " + nowLocal +     " | " + dLocal.toString());
    L.d("utc   : " + nowUTC +       " | " + dUTC.toString());

输出:

tz    : Europe/Belgrade
local : 2015-01-03T21:15:35.170+01:00 | Sat Jan 03 21:15:35 MEZ 2015
utc   : 2015-01-03T20:15:35.170Z | Sat Jan 03 20:15:35 MEZ 2015
java jodatime
7个回答
72
投票

你让他们更复杂得多,你需要:

DateTime dt = new DateTime(DateTimeZone.UTC);

没有转换所需的一切。如果你发现你确实需要转换,你可以使用withZone。我建议你避免通过LocalDateTime去,但是,由于这种方式你可能失去信息,由于时区转换(两个不同时刻可以有相同的时区相同的本地时间,因为时钟回去重复本地时间。

话虽如此,可测试性的缘故,我个人比较喜欢使用Clock接口,可以让我获得当前时间(例如,作为一个Instant)。然后,您可以使用依赖注入注入在生产环境中运行时,一个真实的系统时钟,和一个假的时钟与预设时间进行测试。 Java的8位的java.time包有这种想法把它建成,顺便说一句。


10
投票

您也可以使用静态方法now这使得它更可读

DateTime.now(DateTimeZone.UTC)

8
投票

用这个

DateTime.now().withZone(DateTimeZone.UTC)

如果你想要的格式,你可以使用

DateTime.now().withZone(DateTimeZone.UTC).toString("yyyyMMddHHmmss")

3
投票

请尽量听乔恩长柄水杓很好的建议和意见。这里补充说明。您编辑2包含一个错误:

DateTimeZone tz = DateTimeZone.getDefault();
DateTime nowLocal = new DateTime();
LocalDateTime nowUTC = nowLocal.withZone(DateTimeZone.UTC).toLocalDateTime();
DateTime nowUTC2 = nowLocal.withZone(DateTimeZone.UTC);

Date dLocal = nowLocal.toDate();
Date dUTC = nowUTC.toDate();
Date dUTC2 = nowUTC2.toDate();

如果你调用toDate()的类型nowUTC的对象LocalDateTime那么你可以得到惊喜 - 见javadoc。乔达时间声称在the same fields使用java.util.Date作为nowUTC。这是什么意思?让我们来分析一下:

nowUTC.toString()产生2015-01-02T14:31:38.241也就是说没有时区(注意最后失踪Z),所以它只是一个普通的本地时间戳。通过上下文,我们知道它是在UTC产生。在下一步但是,您使用上述提到的方法将其转换为java.util.Date。此方法结合了系统时区(贝尔格莱德)保存的字段,因此,改变了瞬间的本地时间戳。所以,你终于误纠您瞬间。和你的第二行是错误的。

如果你只是想

UTC日期显示14点

那么就不要使用有问题的和误导性的转换方法乔达时间提供。而使用有图案的专用格式“EEE MMM DD HH:MM:SS ZZZ YYYY”或类似(乔达时间提供DateTimeFormatter)。这个格式和打印设置UTC偏移。完成。彻底摒弃java.util.Date.toString()的任何电话。这样,你甚至不需要做任何危险的转换的。


2
投票

从这里:http://www.joda.org/joda-time/userguide.html#Changing_TimeZone

// get current moment in default time zone
DateTime dt = new DateTime();
// translate to London local time
DateTime dtLondon = dt.withZone(DateTimeZone.forID("Europe/London"));

所得到的值dtLondon具有相同的绝对毫秒时间,但一组不同的字段值。

您也可以替换`欧洲/伦敦”为你想要的时区(UTC)。见this list of proper time zone names


0
投票
    SimpleDateFormat sdf = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" );
    // or SimpleDateFormat sdf = new SimpleDateFormat( "MM/dd/yyyy KK:mm:ss a Z" );
    sdf.setTimeZone( TimeZone.getTimeZone( "UTC" ) );
    System.out.println( sdf.format( new Date() ) 

);

取而代之了System.out.println(sdf.format(新的Date())把你的本地日期


0
投票

我解决了这个问题这个转换器

public class DateTimeConverter implements AttributeConverter<DateTime, Date> {
    @Override
    public Date convertToDatabaseColumn(DateTime attribute) {
        return attribute == null ? null
                : new Date(attribute
                        .withZone(DateTimeZone.UTC)
                        .withZoneRetainFields(DateTimeZone.getDefault())
                        .getMillis());
    }

    @Override
    public DateTime convertToEntityAttribute(Date dbData) {
        return dbData == null ? null
               : new DateTime(dbData.getTime())
                        .withZoneRetainFields(DateTimeZone.UTC)
                        .withZone(DateTimeZone.getDefault());
    }
}

日期存储为UTC加上当前时区恢复

© www.soinside.com 2019 - 2024. All rights reserved.