Mér var bent á það augljósa í dag. Það eru ekki lönd með sömu tímasetning, döhhhh..
Ég hafði hreinlega ekki hugsað útí það að allt sem skráð er á vefjunum(barnaland, babyverden, babyworld, osfrv) er í íslenskum tíma. Hong Kong er 8 tímum á undan okkur og þegar mér var bent á þetta þá hélt ég nú að þetta ætti ekki að vera mjög mikið mál. Sennilega bara stilla einhverja TimeZone breytu í .Net og þá virkar allt eins og það á að virka. Ekki aldeilis. Málið er ekki alveg svo einfalt.
Maður þarf að byrja á að hugsa útí það hvernig maður geymir tímann í gagnagrunninum. Til allrar hamingju erum við hérna á Íslandi alltaf í GMT eða UTC eins og það heitir í dag. Þetta þýðir að við þurfum aldrei að hafa áhyggjur að sumartíma og vetrartíma þegar við búum til forrit og þar sem ég hafði ekki hugsað útí þetta þá er þetta mjög heppilegt því UTC tími er sá tími sem á að geyma í grunninum skv. helstu fræðimönnum. Það er mjög mikilvægt að geyma tímann á þessu formi þar sem engin vetrar- og sumartími er á honum. Ef tíminn er geymdur t.d. á sænskum tíma þá getur maður lent í vandræðum þegar tímanum er breytt og þá sérstaklega þegar breytt er yfir í vetrartíma. Dæmi:Ef umræða uppfærð kl 01:59 síðan verður kl 02:00, þá breytist tíminn í kl 01:00 vegna vetrartímans, þá gerist það að ef raðað er eftir tímaröð þá koma nýjustu færslurnar ekki inn fyrr en eftir kl 01:59 eða um klukkutíma seinna. Því er mikilvægt að gagnagrunnurinn hafi alltaf UTC dagsetningu.
Þá þarf maður að passa sig á því að breyta alltaf dagsetningunni þannig að hún birtist rétt fyrir notandann. Ég fann enga sérstaka praktíska lausn á þessu þannig að ég bjó til klasa sem vinnur úr þessu. Útfærslan er í raun sára einföld.
Ég byrjaði á því að búa til TimeZone töflu í grunninum hjá mér, hvert vefsvæði hefur færslu í honum og inniheldur hann dálkana,
websiteId - Id á vefsvæðinu
offset - +/- frá UTC (t.d. Hong Kong er +8, Ísland er 0)
summertime - segir hvernar á að breytast í sumartíma, má vera null
wintertime - segir hvernar á að breytast í vetrartíma, má vera null
Ég gerði þetta svona því ég þarf aðeins að vita TimeZone-in hjá þeim vefjum sem ég er með í gangi og er í raun sama um allt annað. Ég bjó svo til klasa(kalla hann hérna MyTimeZone) sem er með sömu gildi og finnur sjálfkrafa út hvað offset-ið á að vera eftir því hver tíminn er á árinu(sumar eða vetur).
Næst bjó ég til klasan DisplayDateTime, hann lítur svona út.
public class DisplayDateTime {
public DateTime ConvertLocal(DateTime dt) {
return dt.AddHours((double) MyTimeZone.Current.Offset);
}
public DateTime ConvertUTC(DateTime dt) {
return dt.AddHours((-1)*(double) MyTimeZone.Current.Offset);
}
}
* ConvertLocal fallið skilar dagsetningunni eins og hún á að líta út fyrir notandann
* ConvertUTC fallið skilar UTC dagsetningunni.
* MyTimeZone.Current.Offset skilar decimal gildi því stundum er land með tíman á hálfatímanum.
Þetta er reyndar stytt og breytt útgáfa af klasanum en sýnir það sem sýna þarf.
Ég leitaði svo að öllum DateTime tilvikum á vefnum og fór yfir það hvað þurfti að breyta yfir og hverju mátti ekki breyta. Maður þarf að vanda sig því það má ekki breyta öllu yfir í Local dagsetningu. Þegar maður skráir í grunninn þá er nóg að nota DateTime.Now en það skilar UTC, ef hinsvegar notandinn er að slá inn dagsetninguna sem á að fara í grunnin þá þarf að breyta þeirri dagsetningu yfir í UTC áður en hún er vistuð í grunninn.
Þar með er TimeZone vandamálið leyst og alls ekki svo flókið. Í framtíðinni væri svo hægt að leyfa fólki að velja sitt eigið TimeZone en ég geri það sennilega bara þegar þess er þörf t.d. þegar við opnum í landi sem hefur mörg TimeZone.
Það er samt ótrúlegt hvernig svona basic hlutur getur farið framhjá manni.