1。準備知識
1.日光の節約時間の節約時間/new_yorkは次のとおりです。左は右ではありません
2016-3-13、02:00:00から2016-11-6、02:00:00
2017-3-12、02:00:00から2017-11-5、02:00:00
2。3文字タイムゾーンID
JDK 1.1.xとの互換性のために、いくつかの3文字のタイムゾーンID(「PST」、「CTT」、「AST」など)もサポートされています。
ただし、同じ略語が複数のタイムゾーンでよく使用されるため、それらの使用は廃棄されます
たとえば、CST:4つの意味、米国、オーストラリア、中国、キューバの時間
3。標準
GMT:グリーン平均タイムグリニッジ標準時間、1960年以前に標準時間参照GMT+12-> GMT-12として使用されました
Java8の範囲はGMT+18-> GMT-18です
UTC:調整されたユニバーサルタイムタイム調整は、GMTよりも正確であり、1972年1月1日に新しい標準になります。 UTC、UTC+1、UTC+2 ... UTC+12、UTC-12 ... UTC-1
Java8の範囲UTC-18-> UTC+18
DST:夏時間の節約時間とは、夏に1時間の時点で時計が上昇して日光を以前に使用する時間を指します。英国では夏時間と呼ばれます。
現在、110か国以上が夏時間を使用しています。
中国では、1986年から1992年まで6年間のみ実装され、その後キャンセルされました。理由は次のとおりです。
1.中国は東部と西の方向に大きなスパンを持っており、夏の節約時間を使用して東と西と両立しない統一された東8番目の地区を採用しています。
2。照度の高い地域では、冬と夏に昼と夜の時間が大きく変化します。それはあまり意味がありません。
4.東8番目の地区がGMT+8またはetc/gmt-8であることを示すために使用できます(なぜですか、なぜですか?なぜPHP開発者は東8番目の地区が標準時間よりも8時間高速であると信じており、8時間で減算する必要があるため、表現は異なる参照オブジェクトが異なる表現方法につながります;)
5。中国のタイムゾーンを表現する方法
GMT+8
UTC+8
アジア/ハルビンハルビン//中国の標準時間
アジア/チョンキンチョンキン//中国の標準時間
アジア/チョンキングチョンキン//中国の標準時間
アジア/urumqi urumqi //中国の標準時間
アジア/上海上海(東8地区)//中国の標準時間
PRC
アジア/マカオマカオ//中国の標準時間
香港香港//香港の時間は中国の標準時間と一致しています
アジア/hong_kong香港
アジア/台北台(台湾)//中国の標準時間シンガポールは中国の時代と同じです。
アジア/シンガポール
シンガポール
6。標準のタイムゾーンの表現
UTC
UTC+0
UTC-0
GMT GMT
GMT0 GMT
など/gmt gmt
etc/gmt+0 gmt
etc/gmt-0 gmt
など/GMT0 GMT0 GMTS標準時間注:GMT+XX(-XX)は非常に包括的であり、さまざまな時間の表現を自動的に識別できます。
2。タイムゾーン変換
環境:Java8の前
1。現在の時間を指定されたタイムゾーンディスプレイに変換します
@test public void test()throws Exception {date a = new date(); SimpleDateFormat sf = new SimpledateFormat( "yyyy-mm-dd hh:mm:ss"); sf.settimezone(timezone.gettimezone( "America/new_york")); //中国のタイムゾーンを米国のニューヨークタイムゾーンに変換します。 }2。指定された時間は指定されたタイムゾーンディスプレイに変換されます
本当に正しく変換できますか?落とし穴があるようです、私はオンラインで実装を見ました
夏時間に少し問題があると感じています
//実装方法1:夏時間の節約時間は@test public void test2()スロー例外{ /date datetime = new simpledateFormat( "yyyy-mm-dd hh:mm:ss")。parse( "2016-11-6 14:00:00");日付dateTime = new SimpledateFormat( "yyyy-mm-dd HH:mm:ss")。parse( "2016-10-6 14:00:00"); TimeZone Zhong = TimeZone.GetTimeZone( "GMT+8:00"); //中国TimeZone York = TimeZone.GetTimeZone( "America/new_york"); // gmt-5 //タイムゾーンオフセットここで固定されています、夏時間の節約時間はありません、エラーlong chinesemills = datetime.getTime() + York.getRawoffset() - Zhong.getRawoffset();日付date = new Date(Chinesemills); System.out.println(new SimpledateFormat( "yyyy-mm-dd hh:mm:ss")。形式(日付)); }//実装方法2カレンダークラスのcalendar.dst_offsetを使用することを思い出すことができます。 simpledateformat( "yyyy-mm-dd hh:mm:ss")。parse( "2016-11-6 1:00:00"); //日付時刻= new simpledateformat( "yyyy-mm-ddhh:mm:ss")。 HH:mm:ss ")。parse(" 2016-11-6 0:59:00 "); // date time = new simpledateFormat(" yyyy-mm-dd hh:mm:ss ")。 HH:mm:ss ")。parse(" 2016-11-6 3:00:00 "); // 1。現地時間を取得:カレンダーcal = calendar.getInstance(); cal.settimezone(cal.settimezone(cal.settimezone(timezone.gettimezone)(timezone.gettimezone(" America/new_york "); // 2。 cal.get(calendar.zone_offset)/(1000*60*60); // 3。日光を節約する時間差を取得します。これは、時間の動的な判断に基づいていないことです。タイムゾーンに夏時間がある限り、それは1int dstoffset = cal.get(calendar.dst_offset)/(1000*60*60); out.println(ゾーンオフセット); system.out.println(dstoffset); // 4。 - (ゾーンオフセット + dStoffset))); cal.add(calendar.hour、 - (ゾーンオフセット + dstoffset)); date time2 = cal.gettime(); out.out.println(new simpledateFormat( "yyyy-mm -dd hh:mm:ss")。
//実装方法3準備// Javaが私たちの夏時間を自動的に処理すると言っていませんか? //最初に、夏時間の判断方法が正しいかどうかを確認するための簡単なテストを行いましょう。Javaの自動処理が正しいかどうかを推測できます// 2016年には、2016年に夏時間時間があることが知られています。 point simpledateFormat sf = new simpledateFormat( "yyyy-mm-dd hh:mm:ss"); sf.settimezone(timezone.gettimezone( "gmt+0")); // date datetime = sf.parse( "2016-11-6 5:59:59");日付d1 = sf.parse( "2016-03-13 6:59:59"); // false Date D2 = Sf.Parse( "2016-03-13 7:00:00"); // True Date D3 = Sf.Parse( "2016-11-6 6:59:59"); //夏時間の開始を判断するのに実際に問題はないことがわかりましたが、夏時間の終了時間の間、正確には、1時間前に判断しました//以下の検証を見てください。それを解決する方法は?現在、私はJava8 D3 = sf.Parse( "2016-11-6 5:59:59") // gmt-5 System.out.println( "ターゲットタイムゾーンは夏時間を使用しますか:"+isdaylight(York、d1)); System.out.println( "ターゲットタイムゾーンは夏時間を節約するのを使用しますか:"+isdaylight(York、D2)); System.out.println( "ターゲットタイムゾーンは夏時間を使用しますか:"+isdaylight(York、d3)); System.out.println( "ターゲットタイムゾーンは夏時間を使用しますか:"+isdaylight(York、d4)); } //プライベートブールisdaylight(タイムゾーンゾーン、日付){return zone.usedaylighttime()&&ゾーン.indaylighttime(date); } //実装方法3 //上記の検証を通じて、システムの判断に問題があることがわかります。タイムゾーンを設定することにより、プログラムは夏時間を自動的に処理します。少なくとも、@testpublic void test5()が例外をスローする理由がわかりません{// 13時間アパートチャイナ + 8ニューヨーク-5チェンジゾーン( "2016-3-13 14:59:59"、 "prc"、 "America/new_york"、 "yyyy-mm-dd hh:mm:ss"); 15:00:00 "、" prc "、" America/new_york "、" yyyy-mm-dd hh:mm:ss "); // 2016-03-13 03:00:00 ChangeZone(" 2016-11-6 13:59:59 "、" prc "、" america/nework "、" yyym-mdd HH:mm:ss "); // 2016-11-06 01:59:59 ///この結果は間違っています、02:00:00 ChangeZone(" 2016-11-6 14:00:00:00 "、" prc "、" America/new_york "、" yyyy-mm-dd hh:ss ");実装は次のとおりです。//アイデアは、public static void changezone(string time、string srcid、string destid、string pattern)をスローするparseexception {//デフォルトのタイムゾーンタイムゾーンゾーン= timezone.gettimezone(srcid); timezone.setDefault(ゾーン);日付date = new simpledateFormat(pattern).parse(time); //ターゲットタイムゾーンタイムゾーンDestzone = TimeZone.GetTimeZone(Destid)を設定します。 SimpleDateFormat sdf = new SimpledateFormat(パターン); //タイムゾーンをフォーマットするSDF.SettimeZone(Destzone)を設定します。文字列changtime = sdf.format(date); //ターゲットタイムゾーンSystem.out.printlnを取得します( "タイムゾーンの変更後" + destzone.getId() + "time:" + changtime); }概要:上記の3つの実装方法で得られた結果は、夏時間の時間にやや問題があります
3、Java8実装
1。最初にJava 8のタイムゾーンの変更を見てみましょう
// JDK8の使用可能なタイムゾーン@testpublic void testname1()スロー例外{// jdk8のすべてのタイムゾーンセット<string> ids =ゾーンId.getavailablezoneids(); string [] id1 = ids.toarray(new string [ids.size()]; string ids = arrays.tostring(id1).。 "、]"); system.out.println(ids.size()); // 28 Jdk8のstringの前の時間ゾーン[] id2 = timezone.getavailableids(); system.out.println(id2.length); // 623 // for(string id:id2){if(!idss.contains(id+"、")){system.out.print(id+"、");}} //結論:jdk8のすべてのタイムゾーンはすべて削除されています// jdk8として:// AGT、ART、AST、BET、BST、CAT、CNT、CST、CTT、EAT、ET、ECT、IET、IST、JST、MIT、NET、NST、PLT、PNT、PRT、PST、SST、VST、// localDateTime.ofinstant(instant.now()、zoenid.of(zonid.short_ids.get( "pst"))); system.out.println( "/ndate =" + date);}2。タイムゾーン情報を追加する方法、または変換する方法
// localdate、localdateTime、インスタント追加タイムゾーン情報@testpublic void testname3(){localdate date = localdate.now(); // localdate add timeゾーン情報//方法1zoneddatimeゾーン= date.atstartofday(ゾーンディードdate.atstartofday(Zoneid.systemDefault()); System.out.println(ゾーン); //方法2 localdate date2 = LocalDate.now(ZoneId.of("GMT+0"));System.out.println(date2);System.out.println("----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Zoneime3 = localdateTime.now(clock.system(ゾーン+0 ")); System.out.println(zonetime3); // change System.out.println(zonetime4); // change System.out.println("----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------3.現在の時間の指定された時間を取得する方法(テスト省略)
//現在の時刻の指定されたタイムゾーンを取得します。基準点:0タイムゾーンpublic localDateTime getCurrentzonetime(Zoneid Dest){objects.Requirenonnull(dest); localDateTime time2 = localdateTime.now(clock.system(dest)); string zonedesc = getzonedesc(timezone.gettimezone(dest)); system.out.println(dest.getId()+"は標準のタイムゾーンに対応しています:"+zonedesc); System.out.println( "ターゲットタイムゾーン"+dest+"time"+time2.format(datetimeformatter.ofpattern( "yyyy-mm-dd hh:mm:ss")));戻り時間2;} //標準のタイムゾーン、方法1 // JDK8の前のメソッド、TimeZone Private Static String getZonedesc(TimeZone Destzone){objects.Requirenonnull(destzone); int offset = destzone.getRawoffset() /(1000 * 60 * 60); if(offset <= 0){return "gmt"+string.valueof(offset); } else {return "gmt +" + string.valueof(offset); }} // java8メソッド、方法2、zonerulesを使用しますRule.GetStandArdOffset(ZonedDatetime.Now(dest).toinstant())。getId(); string s = standardoffset.split( ":")[0]; int offset = integer.parseint(s); //戻り方法1:時間と数分で//「GMT」+StandardOffsetを返します。 //メソッドを返す方法:(offset> 0){return "gmt+"+offset;} else {return "gmt"+offset;}}の場合にのみ時間のみで4。指定されたタイムゾーンの指定された時間を取得する方法
上記のタイムゾーンの問題の実装を開始します
同様に、まず、Java8を使用した夏時間の判断方法が正しいかどうかを見てみましょう。
//直接手紙を書いて、米国の時間が夏時間であるかどうかを判断しますパブリックブーリアンisdaylighttime(localdateTime a){objects.requirenonnull(a); localDateTime startDate = a.withmonth(3).tolocaldate()。attime(2、0); localdateTime startlightday = startdate.with(tomealadjusters.dayofweekinmonth(2、dayofweek.sunday)); // 11月のlocaldateTime enddate = a.withmonth(11).tolocaldate()。 enddate.with(thipalaladjusters.dayofweekinmonth(1、dayofweek.sunday)) java8既に既製のメソッドがあります。これは、指定された時間とタイムゾーンのパブリックブールIsdaylighttime(localdateTime a、zoenid dest){zoneddateTime z1 = a.atzone(dest); //この方法で転送// zoneddateTime z2 = zoneddateTime.of(a、dest); System.out.println(z1.format(datetimeformatter.ofpattern( "yyyy-mm-dd hh:mm:ss"))); Zonerulesルール= dest.getrules(); boolean flag = rules.isdaylightsavings(z1.toinstant()); system.out.println(flag); return flag; }//それをテストすると、Java8の夏時間の節約方法が完全に正しいことがわかりました
// 2016:America/New_Yorkの夏時間は2016-3-13 02:00:00から2016-11-06 01:59:59 //(3月の第2日曜日と11月の第1日曜日)@testpublic void testname()Throws Exception {// LocalDateTime A1 = LocalDateTime.Now(); localDateTime a2 = localdateTime.of(2016、3、13、1、59,59); localDateTime a3 = localdateTime.of(2016、3、13、2、00); localdatime a4 = localdateTime.of(2016、11、6、1、59,59); localdatime a5 = localdateTime.of(2016、11、6、2、 0,0); // isdaylighttime(a2); // isdaylighttime(a3); // isdaylighttime(a4); // isdaylighttime(a5); system.out.println( "===================================================== ============================================================================== =========================================================================== =========================================================================== =========================================================================== =========================================================================== =========================================================================== ); // falseIsdaylighttime(a3、zoenid.of( "americ/new_york")); // trueisdaylighttime(a4、zoenid.of( "America/new_york"));実装を開始します:
バージョン1:
//指定された時間の指定されたタイム参照ポイントを取得します。 getzongtime(time、null、dest)を返します。 }
// 2つのタイムゾーンのZonedDateTimeから減算することはできません。ここでタイムゾーンを指定すると、その時間はこのタイムゾーンであるため、このタイムゾーンはPublic DateTime GetzongTime(localDateTime Time、Zoneid SRC、Zoneid Dest)です。これはおそらくObjects.Requirenonnull(dest)により適しています。 ZonedDateTime Z1 = null; if(src == null){z1 = time.atzone(Zoneid.systemDefault()); } else {z1 = time.atzone(src); } //タイムゾーンの応答時間の変化zoneddatime z2 = z1.withzonesameinstant(dest); System.out.println(dest.getId()+"は標準タイムゾーンに対応します。 System.out.println( "ターゲットタイムゾーン"+dest+"time"+z2.format(datetimeformatter.ofpattern( "yyyy-mm-dd hh:mm:ss"))); System.out.println( "-----------------");返品時間; }テストは次のとおりです。
@test public void test6()スロー例外{//夏時間にはないと予想されます。 getzongtime(time4、Zoneid.of( "America/new_york")); //夏時間を節約することが期待されていますgetzongtime(time1、Zoneid.of( "America/new_york")); //夏時間での予想される結果時間:2016-11-06 01:59:59 //再び失敗したと感じています。つまり、Java8が夏時間の終わりを処理する前の方法は、2016-59:59 //この時間は、この時間と同じです。 00:59:59ですが、Java8の判断方法は正しいです。少し奇妙ではありませんか?2 = localdateTime.of(2016、11、6、14、59、59) getzongtime(time2、zoenid.of( "America/new_york")); //夏時間を節約することは期待されていませんgetzongtime(time3、zoenid.of( "America/new_york")); }それで、この結果が体系的な計算の問題であるかどうか、またはニューヨークの習慣を理解していないのか、私は今、私は今疑っていますか?
しかし、私はまだ私が望む結果を得ることができます、2つの方法を使用します:
withearlieloffsetAtoverlap()、withlateroffsetAtoverlap()
バージョン2:
//指定された時間の指定されたタイム参照ポイントを取得:デフォルトタイムゾーンパブリックlocalDateTime getzongtime2(localdateTime time、ゾーンディッドdest){objects.requirenonnull(dest); return getzongtime2(time、null、);} //バージョン2パブリックローカルダテティムgetzongtime2オフセット//デフォルトのタイムゾーンはここで、中国では米国で使用されているため、米国は米国であるため、おそらくオブジェクトに適しています。requirenonnull(dest); ZonedDateTime Z1 = null; if(src == null){z1 = time.atzone(Zoneid.systemDefault()); } else {z1 = time.atzone(src); } // zoneddateTime z2 = z1.withzonesameinstant(dest); //長時間の重複する問題を処理します= duration.between(z2.withearoffsetAtoverlap()、z2.withlateroffsetaToverlap())。tohours(); z2 = z2.plushours(hours); System.out.println(dest.getId()+"は標準タイムゾーンに対応します。 System.out.println( "ターゲットタイムゾーン"+dest+"time"+z2.format(datetimeformatter.ofpattern( "yyyy-mm-dd hh:mm:ss"))); System.out.println( "-----------------");返品時間;}テスト:わかりました
@test public void test4()スロー例外{//夏時間にはないと予想されます。 getZongTime2(Time4、Zoneid.of( "America/new_york")); //夏時間を節約することが期待されていますgetZongTime2(Time1、Zoneid.of( "America/new_york")); //夏時間は2016-11-06 02:59:59 LocalDateTime Time2 = localDateTime.of(2016、11、6、14、59、59); getzongtime2(time2、zoenid.of( "America/new_york")); //夏時間ではない2016-11-06 02:00:00 LocalDateTime Time3 = LocalDateTime.of(2016、11、6、15、00、00); getZongTime2(Time3、Zoneid.of( "America/new_york")); }結果:
America/New_Yorkは、標準のタイムゾーン:GMT-5に対応しています
ターゲットタイムゾーンアメリカ/new_york 2016-03-13 01:59:59の時間
--------------------------
America/New_Yorkは、標準のタイムゾーン:GMT-5に対応しています
ターゲットタイムゾーンアメリカ/new_york 2016-03-13 03:00:00の時間
--------------------------
America/New_Yorkは、標準のタイムゾーン:GMT-5に対応しています
ターゲットタイムゾーンアメリカ/new_york 2016-11-06 02:59:59の時間
--------------------------
America/New_Yorkは、標準のタイムゾーン:GMT-5に対応しています
ターゲットタイムゾーンアメリカ/new_york 2016-11-06 02:00:00の時間
--------------------------
Javaタイムゾーンに基づいて夏時間を変換する上記の問題と解決策は、私があなたと共有するすべてのコンテンツです。参照を提供できることを願っています。wulin.comをもっとサポートできることを願っています。