Javaず時間パヌト1

8幎前、私は䞖界䞭のナヌザヌのニヌズに応え、それらの行動を調敎するこずになっおいるサヌビスの蚭蚈ず開発に参加したした。 プロゞェクトに取り組んでいる間、私は非垞に倚くの堎合、䜜業の倚くの重芁な偎面が時間の経過ずずもに単に無芖されるこずに気付きたした。 サヌビスがロヌカルで特定の地域でのみ䜿甚されおいる堎合、たたはナヌザヌが自然にほずんど盞互䜜甚しない地理的クラスタヌに分割されおいる堎合、これは実際にはそれほど重芁ではありたせん。 ただし、サヌビスが䞖界䞭のナヌザヌを結び付けおいる堎合、仕事の原則を明確に理解しないず、時間をかけおやるこずはできたせん。 䞀般的なむベント䌚議などが厳密に定矩された時間に始たり、ナヌザヌがそれを頌りにするサヌビスを想像しおください。 い぀それらを衚瀺するか、どの時点で通知に悩たされるべきか、圌らの誕生日は䜕であるか、そしおい぀あなたが人を祝犏するこずができるか-蚘事でこれを理解しようずしたす。







この蚘事は、深みがある、たたは孊術的であるず䞻匵しおいたせん。 これは、経隓を䜓系化し、開発者の泚意をあたり明癜でない偎面に向けようずする詊みです。







新しいDate Time APIが JDK8に登堎したした。このAPIには 、倚くの新しい䟿利なクラスが登堎したしたが 、 優れたサヌドパヌティラむブラリに぀いおは蚀及したせん。 これは、別の蚘事に倀する別の倧きなトピックです。 さらに、既に述べたように、特定の技術に぀いおではなく、党䜓ずしおの䜜業の原則に぀いおお話ししようずしおいたす。この点で、新しいAPIは基本的に叀いものず倉わりたせん。



時間軞





遠くから始めたしょう。 ずおも遠い。 時間軞を描きたす。







ここからさたざたな質問が始たりたす。 時間は垞に同じ方向に進みたすか 均等に行きたすか 連続ですか 単䜍ベクトルずしお䜕を取りたすか この軞はすべお同じですか 空間内の䜍眮に䟝存したすか 動きの速さから 最小枬定長は䜕ですか



実際、ここで私は質問をする準備ができおいるだけで、決しお答えたせん。 時間がないず信じられおいたすが 、私はこの問題に぀いお議論する準備もできおいたせん。



しかし、すでに解決されたポむントがありたす。



枬定単䜍に぀いおはすべお明らかです。明確か぀明確に指定されおいたす。



モスクワからワシントンたでの距離は玄7840000メヌトルで、光はこの距離を少なくずも0.026秒で地衚䞊を移動したす。これは非垞に長い時間です。 りラゞオストクでナヌザヌアカりントを䜜成するリク゚ストは、しばらくしおからモスクワサヌバヌで凊理されたす。 したがっお、発生したむベントに関する情報はすぐには利甚できず、空間内のポむント間の距離に䟝存したす。



さらに、 GPSのような非垞に普通の近地球テクノロゞヌでも、時間の速床自䜓はオブゞェクトの速床に䟝存したす。



珟圚の暙準Java時間凊理ラむブラリは、盞察論的効果がなく、誰もが光速に近い速床で動くこずはないず考えおおり、時間軞はすべお少なくずも同じ惑星で同じであり、私たち党員に適しおいたす。 おそらく埌で、新しいJava Date Time APIがJDK6543に実装されたす。これにより、 Millennium Falcon内郚オフィスシステム甚のサヌビスを䜜成でき、その速床ず近くのモルホヌルの有無が考慮されたす。



ここで、時間軞䞊の特定の瞬間をマヌクしたす。 たずえば、今はドットボタンをクリックしたす。 クリック







次に、このボタンを抌した正確なタむミングを説明できる方法を考え出す必芁がありたす。 これを行う最も簡単な方法は、私たち党員に共通の時点を指定するこずです。この時点から、垞に時間サンプルをカりントしたす。 この瞬間が瀺されおいる堎合 その同じ瞬間 、この䞀般的な瞬間からのサンプルの数を送信するこずができたす。ボタンが抌された時間ず、倀を取埗したずきの珟圚の時間ずの関係を理解できたす。



原始的な物理䞖界では、同じ砂時蚈に出䌚っお同時に走るこずができたした。 その埌、萜ち着いおあなたのビゞネスを調べ、むベントの時間をりォッチむンスタンスの砂柱の高さの圢で報告したすおそらく、りォッチは非垞に倧きくおかさばるはずです。







私たちが䜿甚する同じモヌメントは 、次元でもありえたすが、より䞀般的で重芁なむベントに関しおです。 私たちの堎合、これはJavaで䜿甚されるUnixタむムシステム 数倀0で同じ瞬間に起こりたす-これは、1970幎1月1日のR.Khから00:00:00ずラベル付けされた時点です。 UTCはすでに別のスケヌル- グレゎリオ暊です。



Javaはそれず䜕の関係があるのか





Javaの時間軞に時刻を蚭定するために、クラスjava.util.Dateがありたす。 䞀般に、java.util.Dateは、最も初期のバヌゞョンからのJavaの恥です。 たず、圌の名前は本質を反映しおいたせん。 そしお第二に、圌は可倉です。 ただし、 その同じ瞬間からのミリ秒数を栌玍するlong型の内郚フィヌルドの単玔なラッパヌずしお認識するず、人生はより単玔になりたす-それ以䞊は䜕もありたせん。 他のすべおのメ゜ッドは廃止されたものずしおマヌクされおおり、どのような堎合でもそれらを䜿甚する必芁はありたせん。 java.utl.Dateは本質的にミリ秒単䜍の単玔な長いUnix時間の数倀ず同䞀であるこずを芚えおおいおください。



Date moment = new Date(1451665447567L); //    Unix-time  -- moment.getTime(); //    Unix-time  --.
      
      







少し考えおみるず、どの蚀語でも時間衚珟の粟床に制限があるこずが明らかになりたす。 したがっお、java.util.Dateは他の類䌌タむプず同様に時間軞䞊のポむントではなく、セグメントです。 私たちの堎合、ミリ秒の持続時間のセグメント。 しかし、実甚的な芳点からは、このような粟床は私たちに適しおいるため、これをポむントず呌び続けたす。



Javaの衚珟は最初から64ビットなので、確かに十分なものがありたす

私たちに十分
 Date theEnd = new Date(Long.MAX_VALUE); DateFormat dateFormat = SimpleDateFormat.getDateTimeInstance(SimpleDateFormat.LONG, SimpleDateFormat.LONG); dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); String text = dateFormat.format(theEnd); System.out.println(text); # August 17, 292278994 7:12:55 AM UTC
      
      









個々のカレンダヌフィヌルド幎、月、日、時間、分、秒などの読み取り/蚭定/倉曎など、時間に関するさたざたな操䜜には、クラスjava.util.Calendarがありたす。 たた、眪がないわけではありたせん-操䜜䞭、月は0から始たり定数を䜿甚する方が良い、日は1から始たるこずに泚意しおください。

java.util.Calendar
  @Test public void testSunday() throws Exception { Calendar calendar = Calendar.getInstance(); calendar.setTimeZone(TimeZone.getTimeZone("UTC")); calendar.set(2016, Calendar.JANUARY, 5, 12, 30, 0); calendar.add(Calendar.DAY_OF_YEAR, -2); Assert.assertEquals(Calendar.SUNDAY, calendar.get(Calendar.DAY_OF_WEEK)); }
      
      









java.util.Calendarのもう䞀぀の濁った瞬間は、その䞭に完党な日付yyyy、MM、dd、HH、mm、ssを蚭定するず、ミリ秒の数は0にリセットされず、前の蚭定された瞬間からのミリ秒の数に等しいたたですカレンダヌが倉曎されおいない堎合は珟圚の時刻。 したがっお、タスクの条件に埓っおミリ秒単䜍で0が必芁な堎合、このフィヌルドはもう1回远加の呌び出しでリセットする必芁がありたす。

java.util.Calendar
  @Test public void testCalendarMs() throws Exception { TimeZone tz = TimeZone.getTimeZone("Europe/Moscow"); Calendar calendar = Calendar.getInstance(tz); calendar.setLenient(false); calendar.set(2016, Calendar.APRIL, 20, 12, 0, 0); System.out.println(calendar.getTimeInMillis()); calendar.set(Calendar.MILLISECOND, 0); System.out.println(calendar.getTimeInMillis()); }
      
      





 1461142800808
 1461142800000






最初の番号は、呌び出しの時間に応じお、最初の3桁になりたす。 この動䜜は、テストでは非垞に重芁です。



タむムスタンプを軞䞊のポむントに、たたはその逆に倉換するために、クラスjava.text.DateFormatずその子孫がありたす。

java.text.DateFormat
  @Test public void testFormat() throws Exception { TimeZone tz = TimeZone.getTimeZone("Europe/Moscow"); DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); dateFormat.setLenient(false); dateFormat.setTimeZone(tz); Date moment = dateFormat.parse("2005-03-27 01:30:00"); Assert.assertEquals("2005-03-27 01:30:00", dateFormat.format(moment)); }
      
      









java.text.DateFormatおよびjava.util.Calendarに぀いおは、次のこずを明確に蚀う必芁がありたす。





叀いIPAにはさらにいく぀かのクラスがありたす

java.sql.Timestamp-デヌタベヌスのTIMESTAMP型を操䜜するためのナノ秒粟床のjava.util.Dateの拡匵サブクラス

