如何在指定时区的休眠中获取记录?
How to Fetch records in hibernate with specified Timezone?
- 我需要为我的应用程序提供对不同时区的支持。
- 为了插入,我的 JVM 默认使用 UTC 时间,因此在 @CreationTimestamp 和 @UpdateTimestamp 的帮助下,hibernate 将创建和更新日期作为 UTC 时间插入,后者指的是 JVM 时区。
- 每个请求都来自不同的时区。基于时区,我需要将 UTC 时间解析为该特定时区。
- 我不想手动解析所有记录的日期。休眠中是否有任何选项,就像我在获取时指定时区一样。这样我就可以根据给定的时区获取创建和更新的日期(时区是动态获取的)。
已经有几个关于日期时间最佳实践的话题,例如Daylight saving time and time zone best practices
我建议如下:
- 始终在后端和数据库中将所有日期时间处理为 UTC。
- 将日期时间作为 UTC 传输给您的客户。
- 在客户端将 UTC 日期时间转换为本地日期时区。用于显示和更新目的。
根据我的经验,最好让客户端处理所有本地 datetime/zone 转换并承诺将 UTC 用于所有通信和后端用例。
如果您想将日期直接转储到网页中,您可以使用 http://momentjs.com/ 之类的 js 库将其转换为语言环境日期时间。
您可以创建实用程序(通用方法)以将日期转换为时区
下面是一些要转换的例子。
public static Date buildUTCDate(String dateString) throws ParseException {
SimpleDateFormat dateFormat = new SimpleDateFormat(SecureCareConstant.SQL_TIMESTAMP_FORMAT);
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
return dateFormat.parse(dateString);
}
public static String dateToString(Date date) {
return new SimpleDateFormat(SecureCareConstant.SQL_TIMESTAMP_FORMAT).format(date);
}
public static Date buildUTCDate(Date date) {
SimpleDateFormat fromDateFormat = new SimpleDateFormat(SecureCareConstant.SQL_TIMESTAMP_FORMAT);
SimpleDateFormat toDateFormat = new SimpleDateFormat(SecureCareConstant.SQL_TIMESTAMP_FORMAT);
toDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
String dateString = new SimpleDateFormat(SecureCareConstant.SQL_TIMESTAMP_FORMAT).format(date);
try {
return fromDateFormat.parse(toDateFormat.format(fromDateFormat.parse(dateString)));
} catch (ParseException e) {
LOGGER.error("ParseException in buildUTCDate()", e);
}
return null;
}
public static Date getCurrentTimeZoneDate(final Date date) {
Calendar c = Calendar.getInstance();
c.setTime(date);
TimeZone z = c.getTimeZone();
int offset = z.getRawOffset();
if (z.inDaylightTime(new Date())) {
offset = offset + z.getDSTSavings();
}
int offsetHrs = offset / 1000 / 60 / 60;
int offsetMins = offset / 1000 / 60 % 60;
c.add(Calendar.HOUR_OF_DAY, (+offsetHrs));
c.add(Calendar.MINUTE, (+offsetMins));
return c.getTime();
}
public static String toLocalTime(Date dateUTC) {
if (dateUTC == null) {
return StringUtils.EMPTY;
}
SimpleDateFormat dateFormat = new SimpleDateFormat(SecureCareConstant.WEB_SERVICE_DATE_FORMAT);
return dateFormat.format(new Date(dateUTC.getTime() + TimeZone.getDefault().getOffset(dateUTC.getTime())));
}
- 我需要为我的应用程序提供对不同时区的支持。
- 为了插入,我的 JVM 默认使用 UTC 时间,因此在 @CreationTimestamp 和 @UpdateTimestamp 的帮助下,hibernate 将创建和更新日期作为 UTC 时间插入,后者指的是 JVM 时区。
- 每个请求都来自不同的时区。基于时区,我需要将 UTC 时间解析为该特定时区。
- 我不想手动解析所有记录的日期。休眠中是否有任何选项,就像我在获取时指定时区一样。这样我就可以根据给定的时区获取创建和更新的日期(时区是动态获取的)。
已经有几个关于日期时间最佳实践的话题,例如Daylight saving time and time zone best practices
我建议如下:
- 始终在后端和数据库中将所有日期时间处理为 UTC。
- 将日期时间作为 UTC 传输给您的客户。
- 在客户端将 UTC 日期时间转换为本地日期时区。用于显示和更新目的。
根据我的经验,最好让客户端处理所有本地 datetime/zone 转换并承诺将 UTC 用于所有通信和后端用例。
如果您想将日期直接转储到网页中,您可以使用 http://momentjs.com/ 之类的 js 库将其转换为语言环境日期时间。
您可以创建实用程序(通用方法)以将日期转换为时区 下面是一些要转换的例子。
public static Date buildUTCDate(String dateString) throws ParseException {
SimpleDateFormat dateFormat = new SimpleDateFormat(SecureCareConstant.SQL_TIMESTAMP_FORMAT);
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
return dateFormat.parse(dateString);
}
public static String dateToString(Date date) {
return new SimpleDateFormat(SecureCareConstant.SQL_TIMESTAMP_FORMAT).format(date);
}
public static Date buildUTCDate(Date date) {
SimpleDateFormat fromDateFormat = new SimpleDateFormat(SecureCareConstant.SQL_TIMESTAMP_FORMAT);
SimpleDateFormat toDateFormat = new SimpleDateFormat(SecureCareConstant.SQL_TIMESTAMP_FORMAT);
toDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
String dateString = new SimpleDateFormat(SecureCareConstant.SQL_TIMESTAMP_FORMAT).format(date);
try {
return fromDateFormat.parse(toDateFormat.format(fromDateFormat.parse(dateString)));
} catch (ParseException e) {
LOGGER.error("ParseException in buildUTCDate()", e);
}
return null;
}
public static Date getCurrentTimeZoneDate(final Date date) {
Calendar c = Calendar.getInstance();
c.setTime(date);
TimeZone z = c.getTimeZone();
int offset = z.getRawOffset();
if (z.inDaylightTime(new Date())) {
offset = offset + z.getDSTSavings();
}
int offsetHrs = offset / 1000 / 60 / 60;
int offsetMins = offset / 1000 / 60 % 60;
c.add(Calendar.HOUR_OF_DAY, (+offsetHrs));
c.add(Calendar.MINUTE, (+offsetMins));
return c.getTime();
}
public static String toLocalTime(Date dateUTC) {
if (dateUTC == null) {
return StringUtils.EMPTY;
}
SimpleDateFormat dateFormat = new SimpleDateFormat(SecureCareConstant.WEB_SERVICE_DATE_FORMAT);
return dateFormat.format(new Date(dateUTC.getTime() + TimeZone.getDefault().getOffset(dateUTC.getTime())));
}