我的xmlGregorianCalendar带有偏移值..如何进行调整?在java中

我的xmlGregorianCalendar值为2020-10-02T13:07:38-06:00 ..我想传递此xmlGregorianCalendar值并获得类似于2020-10-02T07:07:38的输出(从时间)对此有什么建议吗?

我使用了以下方法。

返回新的Timestamp(xmlGregorianCalendar.toGregorianCalendar(TimeZone.getTimeZone(“ GMT”),null,null).getTimeInmillis())。

但是它删除了偏移值,但没有调整时间。我得到的输出是2020-10-02T13:07:38 ..但我希望像这样的2020-10-02T07:07:38。

aiko_87 回答:我的xmlGregorianCalendar带有偏移值..如何进行调整?在java中

首先,我建议您从过时且容易出错的java.util日期时间API切换到modern java.time日期时间API。从 Trail: Date Time 了解有关现代日期时间API的更多信息。

您对区域偏移的理解不正确

日期时间字符串2020-10-02T13:07:38-06:00告诉我们,给定的日期和时间已经从UTC偏移了-06:00小时,即{{1 }}为UTC,其中2020-10-02T19:07:38Z指定Z小时的区域偏移。

这意味着,如果您期望日期时间为00:00,则需要将给定的日期时间再偏移2020-10-02T07:07:38小时,即总计{{1} }小时偏离-06:00

以下示例说明了此概念:

-12:00

输出:

UTC

使用旧版API:

import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;

public class Main {
    public static void main(String[] args) {
        OffsetDateTime odtGiven = OffsetDateTime.parse("2020-10-02T13:07:38-06:00");
        System.out.println(odtGiven);

        // Date and time at Zone-Offset of 00:00 hours
        OffsetDateTime odtUTC = odtGiven.withOffsetSameInstant(ZoneOffset.UTC);
        System.out.println(odtUTC);

        // Date and time at Zone-Offset of -12:00 hours
        OffsetDateTime odtDerived = odtGiven.withOffsetSameInstant(ZoneOffset.of("-12:00"));
        System.out.println(odtDerived);

        // Get the date-time string in the format with Zone-Offset dropped
        String strDateTimeZoneOffsetDropped = odtDerived.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
        System.out.println(strDateTimeZoneOffsetDropped);
    }
}

输出:

2020-10-02T13:07:38-06:00
2020-10-02T19:07:38Z
2020-10-02T07:07:38-12:00
2020-10-02T07:07:38
,

JDBC 4.2和java.time

Arvind Kumar Avinash已经很好地解释了偏移量是如何工作的(XMLGregorianCalendar误导了时区)。他还已经推荐了java.time,这是现代的Java日期和时间API。我想详细说明这项建议。假设您认为自己的SQL数据库需要java.sql.Timestamp,则不希望这样做。从JDBC 4.2和Hibernate 5开始,我们可以将java.time的类型无缝地转移到我们的SQL数据库中。我建议您改为这样做。

如果在SQL中使用带时区的时间戳,请在Java中的UTC中使用OffsetDateTime

如果SQL中的数据类型为timestamp with time zone(建议使用时间戳),请从Java向其传输OffsetDateTime。对于大多数数据库引擎而言,timestamp with time zone的真正含义是UTC中的时间戳,因此为了清楚起见,我也希望传递一个也是UTC中的OffsetDateTime。有两种转换方式,各有优缺点。

1。通过GregorianCalendar转换

    // For demonstration build an XMLGregorianCalenadr equivalent to yours
    XMLGregorianCalendar xmlGregorianCalendar = DatatypeFactory.newInstance()
            .newXMLGregorianCalendar("2020-10-02T13:07:38-06:00");
    
    // Convert to OffsetDateTime for your SQL database
    OffsetDateTime dateTime = xmlGregorianCalendar.toGregorianCalendar()
            .toZonedDateTime()
            .toOffsetDateTime()
            .withOffsetSameInstant(ZoneOffset.UTC);

    // Show what we’ve got
    System.out.println(dateTime);

输出为:

2020-10-02T19:07:38Z

专业版:这是官方转换。

2。通过字符串转换

    OffsetDateTime dateTime = OffsetDateTime.parse(xmlGregorianCalendar.toString())
            .withOffsetSameInstant(ZoneOffset.UTC);

专业人士:简短,我认为它不会给您带来任何惊喜。缺点:对我来说,将其格式化为字符串并再次解析为日期时间对象感觉很浪费。

3。通过int 进行转换。您可以通过将各个字段从XMLGregorianCalendar中取出并从中建立一个OffsetDateTime来进行转换。它变得冗长,处理几分之一秒有点复杂,并且存在意外交换字段的风险,因此我不建议这样做。

如何传递给SQL 。这是将OffsetDateTime转移到SQL的示例。

    String sqlString = "insert into your_table(your_timestamp_column) values (?);";
    PreparedStatement ps = yourDatabaseConnection.prepareStatement(sqlString);
    ps.setObject(1,dateTime);
    int rowsInserted = ps.executeUpdate();

如果在SQL中使用不带时区的时间戳,请通过Java传递LocalDateTime

如果SQL中的数据类型为timestamp,没有时区(不建议用于时间戳,但是经常看到),则需要从Java传递LocalDateTime。同样,有两种转换方法。我只显示一个:

    LocalDateTime dateTime = xmlGregorianCalendar.toGregorianCalendar()
            .toZonedDateTime()
            .withZoneSameInstant(ZoneId.systemDefault())
            .toLocalDateTime();

我正在使用JVM的默认时区,以与老式Timestamp类一起使用,因此结果取决于时区。在我当前所在的时区(欧洲/哥本哈根)的世界标准时间偏移时间+02:00,结果是:

2020-10-02T21:07:38

您的代码出了什么问题?

您使用的三个参数XMLGregorianCalendar.toGregorianCalendar​(TimeZone,Locale,XMLGregorianCalendar)旨在引入类似您所观察到的错误的错误。它承诺构造一个具有指定时区(如果已指定)和GregorianCalendar中的字段值(年,月,日,时,分等)的XMLGregorianCalendar。因此文档非常清楚地说明了这一点:如果您指定的时区与XMLGregorianCalendar的偏移量不一致,那么它会为您提供与XMLGregorianCalendar指定的时间点不同的时间点。如果XMLGregorianCalendar没有任何偏移并且我们知道要使用哪个时区,这可能会偶尔有用。但是您的XMLGregorianCalendar已经偏移了,因此此方法绝对不是您要使用的方法。

链接

本文链接:https://www.f2er.com/1461605.html

大家都在问