java.sql.Date-デヌタベヌスのDATE型を操䜜するためのjava.util.Dateの拡匵サブクラス。

java.sql.Time-デヌタベヌスのTIME型を操䜜するためのjava.util.Dateの拡匵サブクラス。





さらに、任意の時点を、ミリ秒単䜍の通垞のUnix時間の長い倀ずしお保存できたす。



タむムゟヌン





䞖界䞭たたはロシア党䜓に倚くのオフィスを持぀グロヌバル䌁業で働いた経隓のある人なら誰でも、「䌚議は2016幎1月1日14:00:00に開催されたす」ずいうフレヌズに含たれる情報は事実䞊圹に立たないこずを知っおいたす。 「14:00」ずいうマヌクは、時間軞䞊の特定のポむントに察応するものではなく、耇数のポむントに察応するものです。 党員が同時にビデオチャットルヌムに集たるようにするために、䌚議の䞻催者は別の䜕か、぀たり「14:00」マヌクを解釈するタむムゟヌンを指定する必芁がありたす。 倚くの堎合、タむムゟヌンは本郚本郚によっお暗瀺されたす「モスクワ時間に埓っお䜜業する」。そうでない堎合、デフォルトのタむムゟヌンがたったく暗瀺されない堎合は、「2016幎1月1日14:00に」明瀺的に蚭定する必芁がありたす00 MSK ''-この堎合、時間軞䞊のポむントは完党に明確に蚭定され、党​​員が同時に䌚議に集たりたす。



HHMMCC圢匏のタむムスタンプを䜿甚した操䜜のあいたいさを排陀するには、タむムスタンプの衚瀺時ず入力時の䞡方でタむムゟヌンを指定する必芁がありたす。



䜕らかの方法で暗黙的に暗瀺できる堎合、タむムゟヌンを明瀺的に指定するこずはできたせん。





通垞、サヌビスのタむムゟヌンデフォルトずサヌバヌのタむムゟヌンデフォルトは同じではないこずに泚意しおください。 BIOS、システム、アプリケヌション、およびナヌティリティは、たずえば、UTCタむムゟヌンで動䜜できたすが、同時に、サヌビスのタむムゟヌンはモスクワのタむムゟヌンになりたす。 もちろん、䞀臎する堎合ははるかに簡単ですが、この堎合、管理者はサヌバヌにタむムゟヌンを蚭定し、プログラマヌはそれらに぀いおたったく考えたせん。 これがちょうどあなたの堎合であるなら、あなたはこれ以䞊読むこずができたせん。



同じタむムスタンプをさたざたな方法でナヌザヌに衚瀺できたす。誰もが最も䜿い慣れたタむムゟヌンを䜿甚したす。 たずえば、次のタむムスタンプは、時間軞䞊の同じ時点を指したす。

 Fri Jan 1 16:29:00 MSK 2016 Fri Jan 1 13:29:00 UTC 2016 Fri Jan 1 14:29:00 CET 2016 Fri Jan 1 21:29:00 SGT 2016 Fri Jan 1 22:29:00 JST 2016
      
      







タむムゟヌンに関するりィキペディア 。



Javaでは、タむムゟヌン情報はjava.util.TimeZoneクラスで衚されたす。



タむムゟヌンはオフセットではないず蚀わなければなりたせん。 これは、GMT + 3がペヌロッパ/モスクワであるず蚀っおいるわけではありたせん。 しかし、2016幎党䜓で、タむムゟヌンペヌロッパ/モスクワはGMT + 3オフセットに察応するず蚀えたす。 タむムゟヌンは、履歎期間党䜓の倉䜍の完党な履歎、およびさたざたな過去の瞬間の倉䜍を正確に蚈算し、正しい時間蚈算を行うこずができる他のデヌタです。



タむムゟヌンを調べおみたしょう-最初にペヌロッパ/モスクワを芋おみたしょう

ペヌロッパ/モスクワ
  @Test public void testTzMoscow() throws Exception { TimeZone tz = TimeZone.getTimeZone("Europe/Moscow"); System.out.println(tz.getRawOffset()); System.out.println(tz.getOffset(System.currentTimeMillis())); System.out.println(tz.useDaylightTime()); System.out.println(tz.getDisplayName(false, TimeZone.LONG, Locale.ENGLISH)); System.out.println(tz.getDisplayName(false, TimeZone.SHORT, Locale.ENGLISH)); System.out.println(tz.getDisplayName(true, TimeZone.LONG, Locale.ENGLISH)); System.out.println(tz.getDisplayName(true, TimeZone.SHORT, Locale.ENGLISH)); System.out.println(tz.getDisplayName(false, TimeZone.LONG, Locale.FRENCH)); System.out.println(tz.getDisplayName(false, TimeZone.SHORT, Locale.FRENCH)); System.out.println(tz.getDisplayName(true, TimeZone.LONG, Locale.FRENCH)); System.out.println(tz.getDisplayName(true, TimeZone.SHORT, Locale.FRENCH)); }
      
      





 10,800,000
 10,800,000
停
モスクワ暙準時
 Msk
モスクワ倏時間
 Msd
 Heure Standard de moscou
 Msk
 Heureavancéede moscou
 Msd






ペヌロッパ/モスクワゟヌンでは、珟圚のベヌスオフセットがUTCに察しお+3時間であり、珟時点での合蚈オフセットも+3時間であるこずがわかりたす。 将来、倏時間の矢印の翻蚳はありたせん。 ゟヌンには、倏時間ず冬時間の別々の名前がありたす。



パリの時間を芋おみたしょう。

ペヌロッパ/パリ
  @Test public void testTzParis() throws Exception { TimeZone tz = TimeZone.getTimeZone("Europe/Paris"); System.out.println(tz.getRawOffset()); System.out.println(tz.getOffset(System.currentTimeMillis())); System.out.println(tz.useDaylightTime()); System.out.println(tz.getDisplayName(false, TimeZone.LONG, Locale.ENGLISH)); System.out.println(tz.getDisplayName(false, TimeZone.SHORT, Locale.ENGLISH)); System.out.println(tz.getDisplayName(true, TimeZone.LONG, Locale.ENGLISH)); System.out.println(tz.getDisplayName(true, TimeZone.SHORT, Locale.ENGLISH)); System.out.println(tz.getDisplayName(false, TimeZone.LONG, Locale.FRENCH)); System.out.println(tz.getDisplayName(false, TimeZone.SHORT, Locale.FRENCH)); System.out.println(tz.getDisplayName(true, TimeZone.LONG, Locale.FRENCH)); System.out.println(tz.getDisplayName(true, TimeZone.SHORT, Locale.FRENCH)); }
      
      





 3,600,000
 3,600,000
本圓
䞭倮ペヌロッパ時間
セト
䞭倮ペヌロッパ倏時間
セスト
䞭倮ペヌロッパ
セト
ペヌロッパの䞭倮駅
セスト






ベヌスオフセットはUTCに察しお+1時間で、珟圚の合蚈オフセットも+1時間です。 ゟヌンの将来の倏時間ぞの移行。 冬ず倏時間に別々に、2぀の名前も割り圓おられたす。



次に、ゟヌン「GMT + 5」を芋おみたしょう。 これは実際には䞀時的なゟヌンではありたせん-歎史も倏時間もないし、シフトは䞀定です。

GMT + 5
  @Test public void testGmt5() throws Exception { TimeZone tz = TimeZone.getTimeZone("GMT+5"); System.out.println(tz.getRawOffset()); System.out.println(tz.getOffset(System.currentTimeMillis())); System.out.println(tz.useDaylightTime()); System.out.println(tz.getDisplayName(false, TimeZone.LONG, Locale.ENGLISH)); System.out.println(tz.getDisplayName(false, TimeZone.SHORT, Locale.ENGLISH)); System.out.println(tz.getDisplayName(true, TimeZone.LONG, Locale.ENGLISH)); System.out.println(tz.getDisplayName(true, TimeZone.SHORT, Locale.ENGLISH)); System.out.println(tz.getDisplayName(false, TimeZone.LONG, Locale.FRENCH)); System.out.println(tz.getDisplayName(false, TimeZone.SHORT, Locale.FRENCH)); System.out.println(tz.getDisplayName(true, TimeZone.LONG, Locale.FRENCH)); System.out.println(tz.getDisplayName(true, TimeZone.SHORT, Locale.FRENCH)); }
      
      





 18,000,000
 18,000,000
停
 GMT + 0500
 GMT + 0500
 GMT + 0500
 GMT + 0500
 GMT + 0500
 GMT + 0500
 GMT + 0500
 GMT + 0500






぀たり、バむアスは䞀定で、GMTず比范しお+5時間であり、倉化するこずはありたせん。



䟋





私たちは蚀葉で説明するには長すぎるものを䟋で語り続けたす。 たず、2005幎に「ペヌロッパ/モスクワ」のタむムゟヌンで䜕が起こったのかを芋おみたしょう。

ペヌロッパ/モスクワ-2005
 $ zdump -v /usr/share/zoneinfo/Europe/Moscow | grep 2005 /usr/share/zoneinfo/Europe/Moscow Sat Mar 26 22:59:59 2005 UT = Sun Mar 27 01:59:59 2005 MSK isdst=0 gmtoff=10800 /usr/share/zoneinfo/Europe/Moscow Sat Mar 26 23:00:00 2005 UT = Sun Mar 27 03:00:00 2005 MSD isdst=1 gmtoff=14400 /usr/share/zoneinfo/Europe/Moscow Sat Oct 29 22:59:59 2005 UT = Sun Oct 30 02:59:59 2005 MSD isdst=1 gmtoff=14400 /usr/share/zoneinfo/Europe/Moscow Sat Oct 29 23:00:00 2005 UT = Sun Oct 30 02:00:00 2005 MSK isdst=0 gmtoff=10800
      
      









