如何在Java中将日期转换为秒

时间:2018-11-20 16:49:30

标签: java postgresql

我在postgres db中有一个日期列,其值为2018-11-20 22:07:20。数据类型为timestamz。我想在Java代码中获取上述值,并将其相对于当前时间转换为秒。假设当前日期为2018-11-21 22:07:20,则最终答案应为86400秒。有人可以帮我吗?

2 个答案:

答案 0 :(得分:1)

tl; dr

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很近,但不太正确。

  • 它无法解决您当地时区的异常,例如Daylight Saving Time (DST)LocalDateTime是错误的类,因为按照定义它不能代表一个时刻。
  • 它也无法解决更大的问题,即笨拙的字符串被用来与数据库而不是智能对象交换日期时间值。
  

postgres数据库中的日期列,其值为2018-11-20 22:07:20

否,那不是列的值。这是值的文字表示。有什么区别?不幸的是,许多用于访问数据的工具都可以通过应用时区调整来改变正在检索的数据的自由。

更糟糕的是,您的示例文本缺少时区或UTC偏移量的指示符。这与您的下一个陈述相矛盾。

  

数据类型为timestamz。

我认为您拼写错误的timestampz(缺少p)。即使这样,这似乎还是不正确的,因为Postgres date/time types中没有列出此类类型。某些系统使用该词作为缩写,但是为了清楚起见,我建议始终使用较长的SQL标准名称。

您可能是说Postgres和其他数据库一样,将类型TIMESTAMP WITH TIME ZONE存储为UTC中的值。传入数据中存在的time zoneoffset-from-UTC的任何指示符用于调整为UTC,然后丢弃该指示符。因此,在Postgres的 TIMESTAMP WITH TIME ZONE列中输入和输出的值在UTC中始终是 。如上所述,请注意,某些工具会通过注入时区调整来干扰数据检索,这是一个很好的意图,但非常令人困惑。

智能对象,而不是哑字符串

从JDBC 4.2开始,我们可以通过setObjectgetObject方法与数据库交换 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

顺便说一句,如果您希望通过特定地区(时区)的人们使用的挂钟时间的角度查看odtThenodtNow值,应用ZoneId以获得ZonedDateTime

continent/region的格式指定proper time zone name,例如America/MontrealAfrica/CasablancaPacific/Auckland。切勿使用2-4个字母的缩写,例如ESTIST,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。

ZoneId z = ZoneId.of( "Pacific/Auckland" ) ;
ZonedDateTime zdt = odtThen.atZoneSameInstant( z ) ;

关于 java.time

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

目前位于Joda-Timemaintenance 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中添加内容提供了一个试验场。您可能会在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore

答案 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();

您可以自己设计模式。