Vraag Best practices voor zomertijd en tijdzone [gesloten]


Ik hoop dat ik deze vraag en de antwoorden daarop de definitieve handleiding kan maken voor het omgaan met zomertijd, in het bijzonder voor het omgaan met de feitelijke overschakeling.

Als u iets toe te voegen heeft, doe dat dan

Veel systemen zijn afhankelijk van het bijhouden van de juiste tijd, het probleem zit in het wijzigen van de tijd door zomertijd: de klok vooruit of achteruit.

Bijvoorbeeld, men heeft bedrijfsregels in een orderverzamelsysteem dat afhangt van het tijdstip van de bestelling - als de klok verandert, zijn de regels mogelijk niet zo duidelijk. Hoe moet de tijd van de bestelling worden gehandhaafd? Er zijn natuurlijk een eindeloos aantal scenario's - deze is slechts illustratief.

  • Hoe bent u met het zomertijdsprobleem omgegaan?
  • Welke veronderstellingen zijn onderdeel van uw oplossing? (op zoek naar context hier)

Zo belangrijk, zo niet meer:

  • Wat heb je geprobeerd dat niet werkte?
  • Waarom werkte het niet?

Ik zou geïnteresseerd zijn in programmeren, OS, data-persistentie en andere relevante aspecten van het probleem.

Algemene antwoorden zijn geweldig, maar ik wil ook graag details zien, vooral als ze alleen beschikbaar zijn op één platform.


1885


oorsprong


antwoorden:



Samenvatting van antwoorden en andere gegevens: (voeg de uwe toe)