さお、手が倏に動き、冬に戻るのがわかりたす。 タむムスタンプでこれらの時間に䜕が起こるか芋おみたしょう。 手始めに-冬時間ぞの移行

冬時間
  @Test public void testWinterTime() throws Exception { TimeZone tz = TimeZone.getTimeZone("Europe/Moscow"); DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z"); dateFormat.setLenient(false); dateFormat.setTimeZone(tz); Calendar calendar = Calendar.getInstance(); calendar.setLenient(false); calendar.setTimeZone(TimeZone.getTimeZone("UTC")); calendar.set(2005, Calendar.OCTOBER, 29, 22, 0, 0); for (int i = 0; i < 62; i++) { String mark = dateFormat.format(calendar.getTime()); System.out.printf("%s - %d, %s\n", mark, tz.getOffset(calendar.getTimeInMillis()), tz.inDaylightTime(calendar.getTime())); calendar.add(Calendar.MINUTE, +1); } }
      
      





 2005-10-30 02:00:00 MSD-14400000、true
 2005-10-30 02:01:00 MSD-14400000、true
 ...
 2005-10-30 02:58:00 MSD-14400000、true
 2005-10-30 02:59:00 MSD-14400000、true
 2005-10-30 02:00:00 MSK-10,800,000、false
 2005-10-30 02:01:00 MSK-10,800,000、false






02:59:00 MSD埌、矢印は1時間戻り、次のマヌクはすでに02:00:00 MSK-冬時間です。 タむムゟヌンは、倏時間が終了し、オフセットがGMT + 4からGMT + 3に倉曎されたこずも瀺したす。



この䟋には興味深いニュアンスがありたす。ペヌロッパ/モスクワゟヌンを䜿甚する堎合、020000 MSDマヌクに察応するカレンダヌ䞊のポむントを蚭定するこずは絶察に䞍可胜です。ポむントは必芁な1時間埌の02:00:00 MSKに蚭定されたす。 このポむントを参照ポむントずしお蚭定するには、すべおを蚭定できるUTCタむムゟヌンのサヌビスに頌る必芁がありたす。 別のオプションは、ペヌロッパ/モスクワゟヌンでMSDポむント01:00:00を蚭定し、時間を远加するこずです。



珟圚-倏時間

倏時間
  @Test public void testSummerTime() { TimeZone tz = TimeZone.getTimeZone("Europe/Moscow"); DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z"); dateFormat.setLenient(false); dateFormat.setTimeZone(tz); Calendar calendar = Calendar.getInstance(); calendar.setLenient(false); calendar.setTimeZone(TimeZone.getTimeZone("UTC")); calendar.set(2005, Calendar.MARCH, 26, 22, 0, 0); for (int i = 0; i <= 60; i++) { String mark = dateFormat.format(calendar.getTime()); System.out.printf("%s - %d, %s\n", mark, tz.getOffset(calendar.getTimeInMillis()), tz.inDaylightTime(calendar.getTime())); calendar.add(Calendar.MINUTE, +1); } }
      
      





 2005-03-27 01:00:00 MSK-10,800,000、false
 2005-03-27 01:01:00 MSK-10,800,000、false
 ...
 2005-03-27 01:58:00 MSK-10,800,000、false
 2005-03-27 01:59:00 MSK-10,800,000、停
 2005-03-27 03:00:00 MSD-14400000、true
 2005-03-27 03:00:01 MSD-14400000、true






01:59:00以降、MSKは03:00:00 MSDの盎埌に続きたす。぀たり、針が1時間先に移動したす。 タむムゟヌンは、この時点でオフセットがGMT + 3からGMT + 4に倉化するこずを通知し、倏時間フラグも衚瀺されたす。



しかし、「ペヌロッパ/モスクワ」ゟヌンで「2005-03-27 02:30:00」ずいうラベルを凊理しようずするずどうなりたすか理論的には、そのようなラベルは存圚すべきではありたせんか

存圚しないラベル
  @Test public void testMissing() throws Exception { TimeZone tz = TimeZone.getTimeZone("Europe/Moscow"); DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); dateFormat.setLenient(false); dateFormat.setTimeZone(tz); Date moment = dateFormat.parse("2005-03-27 02:30:00"); System.out.println(moment); }
      
      





 java.text.ParseException解析䞍胜な日付 "2005-03-27 02:30:00"






そうです-厳栌モヌドでは䟋倖が発生したす。



手が冬時間に切り替わった日の1日の継続時間を蚈算したす。

冬時間の倉換
  @Test public void testWinterDay() { TimeZone tz = TimeZone.getTimeZone("Europe/Moscow"); Calendar calendar = Calendar.getInstance(); calendar.setLenient(false); calendar.setTimeZone(tz); calendar.set(2005, Calendar.OCTOBER, 30, 0, 0, 0); Date time1 = calendar.getTime(); calendar.add(Calendar.DAY_OF_YEAR, +1); Date time2 = calendar.getTime(); System.out.println(TimeUnit.MILLISECONDS.toHours(time2.getTime() - time1.getTime())); }
      
      





 25






2005-10-30 00:00:00 MSDから2005-10-31 00:00:00 MSKたで、24時間ではなく25時間が経過したした。



次に、倏時間を確認したす。

倏時間
  @Test public void testSummerDay() { TimeZone tz = TimeZone.getTimeZone("Europe/Moscow"); Calendar calendar = Calendar.getInstance(); calendar.setLenient(false); calendar.setTimeZone(tz); calendar.set(2005, Calendar.MARCH, 27, 0, 0, 0); Date time1 = calendar.getTime(); calendar.add(Calendar.DAY_OF_YEAR, +1); Date time2 = calendar.getTime(); System.out.println(TimeUnit.MILLISECONDS.toHours(time2.getTime() - time1.getTime())); }
      
      





 23






2005-03-27 00:00:00 MSKから2005-03-28 00:00:00 MSDたで、24時間ではなく23時間経過したした。



これらの最埌の2぀の䟋は、24 * 60 * 60 * 1000ミリ秒を24時間ではなくカレンダヌ日ずしお远加する人専甚です。 倏時間ず冬時間の乗り換えはもうないので、今はそのような問題はないず蚀えるでしょう。 これに私は以䞋に答えるこずができたす





java.sql.Time、java.sql.Date





型は、それぞれSQL型のTIMEおよびDATEで動䜜するように蚭蚈されおいたす。 䞡方の倀は時間垯に䟝存しないこずが理解されおいたすが、残念ながらこれは完党に真実ではありたせん。 䞡方のタむプはjava.util.Dateの子孫であるため、日数の解釈はタむムゟヌンに䟝存したす。

java.sql型の問題
  @Test public void testSqlTime() throws Exception { //    2015-01-01 01:00:00 MSK Calendar calendar = Calendar.getInstance(); calendar.setTimeZone(TimeZone.getTimeZone("Europe/Moscow")); calendar.setTimeInMillis(0); calendar.set(2015, Calendar.JANUARY, 10, 1, 0, 0); long now = calendar.getTimeInMillis(); //   java.sql.Time java.sql.Time sqlTime = new java.sql.Time(now); java.sql.Date sqlDate = new java.sql.Date(now); //        Europe/London DateFormat timeFormat = new SimpleDateFormat("HH:mm:ss"); timeFormat.setTimeZone(TimeZone.getTimeZone("Europe/London")); Assert.assertEquals("22:00:00", timeFormat.format(sqlTime)); //        Europe/London DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); dateFormat.setTimeZone(TimeZone.getTimeZone("Europe/London")); Assert.assertEquals("2015-01-09", dateFormat.format(sqlDate)); }
      
      









通垞、コヌドは同じタむムゟヌンの䞡方で機胜するため、どちらのタむプもビゞネスロゞックからJDBCドラむバヌに情報を転送するタスクに察凊したすが、シリアル化などのより高床なケヌスでは、これらのクラスを䜿甚する堎合は十分に泚意する必芁がありたす



察応するタむプの新しいAPIでは、このような問題は解決されおいたす。



UTC、GMT





ほずんどの人は、GMTずUTCは他のタむムゟヌンで圢成されるオフセットに関連する特別な指定であるこずを知っおいたす。 しかし、誰もがUTCずGMTがたったく同じものではないこずを知っおいるわけではありたせん 正匏に。 ぀たり、ラベル「2015-12-01 00:00:00 GMT」ず「2015-12-01 00:00:00 UTC」は、時間軞䞊の異なる近いポむントを瀺しおいたす。



GMTは 、他のオブゞェクトに察する地球の䜍眮から倩文孊的に蚈算されたす。 GMTは、䞀郚の囜ではタむムゟヌンずしお盎接䜿甚されたす。



地球の回転はランダムに枛速するため、地球は垞に増加する時間間隔で同じ䜍眮にありたす。 したがっお、隣接するGMTマヌク䞊の時刻ポむント間の距離たずえば、「10:00:01」ず「10:00:02」は1 秒ず正確に䞀臎しない堎合がありたす。



UTCは GMTの代わりに導入され、原子時間で蚈算されたす。 タむムゟヌンずしお盎接䜿甚されるこずはありたせんディスプレむスメントのサポヌトずしおのみ。



UTCでは、タむムスタンプ間の距離たずえば、「10:00:01」ず「10:00:02」はたったく同じで、厳密には1秒に等しくなりたす。 地球の自転の遅れずGMTずの环積的な差は、1幎たたは2秒の䜙分な秒、぀たりうるう秒を入力するこずで解決されたす。



したがっお、GMTずUTCで同じマヌクのあるポむントの差が1秒を超えるこずはありたせん。



圌らは 、UTCがGMTをほが完党に眮き換え、GMT + 3の圢匏でオフセット衚蚘を䜿甚するこずは長らく悪い考えだず曞いおいたす。UTC+ 3衚蚘を䜿甚するのは正しいこずです。



GMTもUTCも倏時間はありたせん。



Javaで䜿甚されるUnix-timeは 、UTCたたはGMTに盎接察応しおいないず蚀わなければなりたせん。 䞀方では、Unix時間では、隣接するラベル間の差は垞に1秒ですが、他方では、Unix時間ではle秒は想定されおいたせん。



デフォルトのタむムゟヌン





出力にタむムゟヌンを明瀺的に衚瀺するか、衚瀺しないか、入力時にタむムゟヌンを芁求するか、時間どおりの操䜜䞭にタむムゟヌンを指定するか指定しないかを芁求したせんかこれらの操䜜には暗黙的に䞀郚のタむムゟヌンが存圚しおいたす。 独自のものを指定しなかった堎合、デフォルトのタむムゟヌンが䜿甚されたす。



デフォルトのタむムゟヌンずいう甚語は、䞊蚘のテキストですでに䜕床か蚀及されおいたす。 なぜなら、この抂念がなければ、実際には䜕も説明できないからです。 タむムスタンプの時間、出力、および入力を䌎うすべおの操䜜にはタむムゟヌンが必芁です。 あなたがそれを指定しないずいう事実は、それがそこにないこずを意味しない-それは単にデフォルトで取られる。



しかし、すべおが再びそれほど単玔ではありたせん-デフォルトでは誰のために、なぜですか



カヌネルから始めたしょう。 hwclockマニュアルでは、カヌネルにはタむムゟヌンの内郚抂念がありたすが、FATファむルシステムドラむバヌのようないく぀かの珍しいモゞュヌルを陀いお、ほずんど誰も䜿甚しおいたせん。 同じhwclockコマンドを䜿甚しお、タむムゟヌンの倉曎に぀いおカヌネルに通知できたす。



アプリケヌションアプリケヌションは、いく぀かの方法でデフォルトのタむムゟヌンを定矩したす。



たず、Ubuntuのシステム党䜓のタむムゟヌンそれに関する完党な情報は、ファむルシンボリックリンク/ etc / localtimeに保存され、このタむムゟヌンの名前はファむル/ etc / timezoneにありたす。

 $ cat /etc/timezone Europe/Moscow $ file /etc/localtime /etc/localtime: timezone data, version 2, 15 gmt time flags, 15 std time flags, no leap seconds, 77 transition times, 15 abbreviation chars $ zdump -v /etc/localtime | head -n 10 /etc/localtime -9223372036854775808 = NULL /etc/localtime -9223372036854689408 = NULL /etc/localtime Wed Dec 31 21:29:42 1879 UT = Wed Dec 31 23:59:59 1879 LMT isdst=0 gmtoff=9017 /etc/localtime Wed Dec 31 21:29:43 1879 UT = Thu Jan 1 00:00:00 1880 MMT isdst=0 gmtoff=9017 /etc/localtime Sun Jul 2 21:29:42 1916 UT = Sun Jul 2 23:59:59 1916 MMT isdst=0 gmtoff=9017 /etc/localtime Sun Jul 2 21:29:43 1916 UT = Mon Jul 3 00:01:02 1916 MMT isdst=0 gmtoff=9079 /etc/localtime Sun Jul 1 20:28:40 1917 UT = Sun Jul 1 22:59:59 1917 MMT isdst=0 gmtoff=9079 /etc/localtime Sun Jul 1 20:28:41 1917 UT = Mon Jul 2 00:00:00 1917 MST isdst=1 gmtoff=12679 /etc/localtime Thu Dec 27 20:28:40 1917 UT = Thu Dec 27 23:59:59 1917 MST isdst=1 gmtoff=12679 /etc/localtime Thu Dec 27 20:28:41 1917 UT = Thu Dec 27 23:00:00 1917 MMT isdst=0 gmtoff=9079
      
      







Ubuntuの堎合、ディストリビュヌション甚の特別なコマンドを䜿甚しおシステムのタむムゟヌンを蚭定できたす。

 $ dpkg-reconfigure tzdata
      
      







ポラむトtzselectナヌティリティもありたす。

 $ tzselect Please identify a location so that time zone rules can be set correctly. Please select a continent, ocean, "coord", or "TZ". 1) Africa 2) Americas 3) Antarctica 4) Arctic Ocean 5) Asia 6) Atlantic Ocean 7) Australia 8) Europe 9) Indian Ocean 10) Pacific Ocean 11) coord - I want to use geographical coordinates. 12) TZ - I want to specify the time zone using the Posix TZ format. #?
      
      







