SimpleDateFormat返回12小时前的5.30到6.30之间的时间

时间:2019-04-04 15:35:28

标签: java postgresql

我们正在使用SimpleDateFormat将日期时间转换为以毫秒为单位的时间 下面是我们用于转换的代码

以下是我从数据库中获取的日期时间格式

"2019-04-04 12:24:53.754787+00" 

代码:

  SimpleDateFormat sdf = new SimpleDateFormat("yyyy-M-dd 
  hh:mm:ss");
    Date date = null;
    try {
        date = sdf.parse(dateTime);
    } catch (java.text.ParseException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    long timeInMilis = date.getTime();
    return timeInMilis;

它返回正确的时间戳(以毫秒为单位)。除了5.30 pm到6.30 pm之外,它还会返回12个小时的延迟,为什么它返回错误的时间戳?还是他们以其他任何方式进行转换?

2 个答案:

答案 0 :(得分:3)

首先,不要将您的日期时间存储为PostgreSQL中的字符串,也不要从数据库中检索到您要显示的字符串。存储正确的日期/时间类型;在您的情况下,可能是timestamp with time zone。而不是检索字符串,而是获取相应的Java datetime类型。例如:

    PreparedStatement select = yourDatabaseConnection
            .prepareStatement("select ts from your_table where id = 4;");
    ResultSet rs = select.executeQuery();
    if (rs.next()) {
        OffsetDateTime dateTime = rs.getObject("ts", OffsetDateTime.class);
        long milliseconds = dateTime.toInstant().toEpochMilli();
        // Do something with milliseconds
    }

(由于尚未安装PostgreSQL,因此我没有测试过此代码段。)

如果出于某种原因您无法避免获取该字符串:

    DateTimeFormatter formatter
            = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss.SSSSSSx");
    String stringFromDatabase = "2019-04-04 12:24:53.754787+00";
    OffsetDateTime dateTime
            = OffsetDateTime.parse(stringFromDatabase, formatter);
    long milliseconds = dateTime.toInstant().toEpochMilli();
    System.out.println(milliseconds);

我尝试运行的这段代码。输出为:

  

1554380693754

由于PostgreSQL自从epoch以来不存储微秒精度和千分之一,所以我们丢失了原始值的后三位小数。

我正在使用并推荐使用Java.time(现代Java日期和时间API)。您尝试使用的日期时间类-SimpleDateFormatDate-早已过时,并且设计总是很差。所以避免那些。

您的代码出了什么问题?

  • 其他人已经指出,要解析您的字符串,您需要在00到23的一天中的小时内使用大写字母HH。小写的hh在01到12的AM或PM中需要使用小时。 AM表示00,将小时数解析为12会给出您观察到的错误结果,而其他小时数则起作用。
  • 另一方面,单个M在这种情况下无关紧要,它的解析方式与MM相同(对于格式化,如果需要两个MM总是与您的示例字符串中的数字相同。)
  • 您既没有解析秒的分数,也没有解析+00的UTC偏移量。尽管如此,如果您得到的结果大致正确,则说明您很幸运,因此不要指望具有其他默认设置的其他计算机或JVM出现这种情况。

链接

答案 1 :(得分:0)

正如乔恩·斯基特(Jon Skeet)所述,简单的日期格式也有些偏离。我已将-M-更改为-MM-,并将hh更改为HH。可以在https://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html上找到有关SimpleDateFormat的更多信息。另外,TimeZone可能会影响它。

您还可以使用日历返回较长的时间。

示例:

    String date = "2019-04-04 12:24:53.754787+00";

    private long getTime(String _date) {

        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Calendar cal = Calendar.getInstance();
        cal.setTimeZone(TimeZone.getTimeZone("Europe/Vienna"));
        try {
            cal.setTime(format.parse(_date));
        } catch (ParseException e) {
            e.printStackTrace();
        }

        // First .getTime() returns Date, second returns long in millis.
        return cal.getTime().getTime(); 
    }