Do:

  • Telkens wanneer u naar een exact moment in de tijd verwijst, moet u de tijd voortzetten volgens een uniforme standaard die niet wordt beïnvloed door zomertijd. (GMT en UTC zijn in dit opzicht equivalent, maar het heeft de voorkeur om de term UTC te gebruiken. Merk op dat UTC ook bekend staat als Zoeloe of Z tijd.)
  • Als u in plaats daarvan ervoor kiest om een ​​tijd aan te houden met behulp van een lokale tijdswaarde, neemt u de lokale tijdsverschuiving voor deze specifieke tijd op vanaf UTC (deze offset kan het hele jaar door veranderen), zodat de tijdstempel later ondubbelzinnig kan worden geïnterpreteerd.
  • In sommige gevallen moet u mogelijk opslaan beide de UTC-tijd en de equivalente lokale tijd. Vaak gebeurt dit met twee afzonderlijke velden, maar sommige platforms ondersteunen een datetimeoffset type dat beide in één veld kan opslaan.
  • Gebruik als u tijdstempels opslaat als een numerieke waarde Unix tijd - wat het aantal hele seconden sindsdien is 1970-01-01T00:00:00Z (exclusief schrikkelseconden). Gebruik in plaats daarvan milliseconden als u een hogere nauwkeurigheid wenst. Deze waarde moet altijd gebaseerd zijn op UTC, zonder aanpassing van de tijdzone.
  • Als u later de tijdstempel wilt wijzigen, neemt u de oorspronkelijke tijdzone-ID op, zodat u kunt bepalen of de offset is gewijzigd ten opzichte van de oorspronkelijke geregistreerde waarde.
  • Bij het plannen van toekomstige evenementen heeft gewoonlijk lokale tijd de voorkeur in plaats van UTC, omdat het gebruikelijk is dat de offset verandert. Zie antwoord, en blogpost.
  • Bij het opslaan van hele datums, zoals verjaardagen en jubilea, niet converteren naar UTC of een andere tijdzone.
    • Sla indien mogelijk op in een gegevenstype met alleen datum dat geen tijdstip bevat.
    • Als een dergelijk type niet beschikbaar is, moet u altijd het tijdstip van de dag negeren bij het interpreteren van de waarde. Als u er niet zeker van bent dat de tijd van de dag wordt genegeerd, kiest u 12:00 Noon in plaats van 00:00 Midnight als een veiligere representatieve tijd op die dag.
  • Vergeet niet dat tijdsverschuivingen niet altijd een geheel aantal uren zijn (bijvoorbeeld, Indiase standaardtijd is UTC + 05: 30 en Nepal gebruikt UTC + 05: 45).
  • Gebruikt u Java java.time voor Java 8, of gebruik Joda Time voor Java 7 of lager.
  • Als u gebruikt .NETTO, overweeg om te gebruiken Noda Time.
  • Als u .NET zonder Noda Time gebruikt, overweeg dan dat DateTimeOffset is vaak een betere keuze dan DateTime.
  • Als u Perl gebruikt, gebruik dan Datum Tijd.
  • Gebruik als u Python gebruikt pytz of dateutil.
  • Gebruik als u JavaScript gebruikt moment.js met de ogenblik-tijdzone uitbreiding.
  • Als u PHP> 5.2 gebruikt, gebruikt u de eigen tijdzones die worden aangeboden door DateTime, en DateTimeZone klassen. Wees voorzichtig tijdens het gebruik DateTimeZone::listAbbreviations() - Zie antwoord. Om PHP up-to-date te houden met Olson-gegevens, moet u deze periodiek installeren het tijdzoneb PECL-pakket; Zie antwoord.
  • Als u C ++ gebruikt, zorg er dan voor dat u een bibliotheek gebruikt die de juiste implementeert IANA tijdzone-database. Deze omvatten cctz, ICU, en De 'tz'-bibliotheek van Howard Hinnant.
    • Gebruik niet boost voor tijdzone-conversies. Terwijl zijn API beweert dat het standaard IANA (ook bekend als "zoneinfo") -identifiers ondersteunt brengt ze grofweg in kaart naar POSIX-achtige gegevens, zonder rekening te houden met de rijke geschiedenis van wijzigingen die elke zone mogelijk heeft gehad. (Ook is het bestand niet meer onderhouden.)
  • De meeste bedrijfsregels gebruiken civiele tijd in plaats van UTC of GMT. Daarom is het van plan om UTC-tijdstempels naar een lokale tijdzone te converteren voordat toepassingslogica wordt toegepast.
  • Vergeet niet dat tijdzones en offsets niet vast zijn en kunnen veranderen. Historisch gezien hebben bijvoorbeeld de Verenigde Staten en het VK dezelfde datums gebruikt om 'vooruit te springen' en 'terug te vallen'. In 2007 hebben de VS echter de datums gewijzigd waarop de klokken worden gewijzigd. Dit betekent nu dat gedurende 48 weken van het jaar het verschil tussen de tijd in Londen en New York 5 uur is en 4 weken (3 in het voorjaar, 1 in het najaar) 4 uur. Houd rekening met dit soort items in berekeningen met meerdere zones.
  • Overweeg het type tijd (werkelijke evenemententijd, uitzendtijd, relatieve tijd, historische tijd, terugkerende tijd) welke elementen (tijdstempel, tijdzoneverschuiving en tijdzonenaam) u moet opslaan voor correct ophalen - zie "Soorten tijd" in dit antwoord.
  • Houd uw OS-, database- en toepassings-tzdata-bestanden gesynchroniseerd, onderling en met de rest van de wereld.
  • Op servers stelt u hardwareklokken en OS-klokken in op UTC in plaats van een lokale tijdzone.
  • Ongeacht het vorige opsommingsteken, server-side code, inclusief websites, zou moeten nooit verwachten dat de lokale tijdzone van de server iets in het bijzonder is. Zie antwoord.
  • Werk liever met tijdzones op een geval-per-geval basis in uw applicatiecode, in plaats van globaal door configuratiebestandinstellingen of standaardinstellingen.
  • Gebruik NTP services op alle servers.
  • Als u gebruikt FAT32, onthoud dat tijdstempels worden opgeslagen in lokale tijd, niet UTC.
  • Let bij het omgaan met terugkerende evenementen (bijvoorbeeld een wekelijks tv-programma) op dat de tijd verandert met DST en anders zal zijn in tijdzones.
  • Altijd datum- tijdwaarden vragen als ondergrens inclusief, exclusief exclusief (>=, <).