タむムゟヌンを指定する2番目の方法は、環境倉数TZです。この環境倉数では、各プログラムやナヌザヌごずにタむムゟヌンの識別子を個別に指定できたす。



 $ echo $TZ $ date Wed Dec 30 20:18:18 MSK 2015 $ TZ=UTC date Wed Dec 30 17:18:25 UTC 2015 $ TZ=Europe/London date Wed Dec 30 17:18:35 GMT 2015 $ TZ=Europe/Paris date Wed Dec 30 18:18:40 CET 2015
      
      







䞀郚のプログラムでは、蚭定および/たたはコマンドラむン匕数で特定のタむムゟヌンを芁求できたす。

 $ date --utc Fri Jan 1 08:34:36 UTC 2016
      
      







ずころで、時間なしで珟圚のタむムゟヌンのみを衚瀺するように日付を芁求できたす

 $ date +%Z MSK
      
      







しかし、これはlibcでの通垞のプログラム甚であり、Javaプラットフォヌム党䜓がありたす。したがっお、䞊蚘の2぀の可胜性に加えお、さらに2぀ありたす。



JVMを起動する匕数を指定できたす。



 $ cat << EOF | scala -Duser.timezone=Europe/Paris print("%s\n%s\n".format(java.util.TimeZone.getDefault().getID(), new java.util.Date())) EOF ... Europe/Paris Wed Dec 30 19:24:00 CET 2015
      
      







たた、TimeZone.setDefaultTimeZone timeZoneメ゜ッドを䜿甚しお、コヌドでデフォルトのタむムゟヌンを盎接蚭定できたす。

 $ cat << EOF | scala > java.util.TimeZone.setDefault(java.util.TimeZone.getTimeZone("America/Los_Angeles")) > print("%s\n%s\n".format(java.util.TimeZone.getDefault().getID(), new java.util.Date())) > EOF ... America/Los_Angeles Wed Dec 30 10:25:45 PST 2015
      
      







たたは䞀床にすべお

 $ TZ=Europe/London cat << EOF | scala -Duser.timezone=Europe/Paris java.util.TimeZone.setDefault(java.util.TimeZone.getTimeZone("America/Los_Angeles")) print("%s\n%s\n".format(java.util.TimeZone.getDefault().getID(), new java.util.Date())) EOF ... America/Los_Angeles Wed Dec 30 10:37:28 PST 2015
      
      







タむムゟヌンベヌス





さたざたな囜や地域の議員や政府は、倏時間を定期的にオン/オフにしたり、タむムゟヌン間で地域を移動したりするこずさえなく、アむドル状態ではありたせん。そのような倉曎に関するすべおの最新情報をシステムに保持するこずが重芁です。そうしないず、時刻が正しく入力および衚瀺されず、睡眠䞭にSMSが受信され、「+ 2暊日」などの蚈算が正しくなくなりたす。



Linuxでは、通垞のlibcプログラムは/ usr / share / zoneinfoディレクトリ内のファむルで構成されるタむムゟヌンデヌタベヌスを䜿甚したす。これらのファむルはtzdataパッケヌゞに属し、各ディストリビュヌションの開発者が積極的に監芖しおいたす。このパッケヌゞはタむムリヌに曎新されたすが、問題は芚えおいたせん。最埌の手段ずしお、デプロむされたバヌゞョンのLinuxが誰でもサポヌトされなくなった堎合、すべおの情報を手動で曎新できたす。



幞いなこずに、これらのファむルのコンテンツの圢匏や、それらの発生の履歎をここで描く必芁はありたせん-Habréには既にこのトピックに関する優れた蚘事があるからです。Wikipediaにも優れた蚘事がありたす。



しかし、それほど単玔ではありたせん。



Javaは独自のタむムゟヌンデヌタベヌスを䜿甚したす。そしお、原則ずしおOpenJDKのため、堎合は、単玔に、簡単にパッケヌゞのtzdata-javaの定期的なパッケヌゞマネヌゞャをアップグレヌドするこずができ、その埌、OracleのJDKのいずれかにする必芁がありたすアップグレヌドするたったく新しいバヌゞョンに党䜓JDKをたたは別の䜿甚特別なナヌティリティをむンストヌルJDKのタむムゟヌンのデヌタベヌスを曎新したす。



ずころで、䞊蚘のJoda-timeラむブラリはtzdataシステムデヌタベヌスもJVMデヌタベヌスも䜿甚しおいたせん-はい、内郚タむムゟヌンデヌタベヌスがもう1぀ありたすが、これも個別の方法で曎新する必芁がありたす。



pythonの堎合、別個のラむブラリをむンストヌルする必芁がありたすそしお、忘れずに曎新する必芁がありたす。



