我在理解java.sql.timestamp
时遇到问题。
如果我运行不赞成使用的Java构造函数:
java.sql.Timestamp(106,2,26,1,0,0,0)
java.sql.Timestamp(106,2,26,2,0,0,0)
java.sql.Timestamp(106,2,26,3,0,0,0) //<-- Separated by one hour
我得到:
2006-03-26 01:00:00.0
2006-03-26 03:00:00.0
2006-03-26 03:00:00.0 //<--These last two are the same
大约在这些时间发生夏令时(至少在我的国家/地区)。但是时间之前和之后的日期不会移动。为什么两个小时分开返回同一时间?
我想像输入一样获得时间戳,我该如何强制呢?
请勿使用此不推荐使用的构造函数,因为它使用默认时区,因此不推荐使用此构造函数。
使用具有适当时区(CET)的日历(或DateFormat),设置日历的字段(或解析包含您要插入的日期的字符串),从日历/日期获取毫秒,然后构造时间戳(以毫秒为单位)。
使用System.currentTimeMillis();
为您提供格林威治标准时间,不受夏令时,savings秒和其他意外调整日期的影响。
long now = System.currentTimeMillis();
或手动指定时区:
long ms = Calendar.getInstance(TimeZone.getTimeZone("GMT")).getTimeInMillis();
夏时制(DST)转换意味着2 AM小时不存在] >>。因此,您输入的内容无效。
ZonedDateTime
类尝试通过调整您的时间输入来帮助您,该时间跳到凌晨3点,就像凌晨02:00时时钟比早晨跳一个小时。
ZonedDateTime .of( 2006 , 3 , 26 , 2 , 0 , 0 , 0 , ZoneId.of( "Africa/Tunis" ) ) .toString()
2006-03-26T03:00 + 02:00 [非洲/突尼斯]
java.sql.Timestamp
是terrible类,及其同级类,例如java.util.Date
和Calendar
/ GregorianCalendar
。在其许多设计问题中,是时区的混乱处理。
相反,仅使用现代的[[java.time
类。java.timeInstant
—时刻在UTC中。OffsetDateTime
—距UTC偏移(时分分钟数),但时区未知的时刻]>ZonedDateTime
—具有指定时区的时刻。ZoneId
Continent/Region
,例如America/Montreal
,Africa/Casablanca
或Pacific/Auckland
。切勿使用2-4个字母的缩写,例如EST
或IST
,因为它们是not
真实时区,不是标准化的,甚至不是唯一(!)。ZoneId z = ZoneId.of( "America/Montreal" ) ;
如果要使用JVM的当前默认时区,请提出要求并作为参数传递。如果省略,代码将变得难以理解,因为我们不确定您是否打算使用默认值,或者您是否像许多程序员一样不知道该问题。
ZoneId z = ZoneId.systemDefault() ; // Get JVM’s current default time zone.
ZonedDateTime
指定在特定区域(时区)的人们使用的挂钟时间中看到的时间和日期。
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt_1 = ZonedDateTime.of( 2006, 3 , 26 , 1 , 0 , 0 , 0 , z ) ;
ZonedDateTime zdt_2 = ZonedDateTime.of( 2006, 3 , 26 , 2 , 0 , 0 , 0 , z ) ;
ZonedDateTime zdt_3 = ZonedDateTime.of( 2006, 3 , 26 , 3 , 0 , 0 , 0 , z ) ;
System.out.println("zdt_1.toString(): " + zdt_1);
System.out.println("zdt_2.toString(): " + zdt_2);
System.out.println("zdt_3.toString(): " + zdt_3);
zdt_1.toString():2006-03-26T01:00 + 01:00 [非洲/突尼斯]zdt_2.toString():2006-03-26T03:00 + 02:00 [非洲/突尼斯]
zdt_3.toString():2006-03-26T03:00 + 02:00 [非洲/突尼斯]
夏令时(DST)
不存在凌晨2点
从来没有凌晨2点。
那天是只有23小时长,而不是通常的24小时长。因此,我们上面的代码要求输入无效的日期时间。ZonedDateTime
类而不是抛出Exception
,而是尝试通过调整为有效的时间来帮助我们。 JavaDoc for ZonedDateTime.of
的拼写是:从年,月,日,小时,分钟,秒,纳秒和时区中获取ZonedDateTime的实例。
这将创建一个与七个指定字段的本地日期时间尽可能紧密匹配的分区日期时间。夏时制等时区规则意味着,并非每个本地日期时间都对指定时区有效,因此可以调整本地日期时间。
本地日期时间在时间轴上解析为单个时刻。这是通过根据区域ID规则定义的本地日期时间找到UTC /格林威治标准有效偏移量来实现的。
在大多数情况下,本地日期时间只有一个有效的偏移量。在重叠的情况下,当时钟调回时,有两个有效的偏移量。此方法使用通常对应于“夏季”的更早偏移量。
在间隙的情况下,当时钟向前跳时,没有有效的偏移量。取而代之的是,将本地日期时间调整为晚一些间隔时间。对于典型的一小时夏令时更改,本地日期时间将在一小时后移入通常对应于“夏季”的偏移量中。
所以行为是功能,而不是错误。
ZonedDateTime.of
java.util.Date
和java.util.Date
。Calendar
项目现在位于Calendar
中,建议迁移到SimpleDateFormat
类。
要了解更多信息,请参见SimpleDateFormat
。并在Stack Overflow中搜索许多示例和说明。规格为Joda-Time。
您可以直接与数据库交换
java.time
对象。使用兼容maintenance mode或更高版本的java.time。不需要字符串,不需要Oracle Tutorial类。从哪里获取java.time类?java.sql.*
和更高版本-具有捆绑实施的标准Java API的一部分。