Niet doen:

  • Verwar een "tijdzone" niet, zoals America/New_York met een "tijdzoneverschuiving", zoals -05:00. Het zijn twee verschillende dingen. Zien de tijdzone-tag wiki.
  • Gebruik geen JavaScript's Date object om datum- en tijdberekeningen uit te voeren in oudere webbrowsers, zoals ECMAScript 5.1 en lager heeft een ontwerpfout die de zomertijd mogelijk verkeerd gebruiken. (Dit werd opgelost in ECMAScript 6/2015).
  • Vertrouw nooit op de klok van de klant. Het kan heel goed onjuist zijn.
  • Vertel mensen niet "altijd overal UTC te gebruiken". Dit brede advies is kortzichtig van verschillende geldige scenario's die eerder in dit document zijn beschreven. Gebruik in plaats daarvan de juiste tijdreferentie voor de gegevens waarmee u werkt. (Timestamping kan UTC gebruiken, maar toekomstige tijdplanning en alleen datum-waarden mogen dat niet doen.)

testen:

  • Zorg er bij het testen voor dat u landen test in het Westen, Oostelijk, Noordelijk en zuidelijk hemisferen (in feite elk kwart van de wereld, dus 4 regio's), met zowel DST in uitvoering als niet (geeft 8), en een land dat geen DST gebruikt (nog eens 4 voor alle regio's, in totaal 12).
  • Testovergang van DST, d.w.z. wanneer u zich momenteel in de zomertijd bevindt, selecteert u een tijdwaarde uit de winter.
  • Test grensgevallen, zoals een tijdzone die UTC + 12 is, met DST, waarbij de lokale tijd wordt bepaald UTC + 13 in de zomer en zelfs plaatsen die UTC + 13 zijn in de winter
  • Test alle bibliotheken en toepassingen van derden en zorg ervoor dat ze de tijdzonegegevens correct verwerken.
  • Test in elk geval de tijdzones van een half uur.

Referentie:

andere:

  • Lobby je vertegenwoordiger om een ​​einde te maken aan de gruwel die DST is. We kunnen altijd hopen ...
  • Lobby voor Aarde standaardtijd

802



Ik weet niet zeker wat ik kan toevoegen aan de bovenstaande antwoorden, maar hier volgen enkele punten van mij:

Soorten tijden

Er zijn vier verschillende tijden die u zou moeten overwegen:

  1. Tijd van de gebeurtenis: bijv. De tijd wanneer een internationaal sportevenement plaatsvindt, of een kroning / overlijden / enz. Dit is afhankelijk van de tijdzone van het evenement en niet van de kijker.
  2. Televisietijd: een bepaald tv-programma wordt bijvoorbeeld om 21.00 uur lokale tijd overal ter wereld uitgezonden. Belangrijk als u nadenkt over het publiceren van de resultaten (bijvoorbeeld American Idol) op uw website
  3. Relatieve tijd: bijv .: deze vraag heeft een open premie die eindigt in 21 uur. Dit is eenvoudig te tonen
  4. Terugkerende tijd: bijv .: Een tv-programma is elke maandag om 21.00 uur, zelfs wanneer de zomertijd verandert.

Er is ook een historische / alternatieve tijd. Deze zijn vervelend omdat ze misschien niet teruggaan naar de standaardtijd. Bijv .: Juliaanse datums, datums volgens een maankalender op Saturnus, de Klingon-kalender.

Het opslaan van start / eind tijdstempels in UTC werkt goed. Voor 1 heb je een naam van de tijdzone van een evenement + offset nodig die samen met de gebeurtenis is opgeslagen. Voor 2 hebt u een lokale tijdcode nodig die bij elke regio is opgeslagen en een lokale tijdzone naam + offset voor elke kijker (het is mogelijk om deze af te leiden van het IP als u zich in een crunch bevindt). Voor 3, winkel in UTC seconden en geen behoefte aan tijdzones. 4 is een speciaal geval van 1 of 2, afhankelijk van of het een wereldwijd of een lokaal evenement is, maar u moet ook een opslaan gemaakt bij tijdstempel, zodat u kunt zien of een tijdzone-definitie is gewijzigd voordat of nadat deze gebeurtenis is gemaakt. Dit is nodig als u historische gegevens wilt weergeven.