javascriptにはいく぀かのサヌドパヌティラむブラリがありたすが、少なくずもGoogle Closureでサポヌトされおいるこずを正確に芚えおいたす。



䞀般に、特定の゜フトりェアがタむムゟヌンを䜿甚しお個人甚デヌタ​​ベヌスを䜿甚するずいうテヌマは、定期的に衚瀺されたす。たずえば、Thunderbird電子メヌルクラむアントのLightningカレンダヌモゞュヌルは、個人のsqliteデヌタベヌスをタむムゟヌンず共に保存するため、状態の最新の倉曎に䌎い、調敎のためにこのデヌタベヌスに盎接介入する必芁がありたした。そうでなければ、すべおの䌚議は時間通りに出航したした。



䞀般に、開発者の倧郚分は私のような偏執病に悩たされおおらず、タむムゟヌンに぀いお誰も考えおおらず、tzdataプラットフォヌムの基本的な配信に誰も含たれおいないず感じおいたすJVM開発者を陀く。



Androidに぀いお別の蚀葉を蚀いたいです。簡単に説明したす-Androidタむムゟヌンは苊痛です。プラットフォヌムを開発する際に、別のtzdata曎新メカニズムに぀いお、たたは䞖界䞭の議員がひどい倉化を䌎うずいう事実に぀いおは誰も考えたせんでした誰が考えおいたでしょうか。タむムゟヌンのあるデヌタベヌスは、ファヌムりェアベンダヌが必芁ずする堎合にのみ倉曎されたす。䞀郚のベンダヌが6か月埌に自分の電話を認識しなくなるこずを考えるず、tzdataは倚くのデバむスで曎新されるこずはありたせん。䞊玚ナヌザヌは、デバむスの珟圚のタむムゟヌンを、珟圚の状況に倚少応じお別のタむムゟヌンに倉曎したすたずえば、ペヌロッパ/モスクワではなくペヌロッパ/ミンスク。䞊玚ナヌザヌはただペヌロッパ/モスクワGMT + 4に䜏んでおり、単に矢印を回すだけです。その結果、すべおのプログラムのむベントのタむムスタンプは1時間前に倉曎されたす。もちろん、サヌドパヌティの曎新゜リュヌションをルヌト化および䜿甚するオプションがありたすが、すべおのナヌザヌにルヌト電話を匷制するこずはできたせん。







. . , , , , , .



, , -. — . そしお、私たちは皆、私たちのカレンダヌが倚くの1぀であり、おそらく最もよく䜿甚されおいるずは考えおいたせんが、それだけではありたせん。ここで遊ぶこずができたす。



うるう幎





うるう幎は、通垞の幎のように365日ではなく、366日である幎です。うるう幎では、2月-2月29日に1日が远加されたす。



うるう幎は単玔であり、Wikipediaで説明されおいるこずを刀断するための匏



うるう秒





しかし、䜙分な秒調敎の秒があれば、すべおがより耇雑になりたす。プロセスの本質は、地球が絶えずわずかに枛速しおおり、同じ時間のマヌクに沿った星に察するその䜍眮が絶えず倉化しおいるこずです。修正しないず、昌ず倜の時刻が垞に倉わりたす。これを防ぐために、科孊者は地球の䜍眮を远跡し、必芁な補正を蚈算しお調敎蚈画に远加したす。枛速プロセスは無秩序であるため、長期的な修正蚈画を立おるこずは䞍可胜です。修正の2番目を入力する必芁性の刀断は、珟圚の状況に応じお行われたす。地球が突然逆に加速した堎合に備えお、調敎のマむナスの秒を入力するこずも理論的には可胜です。



1秒の調敎が存圚する堎合、UTCの時間は60秒の到来ずずもに流れるこずが理解されたす。

 23:59:58 23:59:59 23:59:60 # leap second 00:00:00 00:00:01
      
      







Unix時間の抂念では、 60秒の秒の抂念はありたせん。「うるう秒を凊理しないため、時間の線圢衚珟でもUTCの真の衚珟でもありたせん。」



少なくずも䜕らかの方法でUTCの時間に察応するため時刻を1秒から深倜に戻すにはトリックが䜿甚されたす。

 23:59:58 23:59:59 23:59:59 # leap second 00:00:00 00:00:01
      
      







トリックが行われ、ファむルのタむムゟヌンのデヌタに基づいお、カヌネルによっお自埋的に正確なタむムサヌビスのいずれかによっお、たたは。



これは吊定的な結果をもたらすハックです。





Javaでは、垞にUnix時間の抂念に関連付けられおいるため、うるう秒の考慮もありたせん。叀いAPIにも、新しいAPIにも、Joda-timeラむブラリにもありたせん。この堎合、情報自䜓は、うるう秒のtzdataの塩基皋床であるが、この方法にはJavaDoc java.util.DategetSecondsは、仮説のJavaマシンフィヌルド倀秒60あるいは61に蚭定するこずができるいく぀かのもの、ただ存圚しないず述べ。



たず、第二を考慮しおいない、うるう秒のJavaクラスの瞬間であるこずを確認しおください。

叀いAPI
  @Test public void testLeapSecond1() throws Exception { TimeZone tz = TimeZone.getTimeZone("UTC"); Calendar calendar = Calendar.getInstance(); calendar.setLenient(false); calendar.setTimeZone(tz); calendar.set(2015, Calendar.JUNE, 30, 23, 59, 0); Date d1 = calendar.getTime(); calendar.set(2015, Calendar.JULY, 1, 0, 1, 0); Date d2 = calendar.getTime(); long elapsed = d2.getTime() - d1.getTime(); System.out.println(TimeUnit.MILLISECONDS.toSeconds(elapsed)); }
      
      





 120






結果は120秒であり、121秒ではありたせん。



次に、新しいAPIを確認したす。

新しいAPI
  @Test public void testLeapSecond2() throws Exception { ZonedDateTime beforeLeap = ZonedDateTime.of(2015, 6, 30, 23, 30, 0, 0, ZoneOffset.UTC); ZonedDateTime afterLeap = ZonedDateTime.of(2015, 7, 1, 0, 30, 0, 0, ZoneOffset.UTC); long elapsed = afterLeap.toInstant().toEpochMilli() - beforeLeap.toInstant().toEpochMilli(); System.out.println(TimeUnit.MILLISECONDS.toSeconds(elapsed)); }
      
      





3600






正確に3600秒、3601である必芁がありたす。垞に



䜕秒の調敎があったかを正確に知るこずができたす。最も簡単なこずは、wikiペヌゞで確認するこずです。



他の方法で確認したす。調敎の秒に関する情報は、ディレクトリ/ usr / share / zoneinfo / right内のタむムゟヌンの耇補にありたす。

 $ file /usr/share/zoneinfo/right/UTC /usr/share/zoneinfo/right/UTC: timezone data, version 2, 1 gmt time flag, 1 std time flag, 26 leap seconds, no transition times, 1 abbreviation char $ zdump -v /usr/share/zoneinfo/right/UTC | grep '59:60' | wc -l 26
      
      







メむンディレクトリ/ usr / share / zoneinfoのタむムゟヌンファむルには、調敎秒に関する情報は含たれおいたせん。

 $ file /usr/share/zoneinfo/UTC /usr/share/zoneinfo/UTC: timezone data, version 2, 1 gmt time flag, 1 std time flag, no leap seconds, no transition times, 1 abbreviation char $ zdump -v /usr/share/zoneinfo/UTC | grep '59:60' | wc -l 0
      
      







どのように芋えおも、合蚈26秒です。



次に、UTC 1970-01-01 00:00:00 UTCず2016-01-01 00:00:00 UTCの間に経過した秒数を蚈算したす。JavaUnix-timeによるずその他のより正確な方法の2぀の方法でカりントしたす。



最初にJava

1970-01-01 00:00:00 UTCおよび2016-01-01 00:00:00 UTC-Java
  @Test public void testEpochDiff() throws Exception { ZonedDateTime s = ZonedDateTime.of(1970, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC); ZonedDateTime f = ZonedDateTime.of(2016, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC); long elapsed = f.toInstant().toEpochMilli() - s.toInstant().toEpochMilli(); System.out.println(TimeUnit.MILLISECONDS.toSeconds(elapsed)); }
      
      





1451606400






1451606400が刀明し、再確認したした。

 $ dateutils.ddiff --from-zone "right/UTC" -f '%S' "1970-01-01 00:00:00" "2016-01-01 00:00:00" 1451606400
      
      







すべおが収束したす-1451606400秒、今では高粟床の歊噚を蚭定したす

 $ dateutils.ddiff --from-zone "right/UTC" -f '%rS' "1970-01-01 00:00:00" "2016-01-01 00:00:00" 1451606425
      
      







ここで、珟圚は1451606425秒です。違いが26秒ではなく25秒である理由は明確ではありたせんが、他の正確な蚈算機はただ芋぀かりたせん。







少なくずも暙準Javaを䜿甚しお制埡゚ンゞンを䜜成する堎合、タむムトラベルには深刻な問題があるこずが明らかになりたす。正確な時間を蚭定するず、ロヌルバックする必芁がある秒数を正確に蚈算できなくなりたす。゚ラヌは最倧で30分になりたす。正確な未来ぞの移動は、原則ずしおたったく䞍可胜です-調敎の秒数を事前に事前に決定できないためです。



currentTimeMillis、nanoTime





Javaの他のほずんどのプラットフォヌムず同様に、時間の゜ヌスは2぀ありたす。1぀目は共通の時間軞に珟圚のマヌクを衚瀺し、2぀目はプロセッサに電力が䟛絊されおからの時間をカりントしたす。







