了解Java util Date

时间:2017-03-22 09:39:04

标签: java date java.util.date

为什么java.util.Date对象显示日期&关于时区的时间实际上,java.util.Date表示时间线上的瞬间,而不是" date"? 存储在对象中的实际数据是自1970-01-01T00:00Z(GMT / UTC 1970年初午夜)以来的长时间毫秒数。

同样在docs中,java.util.Date实例没有时区概念。

如果是这样的话,为什么这个片段打印日期指定了时区。

public static void main(String[] args) {
        Date date = new Date();
        System.out.println(date);
    } 

输出:2017年3月22日星期三14:58:56 IST 2017

为什么在输出中显示特定的时区?我理解SOP在内部实现了toString()。 toString()会影响时区吗?

3 个答案:

答案 0 :(得分:1)

只需按照javadoc进行操作即可:

  

public String toString()

     

将此Date对象转换为以下形式的字符串:

     

dow mon dd hh:mm:ss zzz yyyy

     

zzz是时区(可能反映夏令时)。

当你深入研究源代码时,这个toString()实现将在某个时候使用TimeZone.getDefault() (或者确切地说:getDefaultRef())。换句话说:默认实现提取"默认" JVM的时区。

答案 1 :(得分:0)

它确实有时区概念,但它始终是UTC。当它打印日期时,将它转换为您的计算机的时区是没有问题的。

答案 2 :(得分:0)

TL;博士

UTC当前时刻。

Instant.now()    // Capture current moment in UTC.
    .toString()  // Generate String in standard ISO 8601 format.
  

2018-01-23T01:23:45.677340Z

印度时区的当前时刻。

ZonedDateTime.now( 
    ZoneId.of( "Asia/Kolkata" ) 
).toString()    // Generate string in format wisely extended from ISO 8601 standard, adding the time zone name in square brackets.
  

2018-01-23T06:53:45.677340 + 05:30 [亚/加尔各答]

避免遗留日期时间类

  

为什么java.util.Date对象显示日期&关于时区的时间实际上,java.util.Date表示时间线上的瞬间,而不是" date"?

因为java.util.Date及相关类(CalendarSimpleDateFormat等)的设计很差。虽然勇敢地努力解决日期时间处理这个棘手的问题,但他们没有达到目标。他们的设计选择很糟糕。你应该避免使用它们,因为它们现在被 java.time 类所取代,巨大的改进。

专门回答您的问题:toString Date方法在生成字符串时动态应用JVM的当前默认时区。因此,虽然Date对象本身代表UTC中的一个时刻,但toString会产生错误的印象,即它带有显示的时区。

更糟糕的是,埋在Date对象内的时区。该区域在内部使用,但与我们在此讨论无关。混乱?是的,还有另一个避免这门课的理由。

  

java.util.Date实例没有时区概念。

不正确。 Date表示特定时刻,时间轴上的点,以毫秒为单位,以UTC为单位。如您所述,它被定义为自UTC 1970年第一个时刻以来的毫秒数。

java.time

java.time 类清楚地分离了UTC,分区和未分区值的概念。

java.time.Instant类代表UTC中时间轴上的一个时刻,分辨率为nanoseconds(小数部分最多九(9)位)。此课程取代java.util.Date

Instant instant = Instant.now() ;  // Capture current moment in UTC.

将时区(ZoneId对象)应用于Instant,您将获得ZonedDateTime个对象。该课程取代java.util.Calendar课程。

ZoneId z = ZoneId.of( "Asia/Kolkata" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;  // Same simultaneous moment as `instant`, but different wall-clock time.

如果某个值只有UTC的偏移而不是全时区,请使用OffsetDateTime类。

仅限日期,没有时间和没有时区,请使用LocalDate课程。该类替换java.sql.Date类。同上LocalTime替换java.sql.Time

LocalDate xmasDate2018 = LocalDate.of( 2018 , Month.DECEMBER , 25 ) ;

如果区域或偏移量未知或不确定,例如"圣诞节从2018年12月25日午夜时分开始",请使用LocalDateTime类。此类表示实际时刻,即时间轴上的特定点。这个类缺乏任何时区或偏移的概念。所以它只能代表大约26-27小时的潜在时刻。

LocalDateTime xmasEverywhere2018 = LocalDateTime.of( xmasDate2018 , LocalTime.MIN ) ;

或者...

LocalDateTime xmasEverywhere2018 = LocalDateTime.of( 2018 , Month.DECEMBER , 25 , 0 , 0 , 0 , 0 ) ;

关于 java.time

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

现在位于Joda-Timemaintenance mode项目建议迁移到java.time类。

要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310

如果JDBC driver符合JDBC 4.2或更高版本,您可以直接与数据库交换 java.time 对象。不需要字符串或java.sql。* classes。

从哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如IntervalYearWeekYearQuartermore