Tijden opslaan

  • Sla altijd tijd op in UTC
  • Converteren naar lokale tijd op het display (lokaal gedefinieerd door de gebruiker die de gegevens bekijkt)
  • Wanneer u een tijdzone opslaat, hebt u de naam, het tijdstempel en de offset nodig. Dit is nodig omdat overheden soms de betekenissen van hun tijdzones veranderen (bijvoorbeeld: de VS-regering heeft de zomertijd gewijzigd) en je toepassing moet de dingen netjes verwerken ... bijvoorbeeld: het exacte tijdstempel wanneer afleveringen van LOST zowel voor als na de zomertijd weergaven veranderd.

Offsets en namen

Een voorbeeld van het bovenstaande zou zijn:

Het wereldkampioenschap finale voetbalwedstrijden   is gebeurd in Zuid-Afrika (UTC + 2 - SAST)   op 11 juli 2010 om 19:00 UTC.

Met deze informatie kunnen we historisch het exacte tijdstip bepalen waarop de WCS-finales van 2010 plaatsvonden, zelfs als de tijdzonedefinitie in Zuid-Afrika verandert, en in staat zijn om dat weer te geven aan kijkers in hun lokale tijdzone op het moment dat ze de database bevragen.

Systeemtijd

U moet ook uw tzdata-bestanden voor besturingssystemen, databases en applicaties synchroon houden, zowel met elkaar als met de rest van de wereld, en uitgebreid testen wanneer u een upgrade uitvoert. Het is niet ongehoord dat een externe app waar je van afhankelijk bent niet correct met een TZ-wijziging omgaat.

Zorg ervoor dat hardwareklokken zijn ingesteld op UTC en als u servers over de hele wereld gebruikt, moet u ervoor zorgen dat hun besturingssystemen zijn geconfigureerd om ook UTC te gebruiken. Dit wordt duidelijk wanneer u elk uur geroteerde apache-logbestanden van servers in meerdere tijdzones moet kopiëren. Sorteren op bestandsnaam werkt alleen als alle bestanden een naam hebben met dezelfde tijdzone. Het betekent ook dat je geen datum-wiskunde in je hoofd hoeft te doen wanneer je van de ene naar de andere doos ss en tijdstempels moet vergelijken.

Voer ook ntpd uit op alle vakken.

cliënten

Vertrouw nooit de tijdstempel die u van een clientcomputer krijgt als geldig. Bijvoorbeeld de datum: HTTP-headers of een javascript Date.getTime() noemen. Deze zijn prima bij gebruik als ondoorzichtige ID's, of bij het doen van datumberekeningen tijdens een enkele sessie op dezelfde client, maar probeer deze waarden niet te vergelijken met iets dat u op de server hebt. Uw klanten voeren NTP niet uit, en hebben niet noodzakelijk een werkende batterij voor hun BIOS-klok.

Trivia

Ten slotte zullen regeringen soms heel rare dingen doen:

De standaardtijd in Nederland was   precies 19 minuten en 32.13 seconden   voor UTC bij wet van 1909-05-01   tot 1937-06-30. Deze tijdzone   kan niet exact worden weergegeven met behulp van   het UU: MM-formaat.

Oké, ik denk dat ik klaar ben.


288



Dit is een belangrijk en verrassend moeilijk probleem. De waarheid is dat er geen volledig bevredigende norm is voor het aanhouden van tijd. De SQL-standaard en het ISO-formaat (ISO 8601) zijn bijvoorbeeld duidelijk niet genoeg.

Vanuit conceptueel oogpunt behandelt men meestal twee soorten datum van de datum, en het is handig om ze te onderscheiden (de bovenstaande standaarden niet): "fysieke tijd"en"burgerlijke tijd".

Een 'fysiek' moment van tijd is een punt in de continue universele tijdlijn waar de natuurkunde mee te maken heeft (natuurlijk de relativiteit negeren). Dit concept kan adequaat worden gecodeerd - aangehouden in UTC, bijvoorbeeld (als u schrikkelseconden kunt negeren).

Een "civiele" tijd is een datetime-specificatie die volgt op civiele normen: een tijdstip hier wordt volledig gespecificeerd door een reeks datetime-velden (Y, M, D, H, MM, S, FS) plus een TZ (tijdzone-specificatie) (ook een "kalender", maar laten we aannemen dat we de discussie beperken tot de Gregoriaanse kalender). Een tijdzone en een kalender laten gezamenlijk (in principe) toe om van de ene representatie naar de andere te gaan. Maar civiele en fysieke tijdmomenten zijn fundamenteel verschillende soorten magnitudes, en ze moeten conceptueel gescheiden worden gehouden en anders worden behandeld (een analogie: reeksen bytes en tekenreeksen).

