/* Ċ Ġ* ĠCopyright Ġ 2 0 1 9 - 2 0 2 1 ĠJetBrains Ġs . r . o . Ċ Ġ* ĠUse Ġof Ġthis Ġsource Ġcode Ġis Ġgoverned Ġby Ġthe ĠApache Ġ 2 . 0 ĠLicense Ġthat Ġcan Ġbe Ġfound Ġin Ġthe ĠLICENSE . txt Ġfile . Ċ Ġ*/ Ċ Ċ package Ġkotlinx . datetime Ċ Ċ import Ġkotlinx . datetime . serializers . Utc Offset Serializer Ċ import Ġkotlinx . serialization . Serializable Ċ import Ġkotlin . math . abs Ċ import Ġkotlin . native . concurrent . Thread Local Ċ Ċ @ Serializable ( with Ġ= ĠU tc Offset Serializer :: class ) Ċ public Ġactual Ġclass ĠU tc Offset Ġprivate Ġconstructor ( public Ġactual Ġval Ġtotal Seconds : ĠInt ) Ġ{ ĊĠĠĠ Ġprivate Ġval Ġid : ĠString Ġ= Ġzone Id By Offset ( total Seconds ) ĊĊĠĠĠ Ġoverride Ġfun ĠhashCode (): ĠInt Ġ= Ġtotal Seconds ĊĠĠĠ Ġoverride Ġfun Ġequals ( other : ĠAny ?): ĠBoolean Ġ= Ġother Ġis ĠU tc Offset Ġ&& Ġthis . total Seconds Ġ== Ġother . total Seconds ĊĠĠĠ Ġoverride Ġfun ĠtoString (): ĠString Ġ= Ġid ĊĊĠĠĠ Ġpublic Ġactual Ġcompanion Ġobject Ġ{ ĊĊĠĠĠĠĠĠĠ Ġpublic Ġactual Ġval ĠZERO : ĠU tc Offset Ġ= ĠU tc Offset ( total Seconds Ġ= Ġ 0 ) ĊĊĠĠĠĠĠĠĠ Ġpublic Ġactual Ġfun Ġparse ( offset String : ĠString ): ĠU tc Offset Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( offset String Ġ== Ġ" Z ") Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠZERO ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġparse Ġ- Ġ+ h , Ġ+ hh , Ġ+ hh mm , Ġ+ hh : mm , Ġ+ hh mm ss , Ġ+ hh : mm : ss ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġhours : ĠInt ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġminutes : ĠInt ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġseconds : ĠInt ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( offset String . length ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 2 Ġ-> Ġreturn Ġparse ( offset String [ 0 ]. toString () Ġ+ Ġ" 0 " Ġ+ Ġoffset String [ 1 ]) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 3 Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhours Ġ= Ġparse Number ( offset String , Ġ 1 , Ġfalse ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġminutes Ġ= Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġseconds Ġ= Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 5 Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhours Ġ= Ġparse Number ( offset String , Ġ 1 , Ġfalse ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġminutes Ġ= Ġparse Number ( offset String , Ġ 3 , Ġfalse ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġseconds Ġ= Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 6 Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhours Ġ= Ġparse Number ( offset String , Ġ 1 , Ġfalse ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġminutes Ġ= Ġparse Number ( offset String , Ġ 4 , Ġtrue ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġseconds Ġ= Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 7 Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhours Ġ= Ġparse Number ( offset String , Ġ 1 , Ġfalse ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġminutes Ġ= Ġparse Number ( offset String , Ġ 3 , Ġfalse ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġseconds Ġ= Ġparse Number ( offset String , Ġ 5 , Ġfalse ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 9 Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhours Ġ= Ġparse Number ( offset String , Ġ 1 , Ġfalse ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġminutes Ġ= Ġparse Number ( offset String , Ġ 4 , Ġtrue ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġseconds Ġ= Ġparse Number ( offset String , Ġ 7 , Ġtrue ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġthrow ĠDateTime FormatException (" Invalid ĠID Ġfor ĠU tc Offset , Ġinvalid Ġformat : Ġ$ offset String ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfirst : ĠChar Ġ= Ġoffset String [ 0 ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( first Ġ!= Ġ'+' Ġ&& Ġfirst Ġ!= Ġ'-') Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠDateTime FormatException ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Invalid ĠID Ġfor ĠU tc Offset , Ġplus / minus Ġnot Ġfound Ġwhen Ġexpected : Ġ$ offset String ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( first Ġ== Ġ'-') Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġof Hours Minutes Seconds (- hours , Ġ- minutes , Ġ- seconds ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġof Hours Minutes Seconds ( hours , Ġminutes , Ġseconds ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠIllegalArgumentException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠDateTime FormatException ( e ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġvalidate Total ( total Seconds : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( total Seconds Ġ! in Ġ- 1 8 Ġ* ĠSE CON DS _ PER _ HOUR Ġ.. Ġ 1 8 Ġ* ĠSE CON DS _ PER _ HOUR ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalArgumentException (" Total Ġseconds Ġvalue Ġis Ġout Ġof Ġrange : Ġ$ total Seconds ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// Ġorg . th reet en . bp . Zone Offset # validate ĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġvalidate ( hours : ĠInt , Ġminutes : ĠInt , Ġseconds : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( hours Ġ< Ġ- 1 8 Ġ|| Ġhours Ġ> Ġ 1 8 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalArgumentException (" Zone Ġoffset Ġhours Ġnot Ġin Ġvalid Ġrange : Ġvalue Ġ" Ġ+ Ġhours Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Ġis Ġnot Ġin Ġthe Ġrange Ġ- 1 8 Ġto Ġ 1 8 ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( hours Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( minutes Ġ< Ġ 0 Ġ|| Ġseconds Ġ< Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalArgumentException (" Zone Ġoffset Ġminutes Ġand Ġseconds Ġmust Ġbe Ġpositive Ġbecause Ġhours Ġis Ġpositive ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( hours Ġ< Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( minutes Ġ> Ġ 0 Ġ|| Ġseconds Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalArgumentException (" Zone Ġoffset Ġminutes Ġand Ġseconds Ġmust Ġbe Ġnegative Ġbecause Ġhours Ġis Ġnegative ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( minutes Ġ> Ġ 0 Ġ&& Ġseconds Ġ< Ġ 0 Ġ|| Ġminutes Ġ< Ġ 0 Ġ&& Ġseconds Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalArgumentException (" Zone Ġoffset Ġminutes Ġand Ġseconds Ġmust Ġhave Ġthe Ġsame Ġsign ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( abs ( minutes ) Ġ> Ġ 5 9 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalArgumentException (" Zone Ġoffset Ġminutes Ġnot Ġin Ġvalid Ġrange : Ġabs ( value ) Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġabs ( minutes ) Ġ+ Ġ" Ġis Ġnot Ġin Ġthe Ġrange Ġ 0 Ġto Ġ 5 9 ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( abs ( seconds ) Ġ> Ġ 5 9 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalArgumentException (" Zone Ġoffset Ġseconds Ġnot Ġin Ġvalid Ġrange : Ġabs ( value ) Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġabs ( seconds ) Ġ+ Ġ" Ġis Ġnot Ġin Ġthe Ġrange Ġ 0 Ġto Ġ 5 9 ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( abs ( hours ) Ġ== Ġ 1 8 Ġ&& Ġ( abs ( minutes ) Ġ> Ġ 0 Ġ|| Ġabs ( seconds ) Ġ> Ġ 0 )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalArgumentException (" Utc Ġoffset Ġnot Ġin Ġvalid Ġrange : Ġ- 1 8 : 0 0 Ġto Ġ+ 1 8 : 0 0 ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// Ġorg . th reet en . bp . Zone Offset # of Hours Minutes Seconds ĊĠĠĠĠĠĠĠ Ġinternal Ġfun Ġof Hours Minutes Seconds ( hours : ĠInt , Ġminutes : ĠInt , Ġseconds : ĠInt ): ĠU tc Offset Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvalidate ( hours , Ġminutes , Ġseconds ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( hours Ġ== Ġ 0 Ġ&& Ġminutes Ġ== Ġ 0 Ġ&& Ġseconds Ġ== Ġ 0 ) ĠZERO ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġof Seconds ( hours Ġ* ĠSE CON DS _ PER _ HOUR Ġ+ Ġminutes Ġ* ĠSE CON DS _ PER _ MINUTE Ġ+ Ġseconds ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// Ġorg . th reet en . bp . Zone Offset # of Total Seconds ĊĠĠĠĠĠĠĠ Ġinternal Ġfun Ġof Seconds ( seconds : ĠInt ): ĠU tc Offset Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvalidate Total ( seconds ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( seconds Ġ% Ġ( 1 5 Ġ* ĠSE CON DS _ PER _ MINUTE ) Ġ== Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġut c Offset Cache [ seconds ] Ġ?: ĠU tc Offset ( total Seconds Ġ= Ġseconds ). also Ġ{ Ġut c Offset Cache [ seconds ] Ġ= Ġit Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠU tc Offset ( total Seconds Ġ= Ġseconds ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// Ġorg . th reet en . bp . Zone Offset # parse Number ĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġparse Number ( offset Id : ĠCharSequence , Ġpos : ĠInt , Ġprece ded By Colon : ĠBoolean ): ĠInt Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( pre ce ded By Colon Ġ&& Ġoffset Id [ pos Ġ- Ġ 1 ] Ġ!= Ġ': ') Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠDateTime FormatException (" Invalid ĠID Ġfor ĠU tc Offset , Ġcolon Ġnot Ġfound Ġwhen Ġexpected : Ġ$ offset Id ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġch 1 Ġ= Ġoffset Id [ pos ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġch 2 Ġ= Ġoffset Id [ pos Ġ+ Ġ 1 ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( ch 1 Ġ< Ġ' 0 ' Ġ|| Ġch 1 Ġ> Ġ' 9 ' Ġ|| Ġch 2 Ġ< Ġ' 0 ' Ġ|| Ġch 2 Ġ> Ġ' 9 ') Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠDateTime FormatException (" Invalid ĠID Ġfor ĠU tc Offset , Ġnon Ġnumeric Ġcharacters Ġfound : Ġ$ offset Id ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġ( ch 1 Ġ- Ġ' 0 ') Ġ* Ġ 1 0 Ġ+ Ġ( ch 2 Ġ- Ġ' 0 ') ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ @ Thread Local Ċ private Ġvar Ġut c Offset Cache : ĠMutable Map < Int , ĠU tc Offset > Ġ= Ġmutable Map Of () Ċ Ċ @ Suppress (" ACT UAL _ FUNCTION _ WITH _ DEFAULT _ ARGUMENT S ") Ċ public Ġactual Ġfun ĠU tc Offset ( hours : ĠInt ? Ġ= Ġnull , Ġminutes : ĠInt ? Ġ= Ġnull , Ġseconds : ĠInt ? Ġ= Ġnull ): ĠU tc Offset Ġ= ĊĠĠĠ Ġwhen Ġ{ ĊĠĠĠĠĠĠĠ Ġhours Ġ!= Ġnull Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ ĠU tc Offset . of Hours Minutes Seconds ( hours , Ġminutes Ġ?: Ġ 0 , Ġseconds Ġ?: Ġ 0 ) ĊĠĠĠĠĠĠĠ Ġminutes Ġ!= Ġnull Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ ĠU tc Offset . of Hours Minutes Seconds ( minutes Ġ/ ĠMIN UTES _ PER _ HOUR , Ġminutes Ġ% ĠMIN UTES _ PER _ HOUR , Ġseconds Ġ?: Ġ 0 ) ĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠU tc Offset . of Seconds ( seconds Ġ?: Ġ 0 ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