❌ Het geaccepteerde antwoord is noch correct, noch bruikbaar.
✅ Het antwoord van Ole V.V. daarentegen vat de technische verschillen correct samen – volg voor details de links naar gedetailleerde pagina’s in Wikipedia.
Voor programmeurs die zakelijk georiënteerde apps bouwen, is het resultaat dat UTC het nieuwe GMT is. Je kunt de termen door elkaar gebruiken, waarbij het verschil letterlijk minder dan een seconde is. Dus voor alle praktische doeleinden in de meeste apps, helemaal geen verschil.
Hier volgt wat meer praktisch advies, met codevoorbeelden.
Strings
Zo, ik heb UTC-tijd als “02-01-2018 00:03” betekent dat dan dat mijn Amerikaanse lokale tijd “01-01-2018 18:00” is?
Dat eerste deel is een slecht voorbeeld, waarbij de datum-tijdstring een indicator voor de offset of zone mist.
Als een tekenreeks een specifiek moment aangeeft, moet deze een tijdzone aangeven (Continent/Region
opgemaakte naam) en/of een offset-van-UTC als een aantal uren-minuten-seconden. Als de string bedoeld is om een moment op UTC zelf weer te geven, betekent dat een offset-van-UTC van nul.
Om die string met een offset te schrijven, kunnen verschillende conventies worden toegepast. De beste in de praktijk is met zowel uren als minuten samen met een dubbele punt, zoals +00:00
+05:30
, of -08:00
. De voorloopnul en de dubbele punt zijn beide optioneel, maar ik heb bibliotheken zien afbreken wanneer ze een waarde tegenkwamen als -0800
of -8
.
Zulu
Als afkorting voor een offset van nul, wordt de letter Z
vaak gebruikt om UTC zelf aan te duiden. Uitgesproken als Zulu
.
ISO 8601
Verder is de beste praktijk bij het formatteren van datum-tijden in tekstvorm voor computergebruik de ISO 8601 standaardformaten te gebruiken. Voor een datum-tijd wordt het formaat YYYY-MM-DDTHH:MM:SS±HH:MM:SS gebruikt. De T
scheidt het datumgedeelte van het tijd-daggedeelte. Dit formaat heeft als voordelen dat het grotendeels ondubbelzinnig is, gemakkelijk te ontleden door machines en gemakkelijk te lezen door mensen in verschillende culturen. Een ander voordeel is dat alfabetisch sorteren ook chronologisch is. De standaard accepteert ook de afkorting Z
.
Dus uw voorbeeld UTC time as "02-01-2018 00:03"
is beter vermeld als 2018-01-02T00:03Z
.
java.time
Bedenk goed dat de meeste programmeertalen, bibliotheken en databases zeer slechte ondersteuning hebben voor het omgaan met datum-tijd, meestal gebaseerd op een slecht begrip van datum-tijd kwesties. Het omgaan met datum-tijd is verrassend ingewikkeld en lastig om onder de knie te krijgen.
De enige fatsoenlijke bibliotheek die ik ben tegengekomen zijn de java.time classes (zie Tutorial) gebundeld met Java 8 en later, en zijn voorganger het Joda-Time project (ook losjes geport van Java naar .Net in het Noda Time project).
In java.time wordt een moment op drie manieren weergegeven. Alle hebben een resolutie van nanoseconden.
-
Instant
Altijd in UTC. Technisch gezien een telling van nanoseconden sinds de epoche-referentie van het eerste moment van 1970 (1970-01-01T00:00:00Z). -
OffsetDateTime
Een datum met tijd-van-dag in de context van een bepaald aantal uren-minuten-seconden voor, of achter, UTC. -
ZonedDateTime
Een datum met tijd-van-dag in de context van een bepaalde tijdzone.
Wat is nu het verschil tussen een tijdzone en een offset-van-UTC? Waarom hebben we aparte klassen nodig? Een afwijking ten opzichte van het UTC is gewoon een aantal uren, minuten en seconden, drie getallen, niet meer en niet minder. Een tijdzone is veel meer. Een tijdzone is een geschiedenis van het verleden, het heden en de toekomstige veranderingen in de offset die door de mensen in een bepaalde regio wordt gebruikt.
Welke veranderingen? Veranderingen die worden gedicteerd door de grillen of wijsheid van hun politici. Politici over de hele wereld hebben een voorliefde getoond voor het veranderen van de tijdsverschuiving die wordt gebruikt door de tijdzone(s) in hun rechtsgebied. De zomertijd (DST) is een veel voorkomend patroon van veranderingen, waarbij het tijdschema vaak wordt gewijzigd en het besluit om de DST in te stellen of af te schaffen soms wordt veranderd. Andere veranderingen komen ook voor, zoals alleen al in de laatste paar jaar Noord-Korea hun klok met een half uur te synchroniseren met Zuid-Korea, Venezuela terugdraaien hun klok een half uur alleen om terug te springen vooruit minder dan een decennium later, Turkije dit jaar geannuleerd de geplande verandering van zomertijd naar standaardtijd met weinig waarschuwing vooraf, en de hedendaagse Rusland hebben meerdere van dergelijke veranderingen in de afgelopen jaren.
terug naar uw voorbeeld in punt # 3, laten we eens naar wat code kijken.
Zo, ik heb UTC-tijd als “02-01-2018 00:03” betekent dat dan dat mijn Amerikaanse lokale tijd “01-01-2018 18:00” is?
Jouw voorbeeld strings hebben nog een probleem. Die 03
minuut in het eerste deel wordt genegeerd je tweede deel, een schijnbare typfout. Ik weet dat omdat er op die datum in Amerika geen tijdzone-aanpassing van kracht is met een fractioneel uur van 57 minuten.
Geen moment
Eerst ontleden we je input string. Bij gebrek aan een zone- of offset-aanduiding moeten we deze ontleden met behulp van de LocalDateTime
. De naam LocalDateTime
kan misleidend zijn, want het betekent wel degelijk een specifieke lokaliteit. Het betekent elke of alle plaatsen. Voor meer uitleg, zie Wat is het verschil tussen Instant en LocalDateTime?
String input = "2018-01-02T00:03" ; // Text of a date with time-of-day but without any context of time zore or offset-from-UTC. *Not* a moment, *not* a point on the timeline.LocalDateTime ldt = LocalDateTime.parse( input ) ; // Parsing the input as a `LocalDateTime`, a class representing a date with time but no zone/offset. Again, this does *not* represent a moment, is *not* a point on the timeline.
UTC
Op grond van de in de Vraag gegeven feiten weten we dat deze datum en tijd bedoeld was om een moment in UTC weer te geven. Dus kunnen we de context van een offset-van-UTC van nul uur-minuten-seconden voor UTC zelf toekennen. We passen een ZoneOffset
constante UTC
toe om een OffsetDateTime
object te krijgen.
OffsetDateTime odt = ldt.atOffset( ZoneOffset.UTC ); // We are certain this text was intended to represent a moment in UTC. So correct the faulty text input by assigning the context of an offset of zero, for UTC itself.
Tijdzone
De Vraag vraagt om dit moment te zien door een muurkloktijd van zes uur achter UTC die in de Verenigde Staten wordt gebruikt. Een tijdzone met een dergelijke afwijking is America/Chicago
.
Specifieer een juiste tijdzone-naam in de opmaak van continent/region
, zoals America/Montreal
Africa/Casablanca
, of Pacific/Auckland
. Gebruik nooit de afkorting van 2-4 letters zoals CST
EST
, of IST
, want dat zijn geen echte tijdzones, niet gestandaardiseerd, en zelfs niet uniek(!).
ZoneId z = ZoneId.of( "America/Chicago" ) ; // Adjust from UTC to a time zone where the wall-clock time is six hours behind UTC.ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;
Zie deze code live lopen op IdeOne.com.
odt.toString(): 2018-01-02T00:03Z
zdt.toString(): 2018-01-01T18:03-06:00
Hetzelfde moment, andere wandkloktijd
Deze odt
en zdt
geven beide hetzelfde gelijktijdige moment weer, hetzelfde punt op de tijdlijn. Het enige verschil is de tijd van de muurklok.
Laten we een voorbeeld nemen met IJsland, waar de tijdzone een afwijking ten opzichte van de UTC van nul uur-minuten-seconden gebruikt. Dus de zone Atlantic/Reykjavik
heeft een muur-kloktijd die identiek is aan UTC. Tenminste op dit moment komt hun tijd overeen met UTC; in het verleden of in de toekomst kan het anders zijn, daarom is het onjuist om te zeggen “UTC is de tijdzone van IJsland”. Maar goed, ons voorbeeld… stel dat iemand in Reykjavík, IJsland met 3 minuten na middernacht op de klok die aan zijn muur hangt een telefoontje pleegt naar iemand in de VS. Die persoon in de VS woont in een plaats die de tijdzone van Chicago gebruikt. Terwijl de gebelde persoon de telefoon opneemt, kijkt hij naar de klok aan de muur en ziet dat het net na 18 uur is (18:03). Zelfde moment, andere wandkloktijd.
Ook de kalenders aan de muur zijn anders, want het is “morgen” in IJsland maar “gisteren” op het vasteland van de VS. Hetzelfde moment, verschillende data!
Over java.time
Het java.time framework is ingebouwd in Java 8 en later. Deze klassen vervangen de lastige oude legacy datum-tijdklassen zoals java.util.Date
Calendar
&SimpleDateFormat
.
Het Joda-Time project, nu in onderhoudsmodus, adviseert migratie naar de java.time classes.
Om meer te leren, zie de Oracle Tutorial. En zoek op Stack Overflow voor veel voorbeelden en uitleg. Specificatie is JSR 310.
U kunt java.time-objecten rechtstreeks met uw database uitwisselen. Gebruik een JDBC driver die voldoet aan JDBC 4.2 of later. Geen behoefte aan strings, geen behoefte aan java.sql.*
klassen.
Waar kan ik de java.time klassen verkrijgen?
- Java SE 8, Java SE 9, Java SE 10, Java SE 11 en later – Onderdeel van de standaard Java API met een gebundelde implementatie.
- Java 9 voegt enkele kleine functies en fixes toe.
- Java SE 6 en Java SE 7
- Het grootste deel van de java.time-functionaliteit is teruggeporteerd naar Java 6 & 7 in ThreeTen-Backport.
- Android
- Laterere versies van Android bundelen implementaties van de java.tijdklassen.
- Voor oudere Android (<26) past het ThreeTenABP-project ThreeTen-Backport aan (hierboven vermeld). Zie Hoe ThreeTenABP te gebruiken….
Het ThreeTen-Extra project breidt java.time uit met extra klassen. Dit project is een proeftuin voor mogelijke toekomstige toevoegingen aan java.time. U kunt hier enkele nuttige klassen vinden zoals Interval
YearWeek
YearQuarter
, en meer.