Use timestamp with time zone
in UTC in your database
For a point in time in your database use UTC, universal time. And to make sure that your database knows that it is in UTC, use timestamp with time zone
data type.
你可能认为,在你的地方时间区美国/芝加哥,储存时间更简单,更适合你的目的。 再次思考。 虽然你的意图目前是为这个时区设计的,但谁能保证将来某个时候美国其他地方的用户不会使用它? 您的编码未能在其他一些方案中重新使用? 如果学校项目要在考试后退学,学校项目就是一个很好的培训最佳做法的地方。 这里的最佳做法是储存UTC时间。
如果进一步使用<代码>无时区/代码>或<代码> > 日代码>,数据库中可能存在一个小的问题,即美国/芝加哥时区的时间有时不明确。 每年11月初,午餐时间结束, clo折又一小时。 例如,去年11月5日,2个大坝被退回到1个,尽管早一个小时已经达到1个。 因此,当你在夜间从数据库中抽取1至2天的时间时,你无法知道夏季时间或标准时间是否打算。 同样,这种时代必定相互混淆。 UTC不使用夏天时间,因此, has子没有处理这个问题。
不同的房舍管理处对<代码>与时区代码>有不同的概念。 页: 1 另一些公司在UTC储存时间,必要时从一些当地时间区转而储存和回收,实际上只给我们“UTC时区”的罚款。 我建议,你总是把0(零)冲销。 然而,有几个人允许你储存一个时间区,例如<代码>America/Chicago。 此处使用<代码>Etc/UTC。 在任何情况下,均按您的目的处以罚款。
java.time
我的理解是,你要求在美国/芝加哥时区储存时间。 因此,将<代码>OffsetDatetime与正确的UTC(6或5小时)相加的“UTC”号编码储存在“DB2”“带时间区代码”栏。 如无时区(或<代码>> 其他房舍管理处的日间条码>,则由其他单位决定,储存<条码>当地日条码>。 首先,请从<代码>XGregorianCalendar上转换。 权利:
/**
* For this code example I am assuming that a date without time is stored as the start of day
* and a date with time requires a UTC offset.
* In both cases I am converting to America/Chicago time zone.
*/
public static OffsetDateTime convertXmlgcToOdt(XMLGregorianCalendar value) {
if (value.getHour() == DatatypeConstants.FIELD_UNDEFINED
&& value.getMinute() == DatatypeConstants.FIELD_UNDEFINED
&& value.getSecond() == DatatypeConstants.FIELD_UNDEFINED
&& value.getFractionalSecond() == null) { // Date only
return value.toGregorianCalendar()
.toZonedDateTime()
.toLocalDate()
.atStartOfDay(ZONE_ID)
.toOffsetDateTime();
} else { // date and time
if (value.getTimezone() == DatatypeConstants.FIELD_UNDEFINED) {
throw new IllegalArgumentException("value must have UTC offset ("timezone")");
}
return value.toGregorianCalendar()
.toZonedDateTime()
.withZoneSameInstant(ZONE_ID)
.toOffsetDateTime();
}
}
洞穴:即使“XMLGregorianCalendar和OffsetDatetime
都精准,但我的转换具有微秒。 如果你需要保持XML的精度,我建议:
OffsetDateTime converted = OffsetDateTime.parse(value.toString());
return converted.atZoneSameInstant(ZONE_ID)
.toOffsetDateTime();
Let’s try the conversion method out:
XMLGregorianCalendar xmlDate = DatatypeFactory.newInstance()
.newXMLGregorianCalendar("2024-02-09T01:57:33.240-06:00");
System.out.println(convertXmlgcToOdt(xmlDate));
xmlDate = DatatypeFactory.newInstance()
.newXMLGregorianCalendar("2024-02-09");
System.out.println(convertXmlgcToOdt(xmlDate));
Output:
2024-02-09T01:57:33.240-06:00
2024-02-09T00:00-06:00
如果需要改成<条码>当地日条码>,则以<条码>至OffsetDetetime(<>>/条码>和<条码>取代每一条线路;条码>。
储存在你的数据库中使用像以下的东西,假定你们正在使用日本银行:
OffsetDateTime odt = convertXmlgcToOdt(xmlDate);
PreparedStatement pStmt = yourDatabaseConnection
.prepareStatement("insert into your_table(your_tstz_column) values(?);");
pStmt.setObject(1, odt);
pStmt.executeUpdate();
如果使用<条码>日间断时间区条码>,因此<条码> 当地日条码>,仅通过<条码> 当地日条码>至<条码>。
For really old Java versions
If using Java 6 or 7, use the backport of java.time named ThreeTen Backport, link at the bottom. In this case you can’t directly pass the java.time objects to your PreparedStatement
. One option is to format into strings that you pass to PreparedStatement.setString()
. If using Java 5, use Joda-Time in a similar manner.
Control the time zone via the database session
If for some reason I can’t guess you are forced to use one of the problematic and outdated Date
classes, use the conversion you already have. Configure your database session to use America/Chicago time zone. I don’t understand the logic in this configuration belonging to the session, to me it rather belongs to the database column; but most SQL databases offer it as a setting on the session. Search for how it’s done with your brand of database engine/RDBMS. I include a link for DB2 below to get you started. The DB2 “session time zone” is a mere offset from UTC, so when dealing with times in both standard time and summer time, you will need to set it for each value stored.
www.un.org/Depts/DGACM/index_spanish.htm 或者通过科索沃信托公司违约时区: 真正的 d脏解决办法是,将你的证书的缺省定在独立于服务器的本组织时区之外。 认识到这将影响整个 Java方案,并可能对该方案的其他部分产生意外影响。 我期望它控制用于将<代码>Date转换为timestamp/code>数据类型的时间区,尽管(我尚未测试)。
Either start your server program with a command line option for the purpose, like for example:
java -Duser.timezone=America/Chicago YourApp
Or set the property from within your code, before doing any date and time work:
System.setProperty("user.timezone", "America/Chicago");
If all else fails, tell a lie
如果在您的设置中没有任何上述内容可行,你需要一种办法,以弥补以下事实:你的服务器、证书和你的数据库对时间区有分歧,因此,在储存时对ate进行错误的转换。 我认为,你在自己的答复中所用的骗子似乎奏效,但只有你知道,我们正在做的是故意不正确的转换<>/em>,以弥补我们在储存时从我们的控制下进行的相反不正确的转换。 如果是我的话,我想在守则中阐明这一点,或者今后读到该守则的人可能会被严重混淆,并可能试图“纠正”他们可能认为的无意错误。 您可以自行转换或排雷,或 mix。 这里的地雷:
/**
* Convert to America/Chicago time zone
* and then convert further to a {@code Date} that when interpreted
* in the default time zone of the JVM
* has the same date and time of day (wall-clock time)
* no matter if this makes the point in time wrong.
* We are doing a <em>deliberately incorrect conversion</em> to compensate
* for the opposite incorrect conversion taking place out of our control when
* storing the {@code Date}.
* That incorrect conversion happens because the JVM and the database
* disagree about time zone:
* the JVM uses UTC (GMT), but the database column must be in America/Chicago time zone.
*/
public static Date convertDate(XMLGregorianCalendar value) {
if (value == null) {
return null;
} else {
ZonedDateTime dateTimeWithDeliberatelyWrongTimeZone;
if (value.getHour() == DatatypeConstants.FIELD_UNDEFINED
&& value.getMinute() == DatatypeConstants.FIELD_UNDEFINED
&& value.getSecond() == DatatypeConstants.FIELD_UNDEFINED
&& value.getFractionalSecond() == null) { // Date only
dateTimeWithDeliberatelyWrongTimeZone = value.toGregorianCalendar()
.toZonedDateTime()
.toLocalDate()
.atStartOfDay(ZoneId.systemDefault());
} else { // date and time
if (value.getTimezone() == DatatypeConstants.FIELD_UNDEFINED) { // No UTC offset
// In this case the no-arg toGregorianCalendar() uses the JVM default time zone.
// which already gives us the incorrect result we are after.
dateTimeWithDeliberatelyWrongTimeZone = value.toGregorianCalendar()
.toZonedDateTime();
} else {
dateTimeWithDeliberatelyWrongTimeZone = value.toGregorianCalendar()
.toZonedDateTime()
.withZoneSameInstant(ZONE_ID)
// Preserve date and time of day
// when converting to default time zone
.withZoneSameLocal(ZoneId.systemDefault());
}
}
return Date.from(dateTimeWithDeliberatelyWrongTimeZone.toInstant());
}
}
如美洲金枪鱼委时区现有的那样,将同样的两个<代码>XMLGregorianCalendar的物体转换为:
Fri Feb 09 01:57:33 UTC 2024
Fri Feb 09 00:00:00 UTC 2024
而且,我们在<代码>中未作任何抵销。 XMLGregorianCalendar :
xmlDate = DatatypeFactory.newInstance()
.newXMLGregorianCalendar("2024-02-09T01:57:33.240");
Fri Feb 09 01:57:33 UTC 2024
参看<代码>Date物体在UTC上印。 由于时间是预期的,这意味着<代码>。 日期代码>从科技委起为6小时,因此不正确。 日期和印刷时间也是存放在数据库的日期和时间,这是你想要的。
Links