为什么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()会影响时区吗?
答案 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)
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
及相关类(Calendar
,SimpleDateFormat
等)的设计很差。虽然勇敢地努力解决日期时间处理这个棘手的问题,但他们没有达到目标。他们的设计选择很糟糕。你应该避免使用它们,因为它们现在被 java.time 类所取代,巨大的改进。
专门回答您的问题:toString
Date
方法在生成字符串时动态应用JVM的当前默认时区。因此,虽然Date
对象本身代表UTC中的一个时刻,但toString
会产生错误的印象,即它带有显示的时区。
更糟糕的是,是埋在Date
对象内的时区。该区域在内部使用,但与我们在此讨论无关。混乱?是的,还有另一个避免这门课的理由。
java.util.Date实例没有时区概念。
不正确。 Date
表示特定时刻,时间轴上的点,以毫秒为单位,以UTC为单位。如您所述,它被定义为自UTC 1970年第一个时刻以来的毫秒数。
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 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date
,Calendar
和& SimpleDateFormat
现在位于Joda-Time的maintenance 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的试验场。您可以在此处找到一些有用的课程,例如Interval
,YearWeek
,YearQuarter
和more。