彼が言うように、彼の問題に対するOPの解決策には、疑わしい出力があります。そのコードは、時間の表現についてまだ混乱を示しています。この混乱を解消し、間違った時間につながらないコードを作成するために、彼が行ったことの次の拡張を検討してください。
public static void _testDateFormatting() {
SimpleDateFormat sdfGMT1 = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
sdfGMT1.setTimeZone(TimeZone.getTimeZone("GMT"));
SimpleDateFormat sdfGMT2 = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss z");
sdfGMT2.setTimeZone(TimeZone.getTimeZone("GMT"));
SimpleDateFormat sdfLocal1 = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
SimpleDateFormat sdfLocal2 = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss z");
try {
Date d = new Date();
String s1 = d.toString();
String s2 = sdfLocal1.format(d);
// Store s3 or s4 in database.
String s3 = sdfGMT1.format(d);
String s4 = sdfGMT2.format(d);
// Retrieve s3 or s4 from database, using LOCAL sdf.
String s5 = sdfLocal1.parse(s3).toString();
//EXCEPTION String s6 = sdfLocal2.parse(s3).toString();
String s7 = sdfLocal1.parse(s4).toString();
String s8 = sdfLocal2.parse(s4).toString();
// Retrieve s3 from database, using GMT sdf.
// Note that this is the SAME sdf that created s3.
Date d2 = sdfGMT1.parse(s3);
String s9 = d2.toString();
String s10 = sdfGMT1.format(d2);
String s11 = sdfLocal2.format(d2);
} catch (Exception e) {
e.printStackTrace();
}
}
デバッガーで値を調べる:
s1 "Mon Sep 07 06:11:53 EDT 2015" (id=831698113128)
s2 "2015.09.07 06:11:53" (id=831698114048)
s3 "2015.09.07 10:11:53" (id=831698114968)
s4 "2015.09.07 10:11:53 GMT+00:00" (id=831698116112)
s5 "Mon Sep 07 10:11:53 EDT 2015" (id=831698116944)
s6 -- omitted, gave parse exception
s7 "Mon Sep 07 10:11:53 EDT 2015" (id=831698118680)
s8 "Mon Sep 07 06:11:53 EDT 2015" (id=831698119584)
s9 "Mon Sep 07 06:11:53 EDT 2015" (id=831698120392)
s10 "2015.09.07 10:11:53" (id=831698121312)
s11 "2015.09.07 06:11:53 EDT" (id=831698122256)
sdf2 と sdfLocal2 にはタイム ゾーンが含まれているため、実際に何が起こっているかを確認できます。s1 と s2 はゾーン EDT の 06:11:53 です。s3 と s4 はゾーン GMT の 10:11:53 にあり、元の EDT 時間に相当します。一貫性のために GMT を使用しているデータベースに s3 または s4 を保存すると想像してください。異なるタイム ゾーンを保存することなく、世界中のどこからでも時間を取得できます。
s5 は GMT 時間を解析しますが、現地時間として扱います。つまり、「10:11:53」(GMT 時間) と表示されますが、現地時間で 10:11:53 と見なされます。良くない。
s7 は GMT 時刻を解析しますが、文字列内の GMT を無視するため、ローカル時刻として扱います。
s8 が機能するのは、文字列に GMT が含まれるようになり、ローカル ゾーン パーサーがそれを使用してあるタイム ゾーンから別のタイム ゾーンに変換するためです。
ここで、ゾーンを保存するのではなく、s3 を解析できるようにしたいが、それを現地時間として表示したいとします。答えは、保存されたのと同じタイム ゾーンを使用して解析することです。そのため、作成されたのと同じ sdf、sdfGMT1 を使用します。s9、s10、および s11 はすべて元の時間の表現です。それらはすべて「正しい」です。つまり、d2 == d1 です。次に、それをどのように表示したいかだけの問題です。DB に格納されているもの (GMT 時間) を表示する場合は、GMT sdf を使用してフォーマットする必要があります。s10です。
したがって、文字列に " GMT" を明示的に格納したくない場合、および GMT 形式で表示する場合の最終的な解決策は次のとおりです。
public static void _testDateFormatting() {
SimpleDateFormat sdfGMT1 = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
sdfGMT1.setTimeZone(TimeZone.getTimeZone("GMT"));
try {
Date d = new Date();
String s3 = sdfGMT1.format(d);
// Store s3 in DB.
// ...
// Retrieve s3 from database, using GMT sdf.
Date d2 = sdfGMT1.parse(s3);
String s10 = sdfGMT1.format(d2);
} catch (Exception e) {
e.printStackTrace();
}
}