简而言之
myResultSet.getObject(
… ,
Instant.class
)
.atZone( ZoneId.of( "Africa/Tunis" ) )
.toLocalDate()
.atStartOfDay( ZoneId.of( "Africa/Tunis" ) )
And…
Duration.between( zdtStartOfDay , zdt )
.toMillis()
- 无需字符串。
- 无需
java.sql.Timestamp
。
java.time
现代方法使用java.time类替换麻烦的旧遗留类,如java.sql.Timestamp
、Date
和Calendar
。
MadProgrammer的答案使用了java.time,但是使用了错误的类:LocalDateTime
类有意缺少任何时区或偏移量的概念,但我们的输入字符串确实具有这些信息。输入字符串末尾的Z
代表Zulu
,表示UTC。丢弃有价值的信息(区域/偏移信息)不是一个好习惯。
Instant
类表示时间线上的一个时刻,在UTC中具有纳秒(十进制小数点后九位)的分辨率。
Instant instant = Instant.parse( "2015-07-24T09:39:14.000Z" ) ;
智能对象,不是愚蠢的字符串
我需要从数据库中获取时间戳并仅检索时间,然后比较两个时间。
以下是字符串值
使用适当的对象与您的数据库交换数据,而不仅仅是字符串。
从JDBC 4.2开始,您可以通过getObject
和setObject
直接交换java.time对象。
Instant instant = myResultSet( … , Instant.class ) ;
你刚刚从数据库中直接获取了一个类似于SQL标准的TIMESTAMP WITH TIME ZONE
类型的列的日期时间。
为了向数据库发送数据,请使用带有占位符的PreparedStatement
。
myPreparedStatement.setObject( … , instant ) ;
通过JDBC从数据库检索到的Instant
对象默认为UTC时区。要获取当天的时间,您必须指定用户所在地区的墙钟时间(时区)。
请以continent/region
格式指定适当的时区名称,例如America/Montreal
、Africa/Casablanca
或Pacific/Auckland
。不要使用3-4个字母的伪时区,如EST
或IST
,因为它们不是真正的时区,没有标准化,甚至不唯一!
ZoneId z = ZoneId.of( "Pacific/Auckland" ) ;
将该时区应用于获取一个ZonedDateTime
对象。 Instant
和ZonedDateTime
代表相同的时刻,即时间线上的同一点。这是一个重要的概念需要理解。两个朋友在电话中交谈,一个在加拿大魁北克,另一个在法国巴黎,同时看着墙上的时钟,在同一时刻看到的却是他们所在地区使用的不同时间。
ZoneDateTime zdt = instant.atZone( z ) ;
如果你只关心时间,可以提取一个
LocalTime
对象。
LocalTime lt = zdt.toLocalTime();
生成一个标准ISO 8601格式的String
。
String output = lt.toString();
生成本地化格式的字符串。
DateTimeFormatter f = DateTimeFormatter.ofLocalizedTime( FormatStyle.FULL ).withLocale( Locale.CANADA_FRENCH ) ;
String output = lt.format( f ) ;
但是你似乎想要从一天开始以来某些东西的计数 - 你的问题不够清晰。也许你想要整秒、毫秒的计数,或者我不知道你想要什么。
我们必须获取所需/预期时区中的一天开始时间。不要假设一天始于时间00:00:00。由于夏令时(DST)等异常情况,一天可能始于另一个时间,比如01:00:00。让java.time确定一天的开始。
ZonedDateTime zdtStartOfDay = zdt.toLocalDate().atStartOfDay( z ) ;
将经过的时间计算为 Duration
。
Duration d = Duration.between( zdtStartOfDay , zdt ) ;
将整个时间段提取为完整秒数。
long secondsSinceStartOfDay = d.toSeconds() ;
将整个时间段提取为毫秒数。
long millisSinceStartOfDay = d.toMillis() ;
请注意数据丢失。java.time类的分辨率为纳秒,因此当调用to...方法时,如果存在更细粒度的值,则会忽略该值的更细部分。
关于java.time:
java.time框架内置于Java 8及更高版本中。这些类替代了一些麻烦的旧日期/时间类,如java.util.Date、Calendar和SimpleDateFormat。
Joda-Time项目现在处于维护模式,建议迁移到java.time类。
要了解更多信息,请参见Oracle教程。并在Stack Overflow上搜索许多示例和解释。规范是JSR 310。
您可以直接与数据库交换java.time对象。使用符合JDBC 4.2或更高版本的JDBC驱动程序。不需要字符串,也不需要java.sql.*类。
如何获取java.time类?
ThreeTen-Extra项目通过添加附加类扩展了java.time。该项目是java.time可能未来添加内容的试验场。您可以在这里找到一些有用的类,例如Interval
,YearWeek
,YearQuarter
和更多。