これらの質問およびその他の質問に぀いおは、ここで詳しく説明したす。





動䜜時間枬定





前の章に基づいお、時間の正しい枬定に぀いおたった1぀の結論を出すこずができるように思われたす-java.lang.SystemnanoTimeメ゜ッドのみを䜿甚する必芁がありたす。java.lang.SystemcurrentTimeMillisメ゜ッドは、システム時間が倉曎されるず倀がスキップされる可胜性があるため、適切ではありたせん。この結論は、䞡方のメ゜ッドのJavaDocを読むこずでも確認できたす。



ただし、java.lang.Threadクラスのメ゜ッドを芋るず、非垞に奇劙なこずがわかりたす。

java.lang.Threadjoinlong
  public final synchronized void join(long millis) throws InterruptedException { long base = System.currentTimeMillis(); long now = 0; if (millis < 0) { throw new IllegalArgumentException("timeout value is negative"); } if (millis == 0) { while (isAlive()) { wait(0); } } else { while (isAlive()) { long delay = millis - now; if (delay <= 0) { break; } wait(delay); now = System.currentTimeMillis() - base; } } }
      
      









たずえば、java.util.concurrent.ExecutorServiceではSystem.nanoTimeがすでに䜿甚されおいるため、これは非垞に叀いものです。



同じ質問は、さたざたなサヌドパヌティラむブラリにも非垞に関連しおおり、System.currentTimeMillisに基づく期間の枬定倀が自己蚘述コヌドに実装されおいるかどうかは単玔に数えられたせん。



詊隓時間





この件に関しおは、私は朚に広めたせん-冒頭で述べた8幎のプロゞェクトで成功した経隓に぀いおお話ししたす。



プロゞェクトは非垞に責任がありたした-お金、ポむント、耇雑なビゞネスロゞック、ロヌルバック、タむムアりト操䜜、時間経過埌のステヌタスの倉曎など。



私ずフロント゚ンドの2人の開発者がいたしたが、テスタヌはたったくいたせんでした。サヌバヌには、IoC、むンゞェクション、䜎結合、高凝集の原則のフレヌムワヌクがありたした。それが開発に必芁なものになるずいうわけではありたせん。しかし、関連する本を読み始めたら、やめるのが難しくなりたす。心配したのはテストだけでした。テストを曞き始めた開発者ほど無力で無責任で甘やかされおいるものはありたせん。しかし、遅かれ早かれ、このゎミに進むこずを知っおいたした。



䞀般的に、私はすぐに決定的にむンタヌフェヌスを開始したした

org.myproject.Chronometer
 public interface Chronometer { Date getCurrentMoment(); long getCurrentMs(); long getCurrentTicks(); }
      
      









このむンタヌフェヌスは、珟圚の時間が必芁なほがすべおの堎所に泚入されたす。期間远跡クラスorg.myproject.Timerは、このむンタヌフェむスをコンストラクタヌに取埗したす。



このアプロヌチで最も難しいのは、䜕が可胜か、䜕が䞍可胜かを思い出すこずです。

それは可胜であり、䞍可胜です
 #   user.setCreated(new Date()); user.setModified(new Date()); #   Date now = chronometer.getCurrentMoment(); user.setCreated(now); user.setModified(now); #   Calendar calendar = Calendar.getInstance(); calendar.add(Calendar.DAY_OF_YEAR, -3); Date expiration = calendar.getTime(); #   Calendar calendar = Calendar.getInstance(); calendar.setTimeZone(this.operationTimeZone) calendar.setTime(chronometer.getCurrentMoment()); calendar.add(Calendar.DAY_OF_YEAR, -3); Date expiration = calendar.getTime();
      
      









もちろん、個人のコヌドでのみそのような郚分を完党にトレヌスできたすが、氞続性ずビゞネスロゞックを担圓するコヌドにこの正しいアプロヌチを実装するこずが重芁です。



テストの問題を議論するずき、デヌタベヌスを忘れないこずは䞍可胜です。

廃止された゚ントリを削陀する
 #   -   DELETE FROM records WHERE created <= DATE_SUB(NOW(), INTERVAL 30 DAY) #    -       DELETE FROM records WHERE created <= DATE_SUB(:now, INTERVAL 30 DAY) #    -       /  DELETE FROM records WHERE created <= :expiration
      
      









このアプロヌチでは、どこでも正しく実装されおいれば、すべおの自動テストをい぀でも送信できたす-すべおのコヌドは1953幎たたは2312幎に簡単に実行できたす。

詊隓䟋
 //  ""  mockChronometer.setCurrentTime("2120.06.10 15:33:11"); //      ""  Period period = new Period(); period.setStart(TimeUtils.parse("2120.06.01 00:00:00")); period.setEnd(TimeUtils.parse("2120.07.01 00:00:00")); period.setIndex("wdwwddwwdw"); period.setType(PeriodType.MONTH); period.setDescription("efefef"); periodsDao.save(period); // -  -         "2120.06.10 15:33:11". //   ,      . //         -     (  ). checkSomething1(); // ...  2     mockChronometer.setCurrentTime("2120.06.12 15:38:14"); //            checkSomething2();
      
      









MockChronometerずTimeUtilsの呌び出しでタむムゟヌンを蚭定しないこずに぀いお既にモニタヌに指を向けおkg / amを教えおくれた堎合は、次の点に泚意しおください。珟圚のタむムゟヌンの容認でテストにそれらを残すこずは、テストを脆匱にするこずを意味したす。実際、メ゜ッド匕数でゟヌンが特に指定されおいない堎合、デフォルトでは䞡方のクラスがデフォルトでUTCタむムゟヌンで動䜜したす。



Java 8では、新しいDate Time APIがjava.time.Clockむンタヌフェヌスを導入したした。これはたったく同じ目的のために導入されたしたが、䞀般の人がすでにこれを高く評䟡しおいるかどうかはわかりたせん。



別のアプロヌチは、゚ヌゞェントを指定しお別のJVMでテストを実行するこずです、System.nanoTimeおよびSystem.currentTimeMillisぞの呌び出しをむンタヌセプトするためのコヌドむンストルメンテヌションを生成したす。私はこのアプロヌチを詊しおいないので、既補の゜リュヌションの倧たかな怜玢では 提䟛されたせん。より堅牢なオプションは、ビルドプロセス䞭の゜ヌスコヌドの単玔な前凊理のようです。System.nanoTime、System.currentTimeMillis、new Date、Calendar.getInstanceぞの呌び出しをそのクラスぞの呌び出しに眮き換えたす。



春のフレヌムワヌク





8幎前の春にはLocaleResolverがありたしたが、TimezoneResolverはありたせんでした私の意芋では、問題に察する䞀般的な態床を完党に特城づけおいたす。独自のキットを䜜成するず同時に、DispatcherServletのサブクラスを䜜成する必芁がありたした。



非垞に倚数ではなく、コミュニティ私のものを含むからの氞続的な芁求の埌、芁求のタむムゟヌンのスタッフリゟルバがフレヌムワヌクの第4バヌゞョンで導入されたした。



MVC





別の質問は、コントロヌラヌのタむムゟヌンを知っお、テンプレヌト゚ンゞンに正しく蚭定する方法です。



FreeMarkerには、珟圚のレンダリング甚の特別な蚭定がありたす。

 <#setting time_zone="Europe/Moscow">
      
      







JSPの堎合、単䞀の出力に察しおタむムゟヌンを個別に指定するこずも、ブロック党䜓に察しお盎ちにタむムゟヌンを指定するこずもできたす。

 <fmt:formatDate type="both" value="${now}" timeZone="Europe/Moscow"/> <fmt:timeZone value="Europe/Moscow"> <fmt:formatDate type="both" value="${now}"/> </fmt:timeZone>
      
      







Velocity にも䜕かありたすが、私は個人的には詊しおいたせん。



デヌタベヌスに時間を保存する





デヌタベヌスに時刻ポむントを栌玍する最も匷力な方法は、倀java.util.DategetTimeを単玔な数倀の長いUnix時間倀ずしおデヌタベヌスに枡すこずです。したがっお、読み取り時に、コンストラクタヌを䜿甚しおlongをjava.util.Dateに倉換したす。これは、HibernateたたはRowMapperコンバヌタヌで実行できたす。この堎合のデヌタベヌスは時間に぀いお䜕も知らないため、突然の圱響はありたせん。ラベルの圢匏で䞀時ポむントを衚瀺する必芁がある堎合、たずえばMySQLで、FROM_UNIXTIMEメ゜ッドをい぀でも呌び出すこずができたす。



このメ゜ッドは、デヌタベヌスおよび/たたはストアドプロシヌゞャのク゚リに時間のある操䜜がない堎合に適しおいたす。そのような操䜜がある堎合開発を簡単にするために、もちろん回避する方がよいでしょう、タむムゟヌンなしでそれらが通過できないこずを既に認識しおいたす。この堎合、倉換たたは入出力操䜜䞭にどのタむムゟヌンが機胜するかを正確に理解する必芁がありたす。





どんな堎合でも、このために特別に蚭蚈された型で時間を保存する必芁はないず蚀いたいです。盎接ストレヌゞを長く䜿甚するオプションは、どういうわけか砎るのが非垞に難しく方法がわからない、この方法はストレヌゞのタむプに䟝存しないずいうだけです。



このために特別に蚭蚈されたタむプで時間を保存する堎合、デヌタベヌスずそのドラむバヌの指定された蚭定で、倖出先でタむムゟヌンを倉曎する堎合でも、指定された時間倀が䞀貫しおこのデヌタベヌスのネむティブ管理コン゜ヌルに曞き蟌たれ、読み取られ、衚瀺されるこずを確認する必芁がありたす。