De kwestie is verwarrend omdat we van dit soort gebeurtenissen door elkaar spreken, en omdat de burgerlijke tijden onderhevig zijn aan politieke veranderingen. Het probleem (en de noodzaak om deze concepten te onderscheiden) wordt duidelijker voor gebeurtenissen in de toekomst. Voorbeeld (uit mijn discussie hier.

John noteert in zijn kalender een herinnering voor een bepaalde gebeurtenis op dat tijdstip 2019-Jul-27, 10:30:00, TZ =Chile/Santiago, (die GMT-4 heeft gecompenseerd, vandaar komt het overeen met UTC 2019-Jul-27 14:30:00). Maar op een dag in de toekomst besluit het land om de TZ-offset te wijzigen in GMT-5.

Nu, wanneer de dag komt ... moet die herinnering worden geactiveerd

EEN) 2019-Jul-27 10:30:00 Chile/Santiago  = UTC time 2019-Jul-27 15:30:00 ?

of

B) 2019-Jul-27 9:30:00 Chile/Santiago  = UTC time 2019-Jul-27 14:30:00 ?

Er is geen goed antwoord, tenzij iemand weet wat John in conceptueel opzicht bedoelde toen hij de kalender vertelde "Bel me alsjeblieft 2019-Jul-27, 10:30:00 TZ=Chile/Santiago".

Bedoelde hij een "burgerlijke datum-tijd" ("wanneer de klokken in mijn stad vertellen 10:30 ")? In dat geval is A) het juiste antwoord.

Of bedoelde hij een "fysiek moment van tijd", een punt in de continuus tijdlijn van ons universum, bijvoorbeeld: "wanneer de volgende zonsverduistering happens ". In dat geval is antwoord B) de juiste.

Een paar datum / tijd-API's krijgen dit onderscheid goed: onder hen, Jodatime, dat is de basis van de volgende (derde!) Java DateTime API (JSR 310).


81



Maak een duidelijke architecturale scheiding van zorgen - om precies te weten welke laag interactie heeft met gebruikers, en moet de datum-tijd voor / van de canonieke weergave (UTC) wijzigen. Niet-UTC datum-tijd is presentatie (volgt gebruikers lokale tijdzone), UTC-tijd is model (blijft uniek voor back-end en mid-niveaus).

Ook, beslis wat uw daadwerkelijke publiek is, wat u niet moet dienen en waar u de lijn trekt. Raak geen exotische kalenders aan, tenzij u daar echt belangrijke klanten hebt en overweeg dan afzonderlijke servergerichte server (s) alleen voor die regio.

Als u de locatie van de gebruiker kunt verkrijgen en behouden, gebruikt u de locatie voor een systematische datum-tijdconversie (bijvoorbeeld .NET-cultuur of een SQL-tabel) maar biedt u een manier voor de eindgebruiker om overschrijvingen te kiezen als datum-tijd kritiek is voor uw gebruikers.

Als er historische auditverplichtingen zijn betrokken (zoals precies vertellen wanneer Jo in AZ twee jaar geleden in september een rekening betaalde) houd dan zowel UTC als lokale tijd aan voor de goede orde (uw conversietabellen zullen in de loop van de tijd veranderen).

Definieer de tijdreferentiële tijdzone voor gegevens die in bulk worden weergegeven - zoals bestanden, webservices, enzovoort. Stel dat het bedrijf East Coast een datacenter heeft in CA - u moet vragen en weten wat zij als standaard gebruiken in plaats van een van de twee te accepteren.

Vertrouw geen tijdzone verschuivingen ingebed in tekstuele weergave van de datum-tijd en accepteer niet om ze te ontleden en te volgen. Vraag in plaats daarvan altijd dat tijdzone en / of referentiezone expliciet moeten worden gedefinieerd. U kunt gemakkelijk tijd met PST-offset ontvangen, maar de tijd is feitelijk EST, aangezien dat de referentietijd van de client is en de records juist zijn geëxporteerd naar een server in PST.


