gpt4 book ai didi

java - 将“伪”时间戳存储到数据库中

转载 作者:行者123 更新时间:2023-12-01 11:20:34 27 4
gpt4 key购买 nike

这是我要解决的问题:从数据库A读取一个字符串,将该字符串转换为Date对象,将Date对象存储到数据库B中。

例)数据库A:从数据库A读入日期字符串“ 2015-03-08 02:00:00”,转换为Date对象,再存储回数据库B。

出现此问题的原因是,美国中部时间DST的开始是2:00 AM,因此Data对象将2:00 AM直接转换为3:00 AM,这意味着3:00 AM被存储到数据库B中。

有什么办法可以纠正这个问题?如果有必要,我不反对使用Joda Time。

我想着重于上述日期,2015-03-08 02:00:00

这是我正在使用的代码:

    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
String date = "2015-03-08 02:00:00.0";



try
{
d = sdf.parse(date);
sdf.format(d);

//Insert into database here
// ---
//
}
catch (ParseException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}

最佳答案

您有多个问题交织在一起。

您不应从数据库中读取日期时间值的字符串,而应读取日期时间对象。关于从数据库读取日期时间值/向数据库写入日期时间值,StackOverflow上有很多问题,因此在此无需重复。

如果确实有字符串,例如“ 2015-03-08 02:00:00”,请注意缺少时区或偏移量的任何指示符。如果要假定该字符串表示特定于美国中部时间的时间,那么您必须接受这样一个事实,即没有这样的日期时间,因为夏令时(DST)将其定义为凌晨3点。在凌晨2点,时间标签跳至凌晨2点。因此,试图获得这样一个不存在的日期时间是没有意义的。

使用正确的时区名称

日期时间工作的重要提示:避免将时区视为“中央时间”和3-4个字母代码(如“ CST”)。这些没有标准化,也不是唯一的(很多重复),并且进一步混淆了夏令时。使用“大陆/ majorCityOrRegion”模式中的proper time zone

当地日期时间

也许您的意思是我们所谓的“本地时间”,其中日期时间并非特定于任何时区。例如,“圣诞节从2015年12月25日午夜开始”。这意味着每个特定时区的时刻都不一样。例如,圣诞节在巴黎比蒙特利尔早。

乔达时代

让我们在Joda-Time中将该字符串解释为LocalDateTime。首先,为方便起见,我们将SPACE替换为“ T”,以利用Joda-Time内置的ISO 8601格式解析器。

String input = "2015-03-08 02:00:00";
String inputStandardized = input.replace( " ", "T" ); // For convenience, convert input text to comply with ISO 8601 standard’s canonical format. Replace SPACE between date & time portions with "T".


接下来,我们解析该标准化字符串。

LocalDateTime localDateTime = LocalDateTime.parse( inputStandardized );


转储到控制台。

System.out.println( "inputStandardized: " + inputStandardized );
System.out.println( "localDateTime: " + localDateTime );


运行时。

inputStandardized: 2015-03-08T02:00:00
localDateTime: 2015-03-08T02:00:00.000


可以使用 SQL type TIMESTAMP WITHOUT TIME ZONE将此本地日期时间存储在SQL数据库中。此类型表示在获取(SELECT)或放置(INSERT / UPDATE)数据库值时,不对UTC时区进行任何调整。有关这些SQL类型的更多信息,请参见 Postgres doc

分区日期时间

如果您要表示特定时区(例如 America/Chicago)中的特定时刻,那么我们需要分配该时区。对于这种特定于时区的值,您将在数据库中使用数据类型 TIMESTAMP WITH TIME ZONE。该类型名称具有误导性-意味着尊重时区,因为它将输入数据调整为UTC。然后,数据的原始时区就会丢失。

不幸的是,这是Joda-Time让我们失望的少数情况之一。 Joda-Time拒绝进行调整,而不是进行调整,而是引发异常。 ☹

自己看看……让我们将以下代码添加到上面的示例代码中。

DateTimeZone zone = DateTimeZone.forID( "America/Chicago" );
DateTime dateTimeChicago = localDateTime.toDateTime( zone ); // If the input lacks an offset, then Joda-Time *assigns* the value the specified time zone. If the input has an offset, Joda-Time *adjusts* the value to the specified zone.


转储到控制台。

System.out.println( "zone: " + zone );
System.out.println( "dateTime: " + dateTimeChicago );


运行时。

Exception in thread "main" org.joda.time.IllegalInstantException: Illegal instant due to time zone offset transition (daylight savings time 'gap'): 2015-03-08T02:00:00.000 (America/Chicago



似乎没有很好的通用解决方法,只有黑客。基本上,如果您期望某个时区,则可以自己进行调整。请参见 thisthisthisthe Joda-Time FAQ之类的讨论。

java.time

在Java 8和更高版本中,我们在 java.time packageTutorial)中具有新的内置日期时间框架。该框架的灵感来自Joda-Time,并且比Joda-Time具有一些优势。这些优点之一是处理此DST不存在的值问题。

String input = "2015-03-08 02:00:00";
String inputStandardized = input.replace( " ", "T" );

LocalDateTime localDateTime = LocalDateTime.parse( inputStandardized );


让我们调整该本地日期时间以分配特定的时区。 java.time框架检测到不存在的日期时间,并自动向前滑动日期时间以遵守DST转换。

ZoneId zone = ZoneId.of( "America/Chicago" );
ZonedDateTime zdt = ZonedDateTime.of( localDateTime, zone );


转储到控制台。

System.out.println("inputStandardized: " + inputStandardized );
System.out.println("localDateTime: " + localDateTime );
System.out.println("zone: " + zone );
System.out.println("zdt: " + zdt );


运行时。

inputStandardized: 2015-03-08T02:00:00
localDateTime: 2015-03-08T02:00
zone: America/Chicago
zdt: 2015-03-08T03:00-05:00[America/Chicago]


的SQL

如上所述,您可以在StackOveflow上搜索有关将日期时间进出数据库的大量信息。

理想情况下,使用java.time,您可以将 LocalDateTimeZonedDateTime直接提供给JDBC驱动程序。但是大多数驱动程序尚未更新以处理java.time类型。在更新驱动程序之前,请退回 java.sql.* classes。在Java捆绑的新旧类中都可以找到方便的转换方法。

java.sql.Timestamp ts = java.sql.Timestamp.valueOf( localDateTime );


…要么…

Instant instant = zdt.toInstant();
java.sql.Timestamp ts = java.sql.Timestamp.from( instant );

关于java - 将“伪”时间戳存储到数据库中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31279064/

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