JDBC 时间戳和时间戳日期 GMT 问题

发布于 2024-08-06 15:59:35 字数 499 浏览 9 评论 0原文

我有一个 JDBC 日期列,如果 ai 使用 getDate 则只能获取“日期”部分 2009 年 10 月 2 日,但如果我使用 getTimestamp,我会得到完整的“”日期'2009 年 10 月 2 日 13:56:78:890。这正是我想要的。

然而, getTimestamp 返回的“日期”“忽略”GMT 值,假设日期; 2009 年 10 月 2 日 13:56:78:890,我最终得到 2009 年 10 月 2 日 15:56:78:890

我的日期已保存为 +2GMT 日期数据库,但应用程序服务器位于 GMT,即落后 2 小时

如何仍能按原样获取我的日期,2009 年 10 月 2 日 13:56:78:890

编辑

我在客户端得到日期 +2,即格林威治标准时间 +2

I have a JDBC Date column, which if a i use getDate is get the 'date' part only 02 Oct 2009 but if i use getTimestamp i get the full 'date' 02 Oct 2009 13:56:78:890. This is excatly what i want.

However the 'date' returned by getTimestamp 'ignores' the GMT values, suppose date; 02 Oct 2009 13:56:78:890, i end up getting 02 Oct 2009 15:56:78:890

My date was saved as a +2GMT date on the database but the application server is on GMT i.e 2hrs behind

How can still get my date as is, 02 Oct 2009 13:56:78:890

Edit

I get the date +2 on the client side that is on GMT +2

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

爱格式化 2024-08-13 15:59:35

这就是 MySQL 中时间戳和其他时间类型之间的区别。时间戳以 UTC 格式保存为 Unix time_t,但其他类型实际上存储日期/时间,而没有区域信息。

当您调用 getTimestamp() 时,如果类型是时间戳,MySQL JDBC 驱动程序会将时间从 GMT 转换为默认时区。它不会对其他类型执行此类转换。

您可以更改列类型或自行进行转换。我推荐前一种方法。

That's the difference between Timestamp and other temporal types in MySQL. Timestamp is saved as Unix time_t in UTC but other types store date/time literally without zone information.

When you call getTimestamp(), MySQL JDBC driver converts the time from GMT into default timezone if the type is timestamp. It performs no such conversion for other types.

You can either change the column type or do the conversion yourself. I recommend former approach.

季末如歌 2024-08-13 15:59:35

您应该知道 java.util.Date (以及 java.sql.Datejava.sql.Timestamp,它们是java.util.Date) 对时区一无所知,或者更确切地说,它们始终采用 UTC。

java.util.Date 及其子类只不过是“自 01-01-1970, 12:00 AM UTC 以来的毫秒数”值的容器。

要显示特定时区的日期,请使用 java.text.DateFormat 对象将其转换为字符串。通过调用 setTimeZone() 方法设置该对象的时区。例如:

Date date = ...;  // wherever you get this from

DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

// Make the date format show the date in CET (central European time)
df.setTimeZone(TimeZone.getTimeZone("CET"));

String text = df.format(date);

You should be aware that java.util.Date (and also java.sql.Date and java.sql.Timestamp, which are subclasses of java.util.Date) don't know anything about timezones, or rather, they are always in UTC.

java.util.Date and its subclasses are nothing more than a container for a "number of milliseconds since 01-01-1970, 12:00 AM UTC" value.

To display a date in a specific timezone, convert it to a string by using a java.text.DateFormat object. Set the timezone on that object by calling the setTimeZone() method. For example:

Date date = ...;  // wherever you get this from

DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

// Make the date format show the date in CET (central European time)
df.setTimeZone(TimeZone.getTimeZone("CET"));

String text = df.format(date);
蓝海似她心 2024-08-13 15:59:35

前几天我遇到了类似的问题,时间部分从某些日期被截断。

我们将其范围缩小到 Oracle 驱动程序版本的差异。

在 Oracle 的 FAQ 上有一个关于此的部分:


select sysdate from dual; ...while(rs.next())

在 9201 之前,这将返回:
sysdate 的 getObject :java.sql.Timestamp <<<<<
系统日期的 getDate :java.sql.Date
getTimetamp for sysdate : java.sql.Timestamp

从 9201 开始,将返回以下

getObject for sysdate : java.sql.Date <<<<<<
getDate for sysdate :java.sql.Date>>没有变化
getTimetamp for sysdate :java.sql.Timestamp>>没有变化

注意:java.sql.Date 没有时间部分,而 java.sql.Timestamp 有。

由于数据类型映射中的此更改,当 JDBC 驱动程序从 8i/9iR1 升级到 920x JBDC 驱动程序时,某些应用程序将失败和/或生成不正确的结果。
为了保持兼容性并保持应用程序在升级后正常工作,提供了兼容性标志。开发人员现在有一些选择:

  1. 使用 oracle.jdbc.V8Compatible 标志。

JDBC 驱动程序默认不检测数据库版本。要更改处理 TIMESTAMP 数据类型的兼容性标志,可以将连接属性

“oracle.jdbc.V8Compatible”

设置为“true”,并且驱动程序的行为与在 8i、901x、9 200 中的行为相同(相对于 TIMESTAMP)。

默认情况下,该标志设置为“false”。在 OracleConnection 构造函数中,驱动程序获取服务器版本并适当设置兼容性标志。

java.util.Properties prop=newjava.util.Properties(); 
prop.put("oracle.jdbc.V8Compatible","true"); 
prop.put("user","scott"); 
prop.put("password","tiger");
String url="jdbc:oracle:thin:@host:port:sid"; 
Connection conn = DriverManager.getConnection(url,prop);