53



U moet meer weten over de Olson tz-database, die beschikbaar is vanaf ftp://elsie.nci.nih.gov/pub  http://iana.org/time-zones/. Het wordt meerdere keren per jaar bijgewerkt om te gaan met de vaak last-minute wijzigingen in wanneer (en of) om te schakelen tussen winter- en zomertijd (standaard- en zomertijd) in verschillende landen over de hele wereld. In 2009 was de laatste release 2009s; in 2010 was het 2010; in 2011 was het 2011n; eind mei 2012 was de release 2012c. Merk op dat er een code is om de gegevens en de werkelijke tijdzonegegevens zelf te beheren, in twee afzonderlijke archieven (tzcode20xxy.tar.gz en tzdata20xxy.tar.gz). Zowel de code als de gegevens bevinden zich in het publieke domein.

Dit is de bron van tijdzonelamen zoals America / Los Angeles (en synoniemen zoals US / Pacific).

Als u verschillende zones wilt bijhouden, hebt u de Olson-database nodig. Zoals anderen hebben geadviseerd, wilt u de gegevens ook opslaan in een vast formaat - UTC is normaal de gekozen - samen met een record van de tijdzone waarin de gegevens zijn gegenereerd. Misschien wilt u een onderscheid maken tussen de offset van UTC op het moment en de tijdzonelaam; dat kan later een verschil maken. Ook, wetende dat het momenteel 2010-03-28T23: 47: 00-07: 00 (VS / Pacific) is, kan het u wel of niet helpen bij het interpreteren van de waarde 2010-11-15T12: 30 - die vermoedelijk is gespecificeerd in PST ( Pacific Standard Time) in plaats van PDT (Pacific Daylight Saving Time).

De standaard C-bibliotheekinterfaces zijn niet verschrikkelijk behulpzaam bij dit soort dingen.


De gegevens van Olson zijn verhuisd, deels omdat A D Olson binnenkort met pensioen zal gaan, en deels omdat er een (nu verworpen) rechtszaak tegen de beheerders was wegens schending van het auteursrecht. De tijdzonedatabase wordt nu beheerd onder auspiciën van IANA, de Internet Assigned Numbers Authority, en er is een link op de voorpagina naar 'Tijdzonegegevensbank'. De discussie-mailinglijst is nu tz@iana.org; de lijst met aankondigingen is tz-announce@iana.org.


38



In het algemeen, inclusief de lokale tijdverschuiving (inclusief DST-offset) in opgeslagen tijdstempels: UTC alleen is niet voldoende als u later de tijdstempel in de oorspronkelijke tijdzone (en zomertijdinstelling) wilt weergeven.

Houd er rekening mee dat de offset niet altijd een geheel aantal uren is (bijvoorbeeld de Indiase standaardtijd is UTC + 05: 30).

Geschikte formaten zijn bijvoorbeeld een tuple (unix-tijd, offset in minuten) of ISO 8601.


24



Het overschrijden van de grens van "computertijd" en "mensentijd" is een nachtmerrie. De belangrijkste is dat er geen soort standaard is voor de regels over tijdzones en zomertijd. Landen zijn vrij om hun tijdzone en DST-regels op elk gewenst moment te wijzigen, en dat doen ze ook.

Sommige landen, b.v. Israël, Brazilië, beslist elk jaar wanneer zij hun zomertijd willen hebben, dus het is onmogelijk om van tevoren te weten wanneer (als) zomertijd van kracht zal zijn. Anderen hebben vaste (ih) regels met betrekking tot wanneer DST van kracht is. Andere landen gebruiken DST niet als alles.

Tijdzones hoeven geen volledige uurverschillen te zijn van GMT. Nepal is +5,45. Er zijn zelfs tijdzones die +13 zijn. Dat betekent dat:

SUN 23:00 in Howland Island (-12)
MON 11:00 GMT 
TUE 00:00 in Tonga (+13)

zijn allemaal hetzelfde, maar 3 verschillende dagen!

Er is ook geen duidelijke standaard voor de afkortingen voor tijdzones en hoe deze veranderen in DST, zodat je eindigt met dingen als deze:

