Java SimpleDateFormat返回时间为12小时前的5.30到6.30之间
我们正在使用Java SimpleDateFormat返回时间为12小时前的5.30到6.30之间,java,postgresql,Java,Postgresql,我们正在使用SimpleDateFormat将日期时间转换为以毫秒为单位的时间 下面是我们用于转换的代码 下面是我从数据库中获取的日期时间格式 "2019-04-04 12:24:53.754787+00" 代码: 它以毫秒为单位返回正确的时间戳。除了下午5点30分至6点30分,它返回12小时延迟为什么返回错误的时间戳?或者用其他方法进行转换?正如Jon Skeet提到的,简单的日期格式也有点不合适。我已将-M-更改为-MM-,hh更改为hh。有关SimpleDataFormat的更多信息,
SimpleDateFormat
将日期时间转换为以毫秒为单位的时间
下面是我们用于转换的代码
下面是我从数据库中获取的日期时间格式
"2019-04-04 12:24:53.754787+00"
代码:
它以毫秒为单位返回正确的时间戳。除了下午5点30分至6点30分,它返回12小时延迟为什么返回错误的时间戳?或者用其他方法进行转换?正如Jon Skeet提到的,简单的日期格式也有点不合适。我已将
-M-
更改为-MM-
,hh
更改为hh
。有关SimpleDataFormat的更多信息,请访问。而且,时区可能会影响它
您还可以使用日历返回长时间
例如:
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();
}
首先,不要将日期时间存储为PostgreSQL中的字符串,也不要从数据库中检索所显示的字符串。存储适当的日期/时间类型;在您的情况下,可能是带有时区的时间戳。而不是检索字符串,而是获取相应的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存储的是微秒精度,而millisconds自大纪元以来显然不存储,因此我们丢失了原始值的最后三位小数
我正在使用并推荐java.time,这是一种现代的java日期和时间API。您尝试使用的datetime类--SimpleDateFormat
和Date
——早已过时,而且设计得很糟糕。所以要避免这些
你的代码出了什么问题?
- 其他人已经指出,要解析字符串,您需要在从00到23的一天中的一小时内使用大写字母
。小写的HH
表示从01到12的上午或下午的小时。因为12 AM表示00,所以解析12小时会给出您观察到的错误结果,而其他小时值会起作用hh
- 另一方面,在本例中,单个
并不重要,它在解析时与M
的作用相同(对于格式化,如果始终需要两个数字,则需要MM
,如您的示例字符串)MM
- 您既没有解析秒的分数,也没有解析
的UTC偏移量。尽管如此,如果您得到了一个大致正确的结果,那么您是幸运的,不应该指望其他计算机或具有其他默认设置的JVM会出现这种情况+00
- PostgreSQL
- 来自PostgreSQL JDBC驱动程序文档
- 解释如何使用java.time
- 相关问题:
hh
,但尚未指定am/pm说明符。您几乎肯定希望使用HH
。将M
与dd
一起使用也很奇怪。使用yyyy-MM-dd HH:MM:ss
更为常见。我怀疑Santosh的说法是正确的,因为它具体在5:30到6:30之间。(您当前正在使用默认时区进行解析,这几乎肯定是不合适的。)但格式是另一个问题。我强烈建议您无论如何都要使用java.time
。@JonSkeet虽然总体上更好,但使用java.time对这个特定问题没有影响。@kumesana:是的,它会影响-因为您可能会解析为Instant
,它隐式使用UTC,这可能是正确的做法。为什么要将时间戳作为字符串检索?您应该使用ResultSet.getObject(…,LocalDateTime.class)
从数据库中读取它。或者至少ResultSet.getTimestamp()
日历的使用在这里是不相关的-主要的问题是格式,你没有提到它就纠正了它。@Jon Skeet你完全正确,它是不相关的,你是对的,我甚至没有提到格式。。谢谢
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);