首页 > 解决方案 > 毫秒未从 java new Date() 函数正确转换为带有时区的 postgres 时间戳

问题描述

该代码是遗留代码。

当前日期是使用新的 Date() 函数 (java.util.Date) 在 POJO 字段中设置的。它正在使用 type= Timestamp with time zone 保存到 postgres 数据库中

但有些时候,我得到的日期/时间最多保存 3 位数毫秒,有些最多保存 2 位数毫秒。

例如:

Wed Jul 01 13:06:10 IST 2020 is converted or saved in the database like "2020-07-01 13:06:10.**178**+05:30" and some time "2020-07-01 13:06:10.**18**+05:30"

有人知道毫秒精度的不准确性吗?

标签: javadatetimedatetime-formatpostgresql-9.4date

解决方案


我建议您从过时且容易出错的java.util日期时间 API 切换到丰富的现代日期时间 API 集

定义一个格式化对象:

DateTimeFormatter.ofPattern("u-M-d H:m:s.SSSXXX")

…并使用它来解析两种日期时间字符串。

import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;

public class Main {
    public static void main(final String[] args) {
        // Define the formatter
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("u-M-d H:m:s.SSSXXX");

        // Test date-time strings
        String[] strDateArr = { "2020-07-01 13:06:10.178+05:30", "2020-07-01 13:06:10.18+05:30" };

        OffsetDateTime odt;
        for (String strDate : strDateArr) {
            // Parse a date-time string from the array of test date-time strings
            odt = OffsetDateTime.parse(strDate, formatter);
            System.out.println(odt);
        }
    }
}

输出:

2020-07-01T13:06:10.178+05:30
2020-07-01T13:06:10.180+05:30

请注意,您可以OffsetDateTime直接与PreparedStatementResultSet对象一起使用,而无需将其转换为任何其他日期时间对象,例如

将 OffsetDateTime 对象设置为 PreparedStatement 对象的参数:

pst.setObject(index, odt);

从 Resultset 对象获取 OffsetDateTime 对象:

OffsetDateTime odt = rs.getObject(index, OffsetDateTime.class);

更新

使用旧版 API:

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Main {
    public static void main(final String[] args) throws ParseException {
        // Test date-time strings
        String[] strDateArr = { "2020-07-01 13:06:10.178+05:30", "2020-07-01 13:06:10.18+05:30" };

        // Define the format
        final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSXXX");

        Date date;
        for (String strDate : strDateArr) {
            // Parse a date-time string from the array of test date-time strings
            date = sdf.parse(strDate);
            System.out.println(date);
        }
    }
}

输出:

Wed Jul 01 08:36:10 BST 2020
Wed Jul 01 08:36:10 BST 2020

将 Java SE 8 日期时间类向后移植到 Java SE 6 和 7:

检查ThreeTen-Backport以及如何使用 ThreeTenABP


推荐阅读