来自ZonedDateTime UTC实例的Java日期和时间戳 [英] Java Date and Timestamp from instance of ZonedDateTime UTC

查看:154
本文介绍了来自ZonedDateTime UTC实例的Java日期和时间戳的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Java应用程序,希望在该应用程序中使用UTC。当前,代码混合使用 java.util.Date java.sql.Timestamp 。为了获得UTC时间,我之前的程序员使用了以下代码:



对于日期:

  Date.from(ZonedDateTime.now(ZoneOffset.UTC))。toInstant(); 

对于时间戳:

  Timestamp.from(ZonedDateTime.now(ZoneOffset.UTC).toInstant()); 

但是我自己使用此代码运行了多个测试,并且这两行均返回当前日期/时间(以我当前的时区)。从我看过的所有内容中,似乎似乎没有显示Date / Timestamp的zoneOffset值,但是我找不到对此的具体说明。



无论如何,有没有将timeZone(UTC)保留在Date或Timestamp对象内,还是我需要做一些重构并在整个应用程序中使用实际的ZonedDateTime对象?



示例:

还会将此ZonedDateTime对象与sql的当前Timestamp对象兼容吗?  public static void main(String args [])
{
ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneOffset.UTC);
Timestamp timestamp = Timestamp.from(ZonedDateTime.now(ZoneOffset.UTC).toInstant());
Date date = Date.from(ZonedDateTime.now(ZoneOffset.UTC).toInstant());
System.out.println( ZonedDateTime: + zonedDateTime);
System.out.println( Timestamp: + timestamp);
System.out.println( Date: + date);
}

输出:

  ZonedDate时间:2017-04-06T15:46:33.099Z 
时间戳记:2017-04-06 10:46:33.109
日期:Thu Apr 06 10:46 :33 CDT 2017


解决方案

tl; dr



  Instant.now()//捕获UTC中的当前时刻,分辨率最高为纳秒。 

仅使用 java.time 类。避免在Java 8之前添加麻烦的旧旧日期时间类。



使用java.time



程序员在您使用新的现代java.time类之前,该类现在取代了臭名昭著的麻烦的旧式日期时间类,例如 Date Calendar 时间戳



即时








关于 java.time



java.time 框架内置于Java 8及更高版本中。这些类取代了麻烦的旧旧版日期时间类,例如 java.util.Date 日历 ,& SimpleDateFormat



Joda-Time 项目,现在位于维护模式中,建议迁移到 java.time 类中。



要了解更多信息,请参见 Oracle教程 。并在Stack Overflow中搜索许多示例和说明。规范为 JSR 310



您可以直接与数据库交换 java.time 对象。使用符合 JDBC驱动程序。 jeps / 170 rel = noreferrer> JDBC 4.2 或更高版本。不需要字符串,不需要 java.sql。* 类。



在哪里获取java.time类?





ThreeTen-Extra 项目使用其他类扩展了java.time。该项目为将来可能在java.time中添加内容打下了基础。您可能会在这里找到一些有用的类,例如 时间间隔 YearWeek YearQuarter 更多


I have a java application in which I would like the time in UTC. Currently, the code uses a mix of java.util.Date and java.sql.Timestamp. To get the time in UTC, the programmer before me used:

For Date:

 Date.from(ZonedDateTime.now(ZoneOffset.UTC)).toInstant();

For Timestamp:

 Timestamp.from(ZonedDateTime.now(ZoneOffset.UTC).toInstant());

However I have run multiple tests myself with this code and both of these lines return the current date/time(in my current timezone). From everything I have read it appears that Date/Timestamp does not have a zoneOffset value, but I cannot find a concrete statement of this.

Is there anyway to keep the timeZone (UTC) within the Date or Timestamp objects, or do I need to do some refactoring and use the actual ZonedDateTime object throughout my application? Also will this ZonedDateTime object be compatible with the current Timestamp object for sql?

Example:

public static void main (String args[])
{
    ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneOffset.UTC);
    Timestamp timestamp = Timestamp.from(ZonedDateTime.now(ZoneOffset.UTC).toInstant());
    Date date = Date.from(ZonedDateTime.now(ZoneOffset.UTC).toInstant());
    System.out.println("ZonedDateTime: " + zonedDateTime);
    System.out.println("Timestamp: " + timestamp);
    System.out.println("Date: " + date);
}

Output:

 ZonedDateTime: 2017-04-06T15:46:33.099Z
 Timestamp: 2017-04-06 10:46:33.109
 Date: Thu Apr 06 10:46:33 CDT 2017

解决方案

tl;dr

Instant.now()  // Capture the current moment in UTC with a resolution up to nanoseconds.

Use only java.time classes. Avoid the troublesome old legacy date-time classes added before Java 8.

Using java.time

The programmer before you was making use of the new modern java.time classes that now supplant the notoriously troublesome old legacy date-time classes such as Date, Calendar, Timestamp.

Instant

The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction). To get the current moment in UTC is utterly simple: Instant.now.

Instant instant = Instant.now();

Converting

You should stick to the java.time classes, and avoid the legacy classes. But if absolutely necessary such as interfacing with old code not yet updated for java.time, you may convert to/from java.time. Look to new methods on old classes. The legacy class java.util.Date equivalent is Instant.

java.util.Date d = java.util.Date.from( myInstant); // To legacy from modern.
Instant instant = myJavaUtilDate.toInstant();  // To modern from legacy.

JDBC

Avoid the legacy date-time classes. Use java.time classes instead.

Your JDBC 4.2 compliant driver may be able to directly address java.time types by calling PreparedStatement::setObject and ResultSet::getObject.

myPreparedStatement.setObject( … , instant ) ;

… and …

Instant instant = myResultSet.getObject( … , Instant.class ) ;

If not, fall back to using the java.sql types, but as briefly as possible. Use new conversion methods added to the old classes.

myPreparedStatement.setTimestamp( … , java.sql.Timestamp.from( instant ) ) ;

… and …

Instant instant = myResultSet.getTimestamp( … ).toInstant() ;

No need for ZonedDateTime

Notice that we had no need for your mentioned ZonedDateTime as you said you were only interested in UTC. The Instant objects are always in UTC. That means that original code you quoted:

Date.from(ZonedDateTime.now(ZoneOffset.UTC)).toInstant();

…could have simply been shortened to:

Date.from( Instant.now() ) ;

Note that java.util.Date is always in UTC as well. However, its toString unfortunately applies the JVM’ current default time zone implicitly while generating the String. This anti-feature creates no end of confusion as you can see by searching on Stack Overflow.

If you want to see your Instant object’s UTC value through the lens of a region’s wall-clock time, assign a time zone ZoneId to get a ZoneDateTime.

Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as CDT or EST or IST as they are not true time zones, not standardized, and not even unique(!).

ZoneId z = ZoneId.of( "America/Chicago" );
ZonedDateTime zdt = instant.atZone( z );



About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.

Where to obtain the java.time classes?

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

这篇关于来自ZonedDateTime UTC实例的Java日期和时间戳的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