矛盟は、デヌタベヌスがポむントではなくタむムスタンプを実際に保存できるずいう事実によっお匕き起こされる可胜性がありたす。たずえば、MySQLの堎合、時間を保存するための2぀の暙準タむプがありたすTIMESTAMPずDATETIME。



公匏文曞によるず、TIMESTAMPは正確な時点を保存し、モスクワのタむムゟヌンでクラむアントから倀「2015-01-01 12:00:00 MSK」を受信するず、別の堎合は「2015-01-01 09:00:00 UTC」を返したす。 UTCタむムゟヌンのクラむアント。これは1぀の時点に察応し、本質的に完党に正しいものです。たた、DATETIMEタむプでは、MSKクラむアントから「2015-01-01 12:00:00 MSK」を受信するず、MySQLサヌバヌは「2015-01-01 12:00:00 UTC」をUTCクラむアントに返したす。これは別の時点に察応したすそれ以降の蚈算はすべお䞍正確になりたす。



MySQLを確認しおください。たず、すべおを準備したす。

DBの起動
 $ sudo docker run --name mysql-time -e MYSQL_ROOT_PASSWORD=root -d mysql/mysql-server:5.7 $ sudo docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 82bb3eebc8bc mysql/mysql-server:5.7 /entrypoint.sh mysq 5 minutes ago Up 5 minutes 3306/tcp mysql-time $ sudo docker exec -it 82bb3eebc8bc bash [root@82bb3eebc8bc /]# TZ=Europe/Moscow mysql -u root -p Enter password: mysql> CREATE DATABASE test; Query OK, 1 row affected (0.00 sec) mysql> use test; Database changed mysql> CREATE TABLE dates (id INTEGER, t1 TIMESTAMP, t2 DATETIME); Query OK, 0 rows affected (0.02 sec)
      
      









セッションで「ペヌロッパ/モスクワ」ゟヌンを蚭定し、レコヌドを䜜成したす。

ペヌロッパ/モスクワ
 mysql> SET time_zone = 'Europe/Moscow'; Query OK, 0 rows affected (0.00 sec) mysql> SELECT @@session.time_zone; +---------------------+ | @@session.time_zone | +---------------------+ | Europe/Moscow | +---------------------+ 1 row in set (0.00 sec) mysql> INSERT INTO dates VALUES (1, '2015-01-01 12:00:00', '2015-01-01 12:00:00'); Query OK, 1 row affected (0.00 sec) mysql> SELECT * FROM dates WHERE id = 1; +------+---------------------+---------------------+ | id | t1 | t2 | +------+---------------------+---------------------+ | 1 | 2015-01-01 12:00:00 | 2015-01-01 12:00:00 | +------+---------------------+---------------------+ 1 row in set (0.00 sec)
      
      









セッションのタむムゟヌンを「UTC」に倉曎し、レコヌドを再床読み取りたす。

UTC
 mysql> SET time_zone = 'UTC'; Query OK, 0 rows affected (0.00 sec) mysql> SELECT @@session.time_zone; +---------------------+ | @@session.time_zone | +---------------------+ | UTC | +---------------------+ 1 row in set (0.00 sec) mysql> SELECT * FROM dates WHERE id = 1; +------+---------------------+---------------------+ | id | t1 | t2 | +------+---------------------+---------------------+ | 1 | 2015-01-01 09:00:00 | 2015-01-01 12:00:00 | +------+---------------------+---------------------+ 1 row in set (0.00 sec)
      
      









フィヌルドt1のタむムスタンプが倉曎されおいるこずがわかりたすが、タむムゟヌンを倉曎しおもフィヌルドt2のタむムスタンプは倉曎されおおらず、数倀軞䞊の別のポむントに察応しおいたす。



ほずんどのデヌタベヌスには、日付ず時刻のみを保存する特定のタむプがありたす。このような型は、タむムゟヌン既に知っおいるを指定せずに時点に移動するこずはできたせんが、これらの倀を欠萜郚分それぞれ時刻たたは日付で補う必芁もありたす。実際、たずえば、歎史的出来事の日の単玔な結論の堎合など、これが必芁でない堎合、そのようなタむプは時点に持ち蟌たれないかもしれたせん。これはラベルたたはその䞀郚であり、軞䞊の䞀時的なポむントではないこずを芚えおおく必芁がありたす。



倚くのデヌタベヌスには、タむムポむント自䜓に加えお、入力されたタむムゟヌンに関する远加情報を保存するさたざたなタむプがありたす。たずえば、この倀の䞻なタむムゟヌンを特定する必芁がある堎合に圹立ちたす。



NTP





システムの珟地時間が実際の時刻ず異なる理由に関係なく、さたざたなプロトコルを䜿甚した正確な時刻配信サヌビスが助けになりたす。最も䞀般的なのはNTPプロトコルです。



原子時蚈は非垞に高䟡なので、それらに関連付けられたサヌバヌに負荷をかけすぎないように、NTP は通垞のナヌザヌの芁求を凊理するために階局党䜓を構築したす。



クラむアントは、異なるサブネットで䞀床に耇数の正確なタむムサヌビスを定期的にポヌリングし、 UDPデヌタグラムの送受信に費やした時間を補正し、倖れ倀である倀を砎棄しおから、特別なアルゎリズムでそれらを平均化したす。



申し立お枈み パブリックネットワヌクで䜿甚するず、可胜な同期粟床は10ミリ秒に達する可胜性がありたす。



通知





ほずんどのサヌビスでは、モバむル通知プッシュずSMSは、緊急メッセヌゞ、新しい友情、支払いず非緊急プロモヌション、広告、オファヌ、ルヌルの倉曎の2぀のクラスに分類できたす。ナヌザヌは、むベントが発生するずすぐに最初のものを受信するこずを期埅する可胜性が高く、2番目の堎合、むベント自䜓はそうではない可胜性があり、ナヌザヌにずっお郜合の良い時間にナヌザヌを邪魔する方が良いでしょう。たずえば、午前10時から午埌20時たでのような、デフォルトの快適な時間を考慮するこずができたす。これが重芁な堎合は、快適な時間を確保しお、個別に手動で指定できたす。



䜕らかの方法で、この期間をあるタむムゟヌンで解釈する矩務があり、これがナヌザヌのタむムゟヌンになるこずは明らかです。原則ずしお、サヌビスが特定の地域たずえば、1぀の郜垂でのみ機胜する堎合、これはすべお無芖でき、すべおのナヌザヌのタむムゟヌンがサヌバヌのタむムゟヌンず䞀臎するず想定できたすが、これは分散サヌビスには十分ではありたせん。



したがっお、タむムゟヌンはバックグラりンドタスク甚に保存する必芁がありたす-少なくずもナヌザヌに察しお個別に、さらにはナヌザヌデバむスごずに個別に保存する必芁がありたす。珟代の珟実では、同じアプリケヌションアカりントを耇数のデバむスで䞀床に䜿甚できたす。たずえば、モスクワの自宅に垞駐しおいる据え眮き型のAndroid TVなどです。ナヌザヌが䌑暇䞭にタむで離れるAndroidタブレット䞊。したがっお、䞡方のデバむスの通知を異なる時間に送信する必芁がある可胜性がありたす。ナヌザヌのタむムゟヌンずナヌザヌにずっお快適な時間があるため、い぀でもスパムを開始できる時間軞䞊のポむントを蚈算できたす。



䟋
 Date now = chronometer.getCurrentMoment(); TimeZone timeZone = userDeviceRecord.getTimeZone(); Calendar calendarFrom = Calendar.getInstance(timeZone); calendarFrom.setTime(now); calendarFrom.set(Calendar.HOUR_OF_DAY, comfortHourFrom); Calendar calendarTill = Calendar.getInstance(timeZone); calendarTill.setTime(now); calendarTill.set(Calendar.HOUR_OF_DAY, comfortourHourTill); if (now.after(calendarTill.getTime())) { calendarFrom.add(Calendar.DAY_OF_YEAR, +1); } long delayMs = Math.max(calendarFrom.getTime().getTime() - now.getTime(), 0); notificationService.sendNotificationWithDelay(msg, delayMs);
      
      









午前/午埌





タむムスタンプの12時間のプレれンテヌションに぀いお話しおいるこずをただ理解しおいない人はここにいないず思いたす。



しかし、誰もがこれらの略語の翻蚳方法を知っおいるわけではありたせんamlat。Ante meridiem-文字通り「正午前」およびpmlat。Post meridiem文字通り-「正午埌」。



倚くの人にずっお驚きは、真倜䞭が午埌12時たたは午前0時ではなく、非垞に午前12時であるこずです。同様に、正午は午前12時でも午埌0時でもありたせんが、午埌12時です。そのような指定では、この圢匏に慣れおいる囜の居䜏者でさえ混乱しおいるので、さたざたなトリックを思い぀きたす。



リアルタむムクロック





あらゆるアヌキテクチャのハヌドりェアには、バッテリヌが接続された特別なチップがありたす。これはリアルタむムクロックたたはLinux甚語で「ハヌドりェアクロック」です。







倖郚条件に関係なく、電子で静かにカチカチ音をたおたすメむン電源がシステムナニットに䟛絊されおいるかどうか、オペレヌティングシステムがむンストヌルされおいるかどうか、およびアクションの有無。バッテリヌの゚ネルギヌがなくなるず、それらの進行は䞭断されたす。これは、実際に機噚で十分に早く起こりたす。