对于 JDBC 10.1.0.x,可以使用以下系统属性代替连接属性: java -Doracle.jdbc.V8Compatible=true.....注意:此标志是仅客户端标志,用于管理时间戳和日期映射。它不会影响任何数据库功能。

'2.相应地处理 Date 和 TimeStamp 列数据类型时,请使用 set/getDate 和 set/getTimestamp。

9i 服务器支持 Date 和 Timestamp 列类型,DATE 映射到 java.sql.Date,TIMESTAMP 映射到 java.sql.Timestamp。


因此,对于我的情况,我有这样的代码:

import java.util.Date; 
Date d = rs.getDate(1);

在 9i 中,我得到了一个 java.sql.Timestamp (它是 java.util.Date 的子类),所以一切都很精彩,我有自己的时间和分钟。

但在 10g 中,相同的代码现在得到了 java.sql.Date(也是 java.util.Date 的子类,因此它仍然可以编译),但是 HH:MM 被截断了!

第二个解决方案对我来说非常简单 - 只需将 getDate 替换为 getTimestamp 就可以了。我想这是一个坏习惯。

I ran into a similar problem the other day where the time component was being truncated from some dates.

We narrowed it down to a difference in Oracle Driver versions.

On Oracle's FAQ there is a section about this:


select sysdate from dual; ...while(rs.next())

Prior to 9201, this will return:
getObject for sysdate : java.sql.Timestamp <<<<
getDate for sysdate : java.sql.Date
getTimetamp for sysdate : java.sql.Timestamp

As of 9201 onward the following will be returned

getObject for sysdate : java.sql.Date <<<<<
getDate for sysdate :java.sql.Date >> no change
getTimetamp for sysdate :java.sql.Timestamp >> no change

Note: java.sql.Date has no time portion whereas java.sql.Timestamp does.

With this change in Datatype mapping, some application will fail and/or generate incorrect results when JDBC driver is upgraded from 8i/ 9iR1 to 920x JBDC driver.
To maintain compatibility and keep applications working after upgrade, a compatibility flag was Provided. Developers now have some options:

  1. Use oracle.jdbc.V8Compatible flag.

JDBC Driver does not detect database version by default. To change the compatibility flag for handling TIMESTAMP datatypes, connection property

'oracle.jdbc.V8Compatible'

can be set to 'true' and the driver behaves as it behaved in 8i, 901x, 9 200 (with respect to TIMESTAMPs).

By default the flag is set to 'false'. In OracleConnection constructor the driver obtains the server version and set the compatibility flag appropriately.

java.util.Properties prop=newjava.util.Properties(); 
prop.put("oracle.jdbc.V8Compatible","true"); 
prop.put("user","scott"); 
prop.put("password","tiger");
String url="jdbc:oracle:thin:@host:port:sid"; 
Connection conn = DriverManager.getConnection(url,prop);

With JDBC 10.1.0.x, instead of the connection property, the following system property can be used: java -Doracle.jdbc.V8Compatible=true.....Note: This flag is a client only flag that governs the Timestamp and Date mapping. It does not affect any Database feature.

'2. Use set/getDate and set/getTimestamp when dealing with Date and TimeStamp column data type accordingly.

9i server supports both Date and Timestamp column types DATE is mapped to java.sql.Date and TIMESTAMP is mapped to java.sql.Timestamp.


So for my situation, I had code like this:

import java.util.Date; 
Date d = rs.getDate(1);

With 9i I was getting a java.sql.Timestamp (which is a subclass of java.util.Date) so everything was groovy and I had my hours and minutes.

But with 10g, the same code now gets a java.sql.Date (also a subclass of java.util.Date so it still compiles) but the HH:MM is TRUNCATED!!.

The 2nd solution was pretty easy for me - just replace the getDate with getTimestamp and you should be OK. I guess that was a bad habit.

寒江雪… 2024-08-13 15:59:35

从这篇帖子我得出的结论是,JDBC确实检索了时间戳的时区(我不认为 MS SQL 也支持这一点,大多数 Google 结果都指向 Oracle)

当调用 JDBC getTimeStamp 方法时,它仅获取'毫秒'< /em> 部分并使用服务器时区(即 GMT)创建一个 Date 对象。

当这个 Date 对象呈现给我的客户(格林尼治标准时间 +2)时,它会增加 2 小时,这是导致额外小时数的标准偏移量。

我通过删除检索日期的时间偏移(即转换为真正的 GMT 日期)来纠正此问题。

From this post i have come to the conclusion that JDBC does retrieve the timezone for the Timestamp (I don't think MS SQL support this as well, most Google results point to Oracle)

When the JDBC getTimeStamp method is called it only gets the 'milliseconds' portion and create a Date object with the server TimeZone, which is GMT.

When this Date object is presented to my client which is +2 GMT, it adds 2 hours which is the standard offset which leads to the extra hours.

I have corrected this by removing the time offset from the date i retrieve i.e. convert to the true GMT Date.

秋叶绚丽 2024-08-13 15:59:35
private Date convertDate(Date date1) throws ParseException {
        SimpleDateFormat sdfFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String dateStr = sdfFormatter.format(date1);
        SimpleDateFormat sdfParser = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        sdfParser.setTimeZone(TimeZone.getTimeZone("GMT"));
        return sdfParser.parse(dateStr);
    }
private Date convertDate(Date date1) throws ParseException {
        SimpleDateFormat sdfFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String dateStr = sdfFormatter.format(date1);
        SimpleDateFormat sdfParser = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        sdfParser.setTimeZone(TimeZone.getTimeZone("GMT"));
        return sdfParser.parse(dateStr);
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文