我认为这种方式让我们大吃一惊:当 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:
公共类 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 在任何我们希望它存在的地方运行并及时读回相同的 Instant:
if ( insertValue instanceof ZonedDateTime ) {
if ( insertValue != null ) {
Timestamp convertedDate = Timestamp.from( ((ZonedDateTime) insertValue).toInstant() );
preparedStatement.setTimestamp( paramNumber, convertedDate );
} else {
preparedStatement.setNull ( paramNumber, Types.TIMESTAMP );
}
}
我认为这行得通,但我欢迎批评。