既存のアプリケーションで、従業員が入力した時間が (タイム レコーダー アプリケーションを使用して組織/ストアから) 最初に GMT に変換されてから DB に保存されるという問題に直面しています。また、逆に表示する場合は、GMT の時刻が保存されているローカル タイム ゾーンに変換されて表示されます。ほとんどの場合、これは正常に機能しますが、タイム ゾーンが DST に移動したり、その逆の場合は機能しません。
もっと具体的に言ってみましょう。店舗の標準タイム ゾーンが GMT-8 で、従業員が午前 08:00 AM にパンチすると、時間は GMT に変換されて 16:00 になり、DB に格納されます。変換プロセスは、最初にこの 08:00 AM をローカル時間に変換します。これにより、17:00 CET が得られます。次に、この 17:00 CET が GMT に変換され、16:00 CET が得られます。
しかし、3 月 31 日の DST が午前 2 時から午前 3 時になる場合を例にとると、従業員が 18:00 (3 月 30 日) にパンチすると、ローカルへの最初の変換中に 04:00 AM CEST が返され、これを GMT に変換すると 03:00 CEST が返されます。したがって、元に戻すと 19:00 になりますが、これは正しくありません。設計では、現地時間が UTC に変換されてから DB に格納されると言われていますが、それでも UTC の場合は、GMT/UTC には DST がないため、午前 03:00 ではなく午前 2:00 を格納する必要があります。
変換を行うために使用されるコードは次のとおりです。
ステップ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();
}
SIS日時
GregorianCalendar m_cal;
public SISDateTime(Date dt, TimeZone tz) throws SISDateTimeException
{
m_cal = new GregorianCalendar(tz);
m_cal.setTime(dt);
resetMillis();
}
他の SISDateTime メソッドも同じ GregorianCalendar を使用しています。
この点で何か助けていただければ幸いです。ここで、最初のステップで問題が発生したと仮定していますが、現時点ではそれに対する適切な解決策はわかりません。