JodaTime – 如何获得UTC的当前时间

我想以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(); Ld("tz: " + tz.toString()); Ld("local: " + d1.toString()); Ld("utc: " + d2.toString()); 
  • d1是我当地时间,没关系
  • d2是我当地时间+ 1,但应该是当地时间 – 1 …

我的本地时区是UTC + 1(根据调试输出和列表: http : //joda-time.sourceforge.net/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(); Ld(Temp.class, "------------------------"); Ld(Temp.class, "tz : " + tz.toString()); Ld(Temp.class, "local : " + nowLocal + " | " + dLocal.toString()); Ld(Temp.class, "utc : " + nowUTC + " | " + dUTC.toString()); // <= WORKING SOLUTION Ld(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点钟…现在,这似乎有效……

—– EDIT3 – 最终解决方案—–

希望这是一个很好的解决方案…我想,我尊重所有的tipps …

  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(); Ld("tz : " + tz.toString()); Ld("local : " + nowLocal + " | " + dLocal.toString()); Ld("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 

你做得比你需要的要复杂得多:

 DateTime dt = new DateTime(DateTimeZone.UTC); 

根本不需要转换 。 如果您发现实际需要转换,则可以使用withZone 。 我建议您避免通过LocalDateTime ,但是,由于时区转换,您可能会丢失信息(两个不同的时刻可能在同一时区内具有相同的本地时间,因为时钟会返回并重复本地时间。

说完所有这些之后,为了可测试性,我个人喜欢使用Clock接口来获取当前时间(例如,作为Instant )。 然后,您可以使用dependency injection在生产中运行时注入实际系统时钟,并使用具有预设测试时间的假时钟。 Java 8的java.time包内置了这个想法,顺便说一下。

您现在也可以使用静态方法,使其更具可读性

 DateTime.now(DateTimeZone.UTC) 

用这个

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

如果你想格式化,你可以使用

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

请尝试听听Jon Skeets的好建议和意见。 这是一个额外的解释。 你的edit-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(); 

如果你在类型为LocalDateTime的对象nowUTC上调用toDate() ,那么你会得到惊喜 – 请参阅javadoc 。 Joda-Time声称在java.util.Date使用the same fields nowUTC the same fields 。 这是什么意思? 我们来分析一下:

nowUTC.toString()生成2015-01-02T14:31:38.241这是没有时区的(注意末尾缺少的Z),所以它只是一个普通的本地时间戳。 根据上下文,我们知道它是以UTC格式生成的。 但是,在下一步中,使用上面提到的方法将其转换为java.util.Date 。 此方法将本地时间戳与系统时区(贝尔格莱德)保存为FIELDS,从而改变瞬间。 所以你最终错误地纠正了你的瞬间。 你的第二行是错的。

如果你只是想要

utc日期显示14点

然后不要使用Joda-Time提供的有问题和误导性的转换方法。 请使用具有“EEE MMM dd HH:mm:ss zzz yyyy”或类似模式的专用格式化程序(Joda-Time提供DateTimeFormatter )。 在此格式化程序上设置UTC偏移量并打印。 完成。 完全抛弃java.util.Date.toString()任何调用。 这样,您根本不需要进行任何危险的转换。

从这里: 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具有相同的绝对毫秒时间,但是具有不同的字段值集合。

您可以将“Europe / London”替换为您想要的时区(UTC)。 请参阅此适当的时区名称列表 。

  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(new Date())把你的本地日期

我用这个转换器修好了

 public class DateTimeConverter implements AttributeConverter { @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并使用您当前的时区恢复