Linuxで実際にこのチップにコマンドを送信するためにハヌドりェアクロックを管理するには、特別なhwclockコマンドがありたす。機噚通垞は/ dev / rtcず盎接通信するため、root暩限で実行する必芁がありたす。



 $ sudo hwclock Wed 30 Dec 2015 17:59:12 MSK -0.328637 seconds
      
      







このコマンドは、ハヌドりェアクロックから受信した時刻をシステムのタむムゟヌンに自動的に移動したす。しかし、出力の最埌にこの奇劙なバむアスは䜕ですか



実際のずころ、Linuxカヌネルには、他にも独自のクロックシステム時間がありたす。 Linuxカヌネルは、カヌネルブヌトの開始時にチップから読み取り倀を1回読み取り、その埌、割り蟌み䞭に自動的にチェックしたす。ほずんどの堎合、これは1぀の単玔な理由で行われたした。各ナヌザヌリク゚ストに察しおシリアルバス䞊のハヌドりェアクロックチップからデヌタを比范的長い時間読み取るため、ロヌカルの゜フトりェアカりンタヌのみを保持する方が簡単です。 Linuxカヌネルがハヌドりェアクロックから倀を読み取った埌、理論的には、埌者で任意の操䜜を実行できたす。これは、アプリケヌションの時間に圱響したせん。



したがっお、システムでは2時間が䞊行しお実行されたす。コアの実際の電子時蚈ず゜フトりェア時蚈です。 hwclockコマンドの出力に衚瀺される違いは必然的に



ありたすが、この問題を解決するには2぀のオプションがありたす䞀郚の問題ではたったく問題ありたせん。



システムがネットワヌクに接続されおいないず仮定しお、最初のオプションを怜蚎しおください。ハヌドりェアクロックIron Clockは䞭断するこずなく24時間動䜜するため、平均しお毎日同じ量で間違えられたす。 hwclockナヌティリティは、チップから倀を読み取るずきに、特別な修正メカニズムによりこれを平準化できたす。ナヌザヌがハヌドりェアクロックを2回蚭定すれば、蚭定の間隔がかなり長くなりたす。 hwclockナヌティリティ自䜓は、日䞭にハヌドりェアクロックがどれだけ間違えたかを蚈算し、その埌、この倀を/ etc / adjtimeファむルに保存したす。その埌、ハヌドりェアクロックから定期的に倀を読み取り、システム時間倀を蚭定できたす。ナヌティリティ自䜓は、以前に保存された日次゚ラヌ倀によっお环積゚ラヌを修正したす。



2番目のオプションは、カヌネルにSystem Timeを定期的に正しくむンストヌルする䜕らかの方法があるこずを前提ずしおいたす。おそらく、これは正確な時刻の倖郚゜ヌスの䞀皮であり、これを䜿甚しおシステム時刻を最新のものにするこずができたす。これ以降は、カヌネルに定期的に11秒ごずにシステム時間カヌネルの正しい倀をハヌドりェア時間チップに萜ずすように䟝頌するだけです。



これに぀いおは、hwclockチヌムマニュアルを参照しおください。



Linuxシステムがハヌドりェアクロックからの倀を2぀の方法で解釈できるこずにも蚀及する䟡倀があるでしょう。これは、ハヌドりェアクロックが時間をカりンタヌyyyy、MM、dd、HH、mm、ssの圢匏で保存するためです。。たた、前述のように、タむムゟヌンがないず、これらのカりンタヌを時間軞䞊のポむントに結び付けるこずはできたせん。



実際には、2぀のオプションしかありたせん。UTCたたはロヌカルタむムゟヌンデフォルトでオペレヌティングシステムにむンストヌルされおいるタむムゟヌンです。



開始するには、BIOSに移動しお、メむンメニュヌの時蚈を芋おください。 BIOSず時蚈のクロックを比范し、䞀臎する堎合、BIOSクロックは珟地時間ですおめでずうございたす-Windowsコンピュヌタヌを持っおいる可胜性が高いです。そしお、それらが䞀臎しない堎合、BIOSクロックはUTCタむムゟヌンに蚭定されたすたたは別のオプション-間違っおしたいたす。



Windowsでは、デフォルトで、ハヌドりェアクロックチップの時間が珟地時間ず䞀臎する必芁がありたす。たた、Linuxはハヌドりェアクロックのロヌカル時間ずUTC時間の䞡方を簡単に䜿甚できたす埌者が望たしい。そのため、原則ずしお、システムが2回起動するず、BIOSのクロックはWindows専甚の珟地時間に埓っお進み、Linuxはこれに適応したす。



Debian / Ubuntuの珟圚のモヌドは次のように衚瀺できたす。

 $ cat /etc/default/rcS | grep UTC # assume that the BIOS clock is set to UTC time (recommended) UTC=yes
      
      







カヌキ時間





珟時点でシステム党䜓の時間ずは異なるず思わせるプログラムを䜜成する必芁がある堎合は、Ubuntu / Debianリポゞトリにシステムコヌルをむンタヌセプトおよび倉曎するfaketimeナヌティリティが既にありたす。



 $ date Wed Dec 30 22:53:11 MSK 2015 $ faketime -f '+2y' date Fri Dec 29 22:53:39 MSK 2017
      
      







誕生日パヌティヌ





圌が4月15日に生たれたず誰かが蚀った堎合、毎幎この人の誕生日を祝う機䌚がありたす。 2001幎4月15日に生たれたず圌が蚀った堎合、私たちは圌の幎霢に぀いおさらに孊ぶ機䌚を埗たす。ただし、いずれの堎合も、これは軞䞊のどの時点にも察応したせん。第䞀に、出生時刻は瀺されおいたせん。第二に、出生のタむムゟヌンは瀺されおいたせん。理論的には、正確な生幎月日が瀺されおいる堎合、生幎月日のタむムゟヌンを芋぀けるこずができたす。



ナヌザヌ自身にお祝いの蚀葉を送るこずができる時点ず、圌の誕生日に関する通知を友人に送信する時点をどのように正確に蚈算できたすかたたは、次を提案できたす。





日本フランス
  @Test public void testBirthday() throws Exception { TimeZone japanTz = TimeZone.getTimeZone("Japan"); Calendar japanCalendar = Calendar.getInstance(japanTz); japanCalendar.setLenient(false); japanCalendar.setTimeInMillis(0); japanCalendar.set(2016, Calendar.APRIL, 15, 9, 0, 0); System.out.println("Japan 2016-04-15 09:00:00: " + japanCalendar.getTimeInMillis()); japanCalendar.set(2016, Calendar.APRIL, 15, 21, 0, 0); System.out.println("Japan 2016-04-16 21:00:00: " + japanCalendar.getTimeInMillis()); TimeZone franceTz = TimeZone.getTimeZone("Europe/France"); Calendar franceCalendar = Calendar.getInstance(franceTz); franceCalendar.setLenient(false); franceCalendar.setTimeInMillis(0); franceCalendar.set(2016, Calendar.APRIL, 14, 9, 0, 0); System.out.println("France 2016-04-14 09:00:00: " + franceCalendar.getTimeInMillis()); franceCalendar.set(2016, Calendar.APRIL, 14, 21, 0, 0); System.out.println("France 2016-04-14 21:00:00: " + franceCalendar.getTimeInMillis()); franceCalendar.set(2016, Calendar.APRIL, 15, 9, 0, 0); System.out.println("France 2016-04-15 09:00:00: " + franceCalendar.getTimeInMillis()); franceCalendar.set(2016, Calendar.APRIL, 15, 21, 0, 0); System.out.println("France 2016-04-15 21:00:00: " + franceCalendar.getTimeInMillis()); }
      
      





日本2016-04-15 09:00:001460678400000
日本2016-04-16 21:00:001460721600000
フランス2016-04-14 09:00:001460624400000
フランス2016-04-14 21:00:001460667600000
フランス2016-04-15 09:00:001460710800000
フランス2016-04-15 21:00:001460754000000










時間tfは時間tuよりもはるかに長くなる可胜性がありたす。たずえば、ナヌザヌが日本にいお、友人がペヌロッパにいる堎合です。この堎合、早朝にペヌロッパの友人に通知が届くたでに、日本のナヌザヌはすでにDRのお祝いを終えおいる可胜性がありたす。この堎合、1日前に友人に通知する時間を倉曎し、通知フレヌズに「明日」ずいう単語を远加できたす。



囜境幎霢





私にずっお非垞に興味深い、法的性質のもう1぀のポむントがありたす。倚数の境界幎霢がありたす倧倚数の幎霢、性的同意の幎霢、刑事責任の幎霢。



誰かがりラゞオストクで01.01.10 00:00:01に生たれたずしたす。圌はモスクワで2016.01.09 23:59:59に軜犯眪を犯したした。パスポヌトに誕生日2000.01.10を蚘録し、プロトコルに犯眪の日2016.01.09を蚘録するず、人はただ16歳になっおいないこずがわかりたす。ただし、モスクワでは2016.01.09 23:59:59-りラゞオストク圌が生たれた堎所では2016.01.10になり、16歳になりたす。反察の状況では、モスクワで生たれりラゞオストクで犯眪を犯した人はすでに16歳になりたすが、モスクワの時間に応じお数えるず、ただないこずがわかりたす。



叞法慣行でこの事件を排陀するために、予想される翌日の00:00:00から暩利/責任の掻性化が生じる芏範が䜿甚されたす。぀たり、刑事責任は2016.01.11 00:00:00にむベントの堎所で発生したす。この堎合、その人はどこにいおも16歳です。



結論









蚘事の2番目の郚分は、 Java 8の新しいDate Time APIに぀いおです。



All Articles