我在postgres db
中有一个日期列,其值为2018-11-20 22:07:20
。数据类型为timestamz
。我想在Java代码中获取上述值,并将其相对于当前时间转换为秒。假设当前日期为2018-11-21 22:07:20
,则最终答案应为86400秒。有人可以帮我吗?
答案 0 :(得分:1)
Duration // Represent a span-of-time unattached to the timeline.
.between( // Calculate elapsed time between two moments.
OffsetDateTime.now( ZoneOffset.UTC ) , // Capture the current moment as seen in UTC.
myResultSet.getObject( … , OffsetDateTime.class ) // Retrieve the moment stored in your database as a `OffsetDateTime` object, *not* as a mere string.
) // Return a `Duration` object.
.toSeconds() // View that duration as a total number of whole seconds. Obviously, any fractional second is ignored.
Answer by Michael很近,但不太正确。
LocalDateTime
是错误的类,因为按照定义它不能代表一个时刻。postgres数据库中的日期列,其值为2018-11-20 22:07:20
否,那不是列的值。这是值的文字表示。有什么区别?不幸的是,许多用于访问数据的工具都可以通过应用时区调整来改变正在检索的数据的自由。
更糟糕的是,您的示例文本缺少时区或UTC偏移量的指示符。这与您的下一个陈述相矛盾。
数据类型为timestamz。
我认为您拼写错误的timestampz
(缺少p
)。即使这样,这似乎还是不正确的,因为Postgres date/time types中没有列出此类类型。某些系统使用该词作为缩写,但是为了清楚起见,我建议始终使用较长的SQL标准名称。
您可能是说Postgres和其他数据库一样,将类型TIMESTAMP WITH TIME ZONE
存储为UTC中的值。传入数据中存在的time zone或offset-from-UTC的任何指示符用于调整为UTC,然后丢弃该指示符。因此,在Postgres的 TIMESTAMP WITH TIME ZONE
列中输入和输出的值在UTC中始终是 。如上所述,请注意,某些工具会通过注入时区调整来干扰数据检索,这是一个很好的意图,但非常令人困惑。
从JDBC 4.2开始,我们可以通过setObject
和getObject
方法与数据库交换 java.time 对象。使用对象而不是仅字符串来交换日期时间值。
OffsetDateTime
从TIMESTAMP WITH TIME ZONE
类型的列中将您的值检索为OffsetDateTime
值,其偏移量设置为UTC。
OffsetDateTime odtThen = myResultSet.getObject( … , OffsetDateTime.class ) ;
为进行比较,请获取UTC中的当前时刻。使用常量ZoneOffset.UTC
指定偏移量。
OffsetDateTime odtNow = OffsetDateTime.now( ZoneOffset.UTC ) ;
要生成以标准ISO 8601格式表示该持续时间的文本,请调用OffsetDateTime::toString
。
Duration
捕获经过的时间作为Duration
对象。
Duration d = Duration.between( odtNow , odtThen ) ;
要以标准ISO 8601格式生成表示该持续时间的文本,请调用Duration::toString
。
String output = d.toString() ; // PnYnMnDTnHnMnS
要查看整个持续时间是秒的重要部分,请致电Duration::toSeconds
。
long secondsElapsed = d.toSeconds() ;
ZonedDateTime
顺便说一句,如果您希望通过特定地区(时区)的人们使用的挂钟时间的角度查看odtThen
或odtNow
值,应用ZoneId
以获得ZonedDateTime
。
以continent/region
的格式指定proper time zone name,例如America/Montreal
,Africa/Casablanca
或Pacific/Auckland
。切勿使用2-4个字母的缩写,例如EST
或IST
,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。
ZoneId z = ZoneId.of( "Pacific/Auckland" ) ;
ZonedDateTime zdt = odtThen.atZoneSameInstant( z ) ;
java.time框架已内置在Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date
,Calendar
和SimpleDateFormat
。
目前位于Joda-Time的maintenance mode项目建议迁移到java.time类。
要了解更多信息,请参见Oracle Tutorial。并在Stack Overflow中搜索许多示例和说明。规格为JSR 310。
您可以直接与数据库交换 java.time 对象。使用符合JDBC driver或更高版本的JDBC 4.2。不需要字符串,不需要java.sql.*
类。
在哪里获取java.time类?
ThreeTen-Extra项目使用其他类扩展了java.time。该项目为将来可能在java.time中添加内容提供了一个试验场。您可能会在这里找到一些有用的类,例如Interval
,YearWeek
,YearQuarter
和more。
答案 1 :(得分:0)
解析为LocalDateTime
,然后在该时间和当前时间之间获取Duration
,然后再获取convert it to seconds。
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("your pattern");
LocalDateTime dateTime = LocalDateTime.parse("2018-11-20 22:07:20", formatter);
return Duration.between(dateTime, LocalDateTime.now()).getSeconds();
您可以自己设计模式。