gpt4 book ai didi

java - 使用 java 1.7 从 postgres 检索时日期格式不一致

转载 作者:行者123 更新时间:2023-11-29 13:00:23 26 4
gpt4 key购买 nike

我在使用 JDK 1.7 从 postgres 检索日期列值并导出为 CSV 时遇到了这个独特的问题以下是示例输出

ID,      Date Created,        Date Modified 
816271, 8/8/2013 14:35 2/2/2015 16:47
830322 13/08/2013 11:48 AM 2/2/2015 16:48
1128312 10/2/2015 16:53 10/2/2015 16:53
1129465 12/2/2015 16:23 12/2/2015 16:23
1130482 16/02/2015 4:28 PM 15/06/2015 7:01 AM
1019527 19/08/2014 4:40 AM 23/02/2015 12:14 PM
1134334 23/02/2015 8:38 AM 4/6/2015 5:16

问题是,我看到 AM/PM 被附加到 DAY 部分大于 12 的那些日期值。当我查看数据库时,我没有看到任何 AM/PM。在我的 DO 中,我刚刚将变量声明为 Date。

请告诉我为什么会出现这种格式不一致的情况。

谢谢

以下是我如何将日期设置到我的 DO 中。

public void setCreatedDate(Date createdDate) { 
if (createdDate == null) {
this.mCreatedDate = createdDate; return;
}
this.mCreatedDate = new Date(createdDate.getTime());
}

我根本没有使用任何格式化代码。即使有一个,我不确定为什么它没有应用于所有记录

最佳答案

您需要了解使用日期时间数据类型存储在数据库中的日期时间值没有格式。您看到的是为方便人类查看而生成的日期时间值的字符串表示形式。该字符串不是日期时间。

因此,“AM/PM”的格式问题与某些在 Postgres 之外生成该字符串的代码有关。您没有向我们展示该代码,因此我们无法直接解决问题。但是,如果您有意识地使用日期时间值/对象而不是字符串,您就可以首先避免这个问题。

在 Postgres 中存储日期时间

在 Postgres 中,您通常应该使用 TIMESTAMP WITH TIME ZONE 数据类型。这种类型实际上不保留时区。相反,它尊重时区,使用任何传递的偏移量或伴随数据输入的时区信息来调整到 UTC .然后将结果存储在数据库中。调整后,Postgres 会丢弃原来的偏移量或时区信息。

从 Postgres 检索日期时间

当检索数据(SELECT)时,您可能会得到一个日期时间值或一个字符串,这取决于客户端应用程序(pgAdmin、psql、SQuirreL SQL Client 等)或您的数据库驱动程序(JDBC 等)。如果得到一个字符串,可能代表您对某个时区进行了调整,但该字符串不是日期时间值。如果获取日期时间值,请在工作中坚持使用该值,而不是转换为字符串。在 JDBC 中,这意味着使用 java.sql.Timestamp对象,例如。

Java 日期时间框架

如果使用 Java 8 或更高版本的技术,您应该使用新的 java.time package .如果不可能,请使用 Joda-Time图书馆。尽量避免使用 java.util.Date/.Calendar 和 java.text.SimpleDateFormat,因为它们既麻烦又令人困惑。

例子

下面是从 Postgres 9.4 中提取 java.sql.Timestamp,然后使用 java.time 或 Joda-Time 处理该值的完整示例。

Joda-Time 和 java.util.Date 的数据丢失

请注意,Joda-Time(如 java.util.Date)仅限于 millisecond小数秒的精度。 Postgres 解析为 microseconds .因此,从 Postgres 转换为 Joda-Time/java.util.Date 意味着可能会丢失数据。使用 java.time,没问题,因为它解析为 nanoseconds .

chart comparing usage of milliseconds vs microseconds vs nanoseconds as discussed in previous paragraph

代码

用 Java 8 Update 51 编写,使用 postgresql-9.4-1201.jdbc41.jar司机 Postgres Mac OS X Mountain Lion 上的 9.4.x。

String message = "Example of fetching Timestamp from Postgres.";
StringBuilder sql = new StringBuilder();
sql.append( "SELECT now() " + "\n" );
sql.append( ";" );
java.sql.Timestamp ts = null;
try ( Connection conn = DatabaseHelper.instance().connectionInAutoCommitMode() ;
PreparedStatement pstmt = conn.prepareStatement( sql.toString() ); ) {
try ( ResultSet rs = pstmt.executeQuery(); ) {
// Extract data from result set
int count = 0;
while ( rs.next() ) {
count ++;
ts = rs.getTimestamp( 1 );
}
}

} catch ( SQLException ex ) {
logger.error( "SQLException during: " + message + "\n" + ex );
} catch ( Exception ex ) {
logger.error( "Exception during: " + message + "\n" + ex );

}

java.sql.时间戳

注意旧的 Java 日期时间类如何隐式应用 JVM 当前的默认时区。虽然旨在提供帮助,但它会造成无穷无尽的困惑。运行此代码时看到的时区是 America/Los_Angeles其偏移量为 −07:00

String output_SqlTimestamp = ts.toString();  // Confusingly applies your JVM’s current default time zone.

java.time

在 Java 8 及更高版本中使用 java.time。

// If you have Java 8 or later, use the built-in java.time package.

java.time.Instant instant = ts.toInstant();
java.time.ZoneId zoneId = ZoneId.of( "America/Montreal" );
java.time.ZonedDateTime zdt = java.time.ZonedDateTime.ofInstant( instant , zoneId );

String output_UTC = instant.toString();
String output_Montréal = zdt.toString();

System.out.println( "output_SqlTimestamp: " + output_SqlTimestamp );
System.out.println( "output_UTC: " + output_UTC );
System.out.println( "output_Montréal: " + output_Montréal );

乔达时间

在 Java 8 之前,使用 Joda-Time。

// Before Java 8, use Joda-Time. (Joda-Time was the inspiration for java.time.)
// IMPORTANT: Joda-Time, like java.util.Date, is limited to milliseconds for fraction of a second. So you may experience data loss from a Postgres date-time value with microseconds.

org.joda.time.DateTime dateTimeMontréal = new org.joda.time.DateTime( ts.getTime() , DateTimeZone.forID( "America/Montreal" ) ); // WARNING: Data lost with microseconds truncated to milliseconds.
org.joda.time.DateTime dateTimeUtc = dateTimeMontréal.withZone( DateTimeZone.UTC );

String output_Joda_dateTimeMontréal = dateTimeMontréal.toString();
String output_Joda_dateTimeUtc = dateTimeUtc.toString();

System.out.println( "output_Joda_dateTimeMontréal: " + output_Joda_dateTimeMontréal );
System.out.println( "output_Joda_dateTimeUtc: " + output_Joda_dateTimeUtc );

运行时。

output_SqlTimestamp: 2015-08-24 12:46:06.979144
output_UTC: 2015-08-24T18:46:06.979144Z
output_Montréal: 2015-08-24T14:46:06.979144-04:00[America/Montreal]
output_Joda_dateTimeMontréal: 2015-08-24T14:46:06.979-04:00
output_Joda_dateTimeUtc: 2015-08-24T18:46:06.979Z

关于java - 使用 java 1.7 从 postgres 检索时日期格式不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32175775/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com