AST Arab Standard Time     UTC+03
AST Arabian Standard Time  UTC+04
AST Arabic Standard Time   UTC+03

Het beste advies is om zo veel mogelijk weg te blijven van de lokale tijd en je te houden aan UTC waar je kunt. Converteer alleen op het laatst mogelijke moment naar lokale tijden.

Zorg er bij het testen voor dat je landen in het westelijke en oostelijke halfrond test, met zowel DST aan de gang als niet en een land dat geen DST gebruikt (6 in totaal).


22



Voor PHP:

De DateTimeZone-klasse in PHP> 5.2 is al gebaseerd op de Olson DB die anderen vermelden, dus als je tijdzones omzet in PHP en niet in de DB, ben je vrijgesteld van het werken met (de moeilijk te begrijpen) Olson-bestanden.

PHP wordt echter niet zo vaak geüpdatet als de Olson DB. Het gebruik van PHP-tijdzoneconversies kan u dus met verouderde DST-informatie achterlaten en de juistheid van uw gegevens beïnvloeden. Hoewel dit naar verwachting niet vaak zal gebeuren, kan het gebeuren, en zullen gebeuren als je een groot aantal gebruikers over de hele wereld hebt.

Om het hoofd te bieden aan het bovenstaande probleem, gebruikt u de timezonedb pecl-pakket, dat is de functie om de tijdzone-gegevens van PHP bij te werken. Installeer dit pakket zo vaak als het is bijgewerkt. (Ik weet niet zeker of deze pakketupdates Olson-updates precies volgen, maar het lijkt te zijn bijgewerkt met een frequentie die op zijn minst heel dicht bij Olson-updates ligt.)


18



Als je ontwerp daar ruimte voor biedt, vermijd lokale tijdconversie allemaal samen! 

Ik weet dat dit voor sommigen misschien gek klinkt, maar denk eens aan UX: gebruikers verwerken nabije, relatieve datums (vandaag, gisteren, volgende maandag) sneller dan absolute datums (2010.09.17, vrijdag 17 september) na oogopslag. En als je er meer over nadenkt, is de nauwkeurigheid van tijdzones (en zomertijd) belangrijker naarmate de datum dichterbij ligt now(), dus als je datums / datetijden in een relatief formaat kunt uitdrukken voor +/- 1 of 2 weken, kunnen de resterende datums UTC zijn en het maakt niet uit tot 95% van de gebruikers.

Op deze manier kunt u alle datums in UTC opslaan en de relatieve vergelijkingen in UTC uitvoeren en eenvoudig de UTC-datums van de gebruiker weergeven buiten uw Relatieve dataredrempel.

Dit kan ook van toepassing zijn op gebruikersinvoer (maar meestal op een meer beperkte manier). Selecteren uit een vervolgkeuzelijst met alleen {Gisteren, Vandaag, Morgen, Volgende maandag, Volgende donderdag} is zoveel eenvoudiger en eenvoudiger voor de gebruiker dan een datumkiezer. Datumverzamelaars zijn enkele van de meest pijn veroorzakende componenten van het vullen van formulieren. Natuurlijk zal dit niet voor alle gevallen werken, maar je kunt zien dat het slechts een klein slim ontwerp vergt om het zeer krachtig te maken.


15



Hoewel ik het nog niet heb geprobeerd, zou een benadering van tijdzoneaanpassingen die ik dwingend zou vinden als volgt zijn:

  1. Sla alles op in UTC.

  2. Maak een tafel TZOffsets met drie kolommen: RegionClassId, StartDateTime en OffsetMinutes (int, in minuten).

Sla in de tabel een lijst met datums en tijden op wanneer de lokale tijd is veranderd en door hoeveel. Het aantal regio's in de tabel en het aantal datums hangt af van welk bereik van datums en gebieden van de wereld u moet ondersteunen. Zie dit als een "historische" datum, ook al zouden de datums de toekomst een praktische grens moeten geven.

Wanneer je de lokale tijd van een UTC-tijd wilt berekenen, doe je dit gewoon:

SELECT DATEADD('m', SUM(OffsetMinutes), @inputdatetime) AS LocalDateTime
FROM   TZOffsets
WHERE  StartDateTime <= @inputdatetime
       AND RegionClassId = @RegionClassId;

