gpt4 book ai didi

java - 将数据库时间戳列映射到 UTC 日历 (JPA) 并通过 WebService (jax-ws) 将其作为 UTC 日期传递

转载 作者:行者123 更新时间:2023-12-04 12:57:22 24 4
gpt4 key购买 nike

这听起来像是一项简单的任务。
从数据库获取 UTC 时间戳值并通过 Web 服务将其作为 UTC 日期传递。

我们有时间戳列 DATE_COLUMN 并在其中存储 UTC 时区的时间。

有了 JPA,我们用

@Column(name = "DATE_COLUMN")
private java.sql.Timestamp dateValue;

因为我们必须通过 UTC 网络服务(Jax-ws 2.0)传递这个时间,所以我们有 getDate 和 setDate 方法。
我们对 getDate 感兴趣。

public Calendar getDate()
{
Calendar calendar = Calendar.getInstance(utcTimeZone);
calendar.setTimeInMillis(dateValue.getTime());

return calendar;
}

这并不像您认为的那样有效。
这是因为应用程序的默认时区不是“UTC”。

这里举个例子来说明。
DATE_COLUMN 中的值等于“30.11.09 16:34:48,833045000”,当我将其转换为 UTC 时,我得到“2009-11-30T14:34:48.833Z”。
相差2小时。这是因为我的默认时区是“欧洲/赫尔辛基”。

如果您只想将“DATE_COLUMN”映射到 Calendar,同样的问题

@Column(name = "DATE_COLUMN")
@Temporal(TemporalType.TIMESTAMP)
private Calendar dateValue;

public Calendar getDate()
{
calendar.setTimeZone(utcTimeZone);
return calendar;
}

我不想更改应用程序的时区,因为它看起来不像解决方案。

现在我们只有两个选择。

首先。计算应用程序的时区和UTC之间的偏移量,并在calendar.setTimeZone中自动减去后手动添加。

public Calendar getDate()
{
Calendar calendar = Calendar.getInstance(utcTimeZone);
calendar.setTimeInMillis(dateValue.getTime());

int offset = TimeZone.getDefault().getOffset(dateValue.getTime());

calendar.add(Calendar.MILLISECOND, offset);

return calendar;
}

其次。通过 Web 服务将 dateValue 作为 Long 传递。这还不错,只是我们在 wsdl 中丢失了字段的真实类型。

我想象中的解决方案是

@Column(name = "DATE_COLUMN")
@Temporal(type = TemporalType.TIMESTAMP, timezone = 'UTC')
private Calendar dateValue;

但我倾向于认为某处是真实的。我希望你能指出这一点。

最佳答案

我们决定使用以下解决方案。
使用 Date 从数据库中检索日期。这是因为Date是无时区类型。

@Column(name = "DATE_COLUMN")
@Temporal(TemporalType.TIMESTAMP)
private Date dateValue;

public Date getDate()
{
return dateValue;
}

为了在 UTC (jax-ws) 中通过 WebService 发送它,我们创建了 UtcTimestampAdapter 以在编码阶段将区域从应用程序的默认值更改为 UTC。

public class UtcTimestampAdapter extends XmlAdapter<XMLGregorianCalendar, Date>
{
@Override
public XMLGregorianCalendar marshal(Date date) throws Exception
{
GregorianCalendar calendar = new GregorianCalendar();
calendar.setTime(date);

DatatypeFactory dataTypeFactory = DatatypeFactory.newInstance();
XMLGregorianCalendar xmlCalendar =
dataTypeFactory.newXMLGregorianCalendar(calendar);

//Reset time zone to UTC
xmlCalendar.setTimezone(0);

return xmlCalendar;
}

@Override
public Date unmarshal(XMLGregorianCalendar calendar) throws Exception
{
return calendar.toGregorianCalendar().getTime();
}
}

然后为了对模块中的所有 Data 字段启用此规则,我们像这样添加了特定于包的设置。

@XmlJavaTypeAdapter(value = UtcTimestampAdapter.class, type = Date.class)
@XmlSchemaType(name = "dateTime", type = XMLGregorianCalendar.class)
package com.companyname.modulename;

就是这样。现在我们有了将所有逻辑封装在一个地方的通用解决方案。如果我们想在其他模块中通过 Web 服务将无时区日期作为 UTC 发送,我们将只注释特定的包。

关于java - 将数据库时间戳列映射到 UTC 日历 (JPA) 并通过 WebService (jax-ws) 将其作为 UTC 日期传递,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1821104/

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