gpt4 book ai didi

java - 在 MySQL 和 Glassfish 中保存 ZonedDateTime

转载 作者:可可西里 更新时间:2023-11-01 09:05:20 27 4
gpt4 key购买 nike

这是我在这个论坛上的第一个问题,请耐心等待。

Oracle 说“ZonedDateTime 是一个具有完全限定时区的日期和时间。这可以解决任何时间点的偏移量。经验法则是,如果您想表示日期和时间而不依赖于上下文特定服务器的,您应该使用 ZonedDateTime。”这正是我想要做的,因为应用程序正在处理全局交互,但 MySQL 似乎只将 DATETIME 保存为 TIMESTAMP,但它显然将其保存为 UTC,以便它可以转换为任何时区。我们将在其上运行的服务器将在多个时区运行,我们不知道哪个将在何处运行,因为云提供商将根据需求和维护动态移动它们。

因此,在此应用程序中维护日期/时间/时区似乎非常适合新的 ZonedDateTime 构造,但我一直感到困惑,试图在 PrimeFaces 和其他组件代码仍然提供的遗留日期之间保持一切正常和 MySQL,它想要处理最终将在 2038 年过时的时间戳。

我们不想使用任何外部日期库,例如 Joda 或 Apache。

我的问题相当直截了当,但答案对我来说似乎难以捉摸,而且细微差别似乎很多:将 java ZonedDateTime 保存到 MySQL 数据库、读回它以便工作的最佳实践是什么可以由用户通过 java 在全局范围内执行即时计算,这对本地用户来说是正确的,并且无论 Glassfish 服务器或 MySQL 服务器的位置如何,它们都可能彼此处于不同的时区,而且每天都在不同的时区天?

最佳答案

我认为这让我们震惊的方式是:MySQL 在将日期保存为时间戳时将日期保存为 UTC,因此只要我这样做,MySQL 位于何处都无关紧要。

Glassfish 可以通过查询服务器告诉您它所在的位置,但它也可以为家庭办公室设置一个属性,为您提供一个在服务器所在的任何地方都一致的操作基础。你可以在 web.xml 中做到这一点

<context-param>
<param-name>GLASSFISH_HOME_TIME_ZONE</param-name>
<param-value>America/New_York</param-value>
</context-param>

数据 bean 需要完成大部分工作,以便它与所有数据使用中的数据保持一致。未更新到 ZonedDateTime 或仅部分更新的组件库的问题通常会使用 getter 调用数据,因此使用重载应该允许组件库找到它喜欢的特定方法。我创建了一个看起来像这样的数据 bean:

公共(public)类 DataBean {

private final ZoneId GLASSFISH_HOME_TIME_ZONE = ZoneId.of(FacesContext.getCurrentInstance().getExternalContext().getInitParameter( "GLASSFISH_HOME_TIME_ZONE"));
private ZonedDateTime dateToUseInGlassfish = null;

public DataBean (
Timestamp dateFromMySQL)
{
if ( dateFromMySQL == null ) {
this.dateToUseInGlassfish = null;
} else {
this.dateToUseInGlassfish = LocalDateTime.ofInstant(dateFromMySQL.toInstant(), GLASSFISH_HOME_TIME_ZONE ).atZone( GLASSFISH_HOME_TIME_ZONE );
}
}

/** Formatter for Date/Time */
private final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("MM/dd/yyyy ' at ' h:mm a z");

/** Formatter for Date only */
private final DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("MM/dd/yyyy");

/** Get the date string formatted with date and time */
public String getDateToUseInGlassfishDateTimeFormatted() {
if ( dateToUseInGlassfish == null ) { return null; }
String formattedDate = dateTimeFormatter.format( dateToUseInGlassfish );
return formattedDate;
}

/** Get the date string formatted with date only */
public String getgetDateToUseInGlassfishDateFormatted() {
if ( dateToUseInGlassfish == null) { return null; }
String formattedDate = dateFormatter.format( dateToUseInGlassfish );
return formattedDate;
}

/** Get the date ZDT formatted (for calculations) */
public ZonedDateTime getgetDateToUseInGlassfish() {
return dateToUseInGlassfish;
}

/** Get the date as Date (for component libraries that automatically fetch then throw up with ZDT) */
public Date getDateToUseInGlassfishDate() {
if ( dateToUseInGlassfish == null) { return null; }
return Date.from( dateToUseInGlassfish.toInstant());
}

/** Set the date from ZDT (results from calculations stored in bean) */
public void setDateToUseInGlassfish( ZonedDateTime dateToUseInGlassfish ) {
this.dateToUseInGlassfish = dateToUseInGlassfish;
}

/** Set the date from Date with an automatic convert to ZDT */
public void setDateToUseInGlassfish( Date dateToUseInGlassfish ) {
if (dateToUseInGlassfish == null) {
this.dateToUseInGlassfish = null;
} else {
this.dateToUseInGlassfish = LocalDateTime.ofInstant( Instant.ofEpochMilli( dateToUseInGlassfish.getTime()), GLASSFISH_HOME_TIME_ZONE ).atZone( GLASSFISH_HOME_TIME_ZONE );
}
}

从 MySQL 获取日期作为时间戳是将其作为 UTC 时间点获取,它看起来像这样:

ResultSet resultSet = preparedSelectQuoteSql.executeQuery()) {
while (resultSet.next()) {
quoteBean = new QuoteBean(
resultSet.getTimestamp("MySQLDateColumn")
);
}
}

将其从 ZonedDateTime 插入/更新到 MySQL 中,成为 MySQL 自动转换为 UTC 的时间戳,这样我们就可以让 MySQL 存在于任何我们希望它存在的地方,并及时读回相同的瞬间:

if ( insertValue instanceof ZonedDateTime ) {
if ( insertValue != null ) {
Timestamp convertedDate = Timestamp.from( ((ZonedDateTime) insertValue).toInstant() );
preparedStatement.setTimestamp( paramNumber, convertedDate );
} else {
preparedStatement.setNull ( paramNumber, Types.TIMESTAMP );
}
}

我认为这是可行的,但我欢迎批评。

关于java - 在 MySQL 和 Glassfish 中保存 ZonedDateTime,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31909006/

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