我在我们现有的应用程序中面临一个问题,其中员工输入的时间(从他的组织/商店使用时钟应用程序)首先转换为 GMT,然后存储在数据库中。并且为了显示回来,将GMT时间转换回存储本地时区并显示。在大多数情况下,这可以正常工作,但当时区移动到 DST 时则不行,反之亦然。
让我更具体一点。假设商店的标准时区是 GMT-8 并且员工在早上 08:00 打卡,因此将时间转换为 GMT 16:00,然后存储在 DB 中。转换过程首先将这个 08:00 AM 转换为存储本地时间,以某种方式给出 17:00 CET,然后这个 17:00 CET 转换为 GMT,给出 16:00 CET。
但是,如果我们以 3 月 31 日的 DST 为例,此时 02:00 AM 变为 03:00 AM。假设员工在 18:00(3 月 30 日)打卡,它在第一次转换为本地时返回给我 04:00 AM CEST,然后当我将其转换为 GMT 时,它给出了 03:00 CEST。因此,在将其转换回来时,这会给出 19:00,这是不正确的。该设计表示本地时间被转换为 UTC,然后存储在数据库中,但如果它仍然是 UTC,那么它应该存储 02:00 AM 而不是 03:00 AM,因为 GMT/UTC 没有 DST。
用于进行转换的代码是:
步骤1
final Date localPunchDateTime = R3ValConverter.convertFromTimeZone(teData.m_dtTm,
TimeZone.getTimeZone("GMT-8"));
第2步
teData.m_dtTm = R3ValConverter.convertToGMT( localPunchDateTime );
R3ValConverter.java
public static Date convertFromTimeZone(final Date dtSrc, final TimeZone tzSrc)
{
final SISDateTime dtTmTemp = new SISDateTime(dtSrc, TimeZone.getDefault());
final SISDateTime dtTmSrc = new SISDateTime( dtTmTemp.getYear(), dtTmTemp.getMonth(),
dtTmTemp.getDate(), dtTmTemp.getHour(),
dtTmTemp.getMinute(), dtTmTemp.getSecond(),
tzSrc );
return dtTmSrc.toDate();
}
SISDateTime
GregorianCalendar m_cal;
public SISDateTime(Date dt, TimeZone tz) throws SISDateTimeException
{
m_cal = new GregorianCalendar(tz);
m_cal.setTime(dt);
resetMillis();
}
另一个 SISDateTime 方法也使用相同的 GregorianCalendar。
我真的很感激在这方面的任何帮助。我在这里假设我们在第一步中遇到了一些问题,但目前不知道有什么好的解决方案。