Misschien wilt u deze tabel in de cache plaatsen en LINQ of soortgelijke middelen gebruiken om de query's uit te voeren in plaats van de database te raken.

Deze gegevens kunnen worden gedistilleerd uit de publieke domein tz-database.

Voordelen en voetnoten van deze aanpak:

  1. Er zijn geen regels in code vastgelegd, u kunt de offsets gemakkelijk aanpassen voor nieuwe regio's of datumbereiken.
  2. U hoeft niet elk bereik van datums of regio's te ondersteunen, u kunt ze desgewenst toevoegen.
  3. Regio's hoeven niet direct te corresponderen met geopolitieke grenzen en om dubbele rijen te voorkomen (de meeste staten in de VS verwerken DST op dezelfde manier), u kunt brede regiocodes gebruiken die in een andere tabel verwijzen naar meer traditionele lijsten van staten, landen, etc.
  4. Voor situaties zoals de VS waar de begin- en einddatum van DST de afgelopen jaren is veranderd, is dit vrij gemakkelijk om aan te pakken.
  5. Omdat het StartDateTime-veld ook een tijd kan opslaan, wordt de standaard omschakeltijd van 2:00 AM eenvoudig afgehandeld.
  6. Niet overal ter wereld gebruikt een DST van 1 uur. Dit behandelt die gevallen gemakkelijk.
  7. De gegevenstabel is platformonafhankelijk en kan een afzonderlijk open-sourceproject zijn dat kan worden gebruikt door ontwikkelaars die bijna elk databaseplatform of programmeertaal gebruiken.
  8. Dit kan worden gebruikt voor verschuivingen die niets te maken hebben met tijdzones. Bijvoorbeeld de aanpassingen van één seconde die van tijd tot tijd plaatsvinden om zich aan te passen aan de rotatie van de aarde, historische aanpassingen aan en binnen de Gregoriaanse kalender, enz.
  9. Aangezien dit zich in een databasetabel bevindt, kunnen standaardrapportquery's enz. Profiteren van de gegevens zonder een reis door logica van bedrijfslogica.
  10. Hiermee worden ook tijdzoneverschuivingen verwerkt, als u dat wilt, en kunt u zelfs rekening houden met speciale historische gevallen waarin een regio is toegewezen aan een andere tijdzone. Het enige dat u nodig hebt, is een begindatum die een tijdzone-offset toekent aan elke regio met een minimale startdatum. Hiervoor zou je voor elke tijdzone tenminste één regio moeten maken, maar zou je ook interessante vragen kunnen stellen zoals: "Wat is het verschil in lokale tijd tussen Yuma, Arizona en Seattle, Washington op 2 februari 1989 om 5:00 uur?" (Trek slechts één SOM () van de andere af).

Nu, het enige nadeel van deze aanpak of een ander is dat conversies van lokale tijd voor GMT is niet perfect, omdat elke zomertijdverandering een negatieve verschuiving naar de klok heeft herhalingen een bepaalde lokale tijd. Geen gemakkelijke manier om daarmee om te gaan, vrees ik, en dat is een reden waarom het opslaan van lokale tijden in de eerste plaats slecht nieuws is.


15



Ik heb dit over twee soorten systemen gehad, "ploegplanningssystemen (bijvoorbeeld fabrieksarbeiders)" en "gasafhankelijke beheersystemen) ...

23 en 25 uur lange dagen zijn lastig om mee om te gaan, net als 8-uursdiensten die 7 uur of 9 uur duren. Het probleem is dat je zult merken dat elke klant of zelfs afdeling van de klant verschillende regels heeft die ze hebben gemaakt (vaak zonder te documenteren) over wat ze in deze speciale gevallen doen.

Sommige vragen worden pas aan de klant gesteld nadat ze hebben betaald voor uw "van de plank" -software. Het komt zelden voor dat een klant bij het kopen van software voorover nadenkt over dit soort problemen.

Ik denk dat je in alle gevallen tijd moet opnemen in UTC en moet converteren naar / van lokale tijd voordat je de datum / tijd opslaat. Maar zelfs als je weet welke tijd een bepaalde tijd in beslag neemt, kan moeilijk zijn met zomertijd en tijdzones.


12