java和postgresql中从日期到长的转换是不一样的

Posted

技术标签:

【中文标题】java和postgresql中从日期到长的转换是不一样的【英文标题】:Convert from date to long are not the same in java and postgresql 【发布时间】:2017-11-30 13:26:30 【问题描述】:

我在 postgresql 中有一个表,其中有一列 created_date 日期类型。我创建了以毫秒为单位返回日期而不是日期的视图:

select date_part('epoch'::text, timezone('UTC'::text, created_date::timestamp with time zone)), created_date
from table

这将返回以下结果:

date_part    created_date

1497384000   2017-06-14
1497384000   2017-06-14
1498420800   2017-06-26
1498420800   2017-06-26

在 Java 中,我做了以下操作:

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
LocalDate date = LocalDate.parse(view.getStartDate(), formatter);
long longDate = date.atStartOfDay(ZoneId.of("UTC")).toEpochSecond(); 

longDate 结果是1497398400 对应2017-06-141498435200 对应2017-06-26

为什么postgresql和Java从日期到长的转换不一样?

PS:数据库的时区是Asia/Baku

【问题讨论】:

24 小时? @pnuts 区域偏移通常在距 UTC 的 +/- 14 小时内,因此听起来不太可能。巴库全年为 UTC+4:00。 虽然您认为两个区域偏移可能相隔 24 小时是正确的,但使用中的区域偏移不存在 与 UTC 相差 24 小时。这是因为 UTC 几乎位于所有区域偏移的中间。 @pnuts 没错,@pnuts 【参考方案1】:

你打电话给atStartOfDay(ZoneId)。由于ZoneId 是UTC,它将小时设置为午夜,区域设置为UTC。因此,您的日期变为2017-06-14T00:00:00Z,等效的纪元秒值为1497398400

如果检查数据库返回的值(1497384000):

System.out.println(Instant.ofEpochSecond(1497384000L));

你得到:

2017-06-13T20:00:00Z

如果您将其转换为您的系统使用的时区 (Asia/Baku):

System.out.println(Instant.ofEpochSecond(1497384000L).atZone(ZoneId.of("Asia/Baku")));

你得到:

2017-06-14T00:00+04:00[亚洲/巴库]

因此,1497384000 的值相当于 UTC 中的 2017-06-13T20:00:00Z。数据库返回 2017-06-14,因为它正在将此 UTC 日期/时间转换为系统的时区 (Asia/Baku)。

如果您想获得相同的结果,则必须使用数据库使用的相同时区:

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
LocalDate date = LocalDate.parse("2017-06-14", formatter);
// using Asia/Baku timezone instead of UTC
long longDate = date.atStartOfDay(ZoneId.of("Asia/Baku")).toEpochSecond();
System.out.println(longDate);

输出将是:

1497384000

【讨论】:

数据库时区为“亚洲/巴库”

以上是关于java和postgresql中从日期到长的转换是不一样的的主要内容,如果未能解决你的问题,请参考以下文章

在 SQL 中从 POSTGRE/SQL 数据库转换 UTC 时间字段

Java中从字符串到sql日期的日期转换给出不同的输出? [复制]

Java中从LocalDateTime到joda DateTime的不正确日期转换

BigQuery 使用从宽到长的结构重塑表

使用 INNER JOIN LATERAL 和 postgresql 将宽表转换为长表

在javascript中从纪元日期转换[重复]