-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.html
818 lines (612 loc) · 65.7 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<title>Working with Time and Timezones</title>
<meta charset="utf-8"/>
<script src="https://www.w3.org/Tools/respec/respec-w3c" class="remove"></script>
<script class="remove">
var respecConfig = {
// specification status (e.g. WD, LCWD, WG-NOTE, etc.). If in doubt use ED.
specStatus: "ED",
//publishDate: "2021-07-08",
previousPublishDate: "2011-07-05",
previousMaturity: "WG-NOTE",
noRecTrack: true,
shortName: "timezone",
copyrightStart: "2022",
edDraftURI: "https://w3c.github.io/timezone/",
// if this is a LCWD, uncomment and set the end of its review period
// lcEnd: "2009-08-05",
// editors, add as many as you like
// only "name" is required
//authors: [
// { name: "Person", mailto: "[email protected]",
// company: "Invited Expert" },
// ],
editors: [
{ name: "Addison Phillips", mailto: "[email protected]", company: "Invited Expert", w3cid: 33573 }
],
otherLinks: [
{
key: "Contributors:",
data: [
{
value: "See the Contributors section.",
href: "#contributors",
},
],
},
],
github: "w3c/timezone",
group: "i18n",
};
</script>
<link rel="stylesheet" href="local.css">
<script>
const zonesToTest = [ "UTC",
"Pacific/Noumea",
"Australia/Adelaide",
"Asia/Tokyo",
"Asia/Shanghai",
"Africa/Nairobi",
"Europe/Paris",
"America/New_York",
"America/Buenos_Aires",
"Pacific/Tahiti"];
function currTimeUpdate() {
var fmt = new Intl.DateTimeFormat('en-US', {dateStyle: 'full', timeStyle: 'medium'});
const now = new Date();
var currTimeSpan = document.getElementById('currTime');
currTimeSpan.textContent = Number(now);
currTimeSpan = document.getElementById('currTimeDisplay');
currTimeSpan.textContent = fmt.format(now);
var currZone = document.getElementById('currZone');
currZone.textContent = fmt.resolvedOptions().timeZone;
var tbody = document.getElementById('zoneOutTBody');
for (const zone of zonesToTest) {
var datefmt = new Intl.DateTimeFormat('en-US', { timeZone: zone, dateStyle: 'full' });
var timefmt = new Intl.DateTimeFormat('en-US', { timeZone: zone, timeStyle: 'short', hour12: false });
var tr = document.createElement('tr'); // table row
var td = document.createElement('td');
var code = document.createElement('code');
code.textContent = zone;
td.append(code);
tr.append(td);
td = document.createElement('td');
td.textContent = datefmt.format(now);
tr.append(td);
td = document.createElement('td');
td.textContent = timefmt.format(now);
tr.append(td);
tbody.append(tr);
}
}
</script>
</head>
<body onload="currTimeUpdate()">
<div id="abstract">
<p>This document contains guidelines and best practices for working with time and time zones in applications and document formats. Use cases are provided to help choose an approach that ensures that geographically distributed applications work well with date and time values. This document also aims to provide a basic understanding and vocabulary for talking about time and time handling in software, a source of confusion for many developers and content authors on the Web.</p>
</div>
<div id="sotd">
<p>We welcome comments on this document, but to make it easier to track them, please raise separate issues for each comment, and point to the section you are commenting on using a URL.</p>
</div>
<section id="contributors">
<h2 id="Acknowledgements">Contributors</h2><!-- This section was formerly an appendix with this 'id'. -->
<p>This document is based on several previous documents. The original Working Group Note (<a href="http://www.w3.org/TR/2005/NOTE-timezone-20051013/">Working With Timezones</a>) was by Martin Dürst, Mark Davis, Felix Sasaki, and Addison Phillips. A <a href="https://www.w3.org/TR/2011/NOTE-timezone-20110705/">later revision</a> was written by Martin Dürst, Mark Davis, Felix Sasaki, Richard Ishida, and Addison Phillips. Sections [[[#history]]] and [[[#what-is-time-zone]]] were adapted from an article and later a Unicode conference presentation (<cite>Time Out of Joint</cite>) by Addison Phillips. Information on time zone scenarios is based on work by Norbert Lindenberg. Information about temporal serializations and use cases is based on work by CJ Butenhoff.</p>
</section>
<section>
<h2 id="introduction">Introduction</h2>
<p>One common requirement for applications is the need to deal with dates, times, or durations. Working with time-related data can be complex because values are related to calendars and timekeeping rules, which themselves can be somewhat arcane. One of these complexities in working with time-related data is the effect of time zone on the handling and presentation of the data.</p>
<p>This document contains guidelines and best practices for working with date and time values, including time zones, in applications and document formats. Use cases are provided to help choose an approach that ensures that geographically distributed applications work well with date and time values. This document also aims to provide a basic understanding and vocabulary for talking about time, a source of confusion for many developers and content authors on the Web.</p>
<aside class="note">
<p>In this document [[RFC2119]] keywords have their usual meaning. Best practices and definitions are set off from the remainder of the text with special formatting.</p>
<p class="example">Examples appear with a different background color and decoration like this.</p>
<p class="advisement">Best practices appear with a different background color and decoration like this.</p>
<p class="definition">Definitions appear with a different background color and decoration like this.</p>
<p class="issue-example">Gaps or recommendations for future work appear with a different background color and decoration like this.</p>
</aside>
<section>
<h2>Why You Should Read This</h2>
<p>Working with date and time values, including the effect of time zones on the display and processing of these values, can be confusing. By understanding how date and time values work and how to manage these values in applications or specify them in standards, you can prevent many problems.</p>
<noscript>
<aside class="note">
<p><strong>This section requires JavaScript.</strong> Code demos in this document use JavaScript to demonstrate different features. Enabling JavaScript will allow you to view these demos successfully and make the document much more meaningful.</p>
</aside>
</noscript>
<p>When working with date and time values, the time zone, the <a>locale</a>, and your choices for encoding, handling, and processing date and time values can produce different and perhaps unexpected or unwanted results. Some examples of errors due to improper date/time handling might include the items listed below. Reading the best practices and guidelines in this document can help you create specifications, designs, or implementations that avoid errors when working with time values.</p>
<ul>
<li>Two people schedule a recurring phone call using a phone application. They set it up to start on a particular day of the week at a particular time. Sometimes the reminder comes too early to either one of the people. Sometimes it comes too late. Sometimes the phone application won't let the users in because the call is "already over".</li>
<li>A customer is eligible for a discount on their birthday, but when they log in on their birthday, they can't access the discount.</li>
<li>An website tracks customer loyalty by keeping track of the number of days that customer visited the site. The site shows gaps when the user travels, even though the customer logged in every day.</li>
<li>A business-critical regularly-scheduled process fails to run, but only on certain days of the year.</li>
</ul>
<aside class="example">
<p>The system time of your browser when this page was loaded was: <code id=currTimeDisplay></code>. This has an [=incremental time=] value of <code id=currTime></code>.</p>
<p>Your browser's time zone is: <code id=currZone></code>.</p>
<p>If a friend in a different time zone views this page at the same instant you do, they might see a very different time—perhaps even on a different day:</p>
<div id=zoneOut>
<table>
<thead>
<th style="width:30%">Zone</th>
<th style="width:50%">Date</th>
<th>Time</th>
</thead>
<tbody id=zoneOutTBody>
</tbody>
</table>
</div>
</aside>
</section>
</section>
<section>
<h2 id="howToUse">Concepts</h2>
<p>This section provides the basic concepts, terminology, and background for those unfamiliar with the origins, processing, and representation of date and time values in modern computer systems.</p>
<section>
<h3 id="definitions">Definitions</h3>
<p>These definitions are useful in understanding date/time values.</p>
<p class="definition"><dfn class="lint-ignore export">Chronology</dfn> or <dfn id="calendar">calendar</dfn> A timekeeping system used to organize dates and times.</p>
<p>Many different chronologies and calendars have been used or are in use today around the world. These different systems have varying rules for organizing and dividing time values.</p>
<p class="definition"><dfn class="lint-ignore export">ISO Chronology</dfn> is based on the [[ISO8601]] standard, which is the <em>de facto</em> world calendar. This system uses a <a>proleptic</a> Gregorian calendar.</p>
<p class="definition">A <dfn data-lt="proleptic">proleptic calendar</dfn> is a calendar that applies modern rules to all times in the past, as if the calendar were observed at that time.</p>
<p>For example, the Gregorian calendar was created in 1582 CE, but not adopted universally, even by countries observing the Julian calendar. A proleptic Gregorian calendar (and thus, by extension, the <a>ISO Chronology</a>) applies year numbers, leap years, and dating for dates in the past, even when that would be inappropriate historically.</p>
<p class="definition"><dfn class="link-ignore export">Observed Time</dfn> A moment in time based on an observed event or events. For example, "local noon", the shortest day or the year, or the first new moon.</p>
<p class="definition"><dfn class="link-ignore export">Wall Time</dfn> A date or time value as experienced by human beings, so called because the value might be what is shown on a paper calendar or analog clock mounted on the wall in a given location at a given moment.</p>
<p class="definition"><dfn class="link-ignore export">Epoch</dfn> A specific moment in time that serves as a reference point for a given <a>chronology</a>. The most common epoch is the Unix Epoch, which is used by the most common computer timekeeping systems and measures incremental time values from midnight, January 1, 1970 in the UTC time zone, i.e. from <code>1970-01-01T00:00:00.000Z</code></p>
<p class="definition"><dfn class="lint-ignore export">Era</dfn> A grouping within a <a>calendar</a> used to number years. Most eras start with year "1" and count up to the start of the next era. There are some exceptions to this: the Gregorian calendar's era "BCE" counts backwards, with 1 BCE being the year just before 1 CE (1 AD).</p>
<p class="definition"><dfn>Ghost time</dfn> A <a>wall time</a> that can never exist because of time zone or <a>calendar</a> rules. For example, the date `2023-02-29` is a "ghost time" because 2023 is not a leap year in the Gregorian calendar. Similarly, in the `America/Los_Angeles` time zone, the <a>wall time</a> `2:34 a.m.` on the date `2024-03-10` is a "ghost time" because, due to daylight-savings time, the clock skips from `1:59 a.m.` directly to `3:00 a.m.`.</p>
<p class="definition"><dfn class="lint-ignore export">Timeline</dfn> In a given chronology, the fixed sequence of moments, measured against the <a>epoch</a>. A datetime value is said to be <em>on the timeline</em> if it is attached to a discrete moment in time. This is a hallmark of incremental time values.</p>
<p class="definition"><dfn class="link-ignore export">Incremental Time</dfn> A datetime value consisting of monotonically increasing integer units measured from a specific moment in time (which is called the <a>epoch</a>). For example, the moment <code>1970-01-02T00:00:00.000Z</code> in the <a>ISO Chronology</a> might have an incremental time value (measured in milliseconds) of <code>86400000</code>, since there are 86,400 seconds in a day and 1000 ms in a second.</p>
<p class="definition"><dfn>Field-based Time</dfn> A datetime value that stores the time value in separate fields (era, year, month, day, hour, minute, second, millisecond, etc.)</p>
<p class="definition"><dfn data-lt="floating time|plain time|local time" class="link-ignore export">Floating Time</dfn> Any date or time value that is not fixed to a specific incremental time value or time zone. Also called a <em>local</em> or <em>plain</em> date or time value.</p>
<p class="definition"><dfn class="lint-ignore export">Instant</dfn> An <a>incremental time</a> in the Unix <a>epoch</a>. An instant can be converted for display in any <a>calendar</a> and/or time zone and any two instants can be ordered in time.</p>
<p class="definition"><dfn data-lt="universal coordinated time|UTC">Universal Coordinated Time</dfn> or <strong>UTC</strong> is the basis for modern timekeeping. Among other things, it provides a common baseline for converting between incremental and wall time. UTC is also known as GMT (Greenwich Mean Time). There are some subtle differences between the two, but none that the average person would notice. The time zone offset for UTC is <code>0</code>. UTC is often indicated in field-based formats using <code>Z</code>.</p>
<p class="definition"><dfn class="link-ignore export">Local Time Offset</dfn> The different (positive or negative) of a given location from <a>UTC</a>. This is usually expressed as an offset in hours and minutes, such as <code>+10:00</code> or <code>-09:30</code>.</p>
<p class="definition"><dfn class="link-ignore" data-lt="summer time|daylight savings time|DST|daylight time">Daylight Savings Time</dfn> Also called <em>summer time</em> or <em>daylight time</em> and abbreviated <em>DST</em>. The practice of advancing clocks to make better use of longer periods of daylight during the summer, so that darkness falls at a later [=wall time=]. Rules around observation (or non-observation) of DST is one feature of a time zone.</p>
</section>
<section>
<h2 id="history">A Brief History of Timekeeping</h2>
<p>Computer systems tell time differently than people do. So it is helpful to understand how time works within computers as well as in the real world in order to get a handle on how to get the results that you want. This description is necessarily simplified.</p>
<p>Timekeeping has its roots in observable celestial events, such as sunrise, sunset, the longest/shortest day of the year, the phases of the moon, or the position of the constellations. This is called <a>observed time</a> and underpins the various customary systems for measuring time.</p>
<p>Conventions have been established by various cultures to organize time into more convenient units. For example, days are broken up into arbitrary units such as hours, minutes, and seconds or grouped together to form weeks. Years are broken up into months. They are also numbered starting from significant events or organized into <a>eras</a>. Each unique cultural system for organizing time forms a <a>calendar</a> or <a>chronology</a>.</p>
<p>Gradually, over time, most chronologies have weakened or sometimes removed some of the ties to the original observational basis for events. For example, the Gregorian calendar's months do not correspond to the lunar cycle. Other calendars retain stronger linkages to specific celestial events. For example, most Islamic calendars use actual solar or lunar observations to determine the start of specific periods or months.</p>
<p>Mechanical timekeeping allows for more precision and standardization in counting or measuring events. We refer to the dates and times experienced in a given location as <a>wall time</a> because the date or time can be read from a printed calendar or a clock mounted on the wall.</p>
<p>The advent of speed-of-light communication (such as the telegraph) and efficient means of travel (such as railroads) meant that timekeeping based on local observations (such as "local noon") became inconvenient: it is difficult to manage schedules when each locality keeps its own clock! Even relatively small travel distances produce measurable differences in observed time. As a result, synchronization of different regions that observe the same calendar and <a>wall time</a> became necessary, resulting in the advent of time zones.</p>
<p><a>Observed time</a> has many disadvantages computationally. Observed events are not always predictable or convenient to use. The advent of mechanical timekeeping has allowed a different kind of time to flourish: <a>incremental time</a> based on a monotonic progression of fixed units. In some cases, incremental time is merely a prediction of when an event might be observed.</p>
<p>The modern standardized system of timekeeping in computer systems is generally based on a few core standards. <a>Universal Coordinated Time</a> (or "UTC"), adopted in 1972 CE, is used for global synchronization of clocks and to define local time zone variations. Many systems set computer clocks using the UNIX epoch (counting time from January 1, 1970 in UTC). Standards such as [[ISO8601]] or [[RFC3339]] provide serialization schemes for the interchange of date and time values and most programming languagues or data formats provide data structures for storing or exchanging date and time values. These types of systems are usually based on the <a>ISO Chronology</a> (also known as the <em>Gregorian calendar</em>), although they can be converted to other systems, such as the one of the Islamic calendars, the Ethiopic or Chinese solar-lunar calendars, and so forth.</p>
</section>
<section id="what-is-time-zone">
<h3>What is a Time Zone?</h3>
<p>A time zone is a set of rules for determining the local observed time (<a>wall time</a>) as it relates to <a>incremental time</a> (as used in most computing systems) for a particular geographical region.</p>
<p>Before the adoption of time zones, local time was derived directly from observation. Clocks might be set, for example, based on an observed event such as local noon. Traveling fairly short distances across the Earth's surface results in changes in local observed time: you only have to travel about 28 kilometers (17 miles) at the equator (and less distance the further north or south of the equator you are) to alter the observed local noon by one minute.</p>
<p>Time zones were originated in several countries by railroad operators. Before time zones were instituted, it was difficult know when trains would arrive or depart because local wall time might vary significantly from one station to another. This also made it difficult to schedule traffic across the rail network.</p>
<p>Railroads solved this problem by adopting fixed regions in which the same local time was used throughout. These "time zones" were intended to be about one observed hour wide: the local time in the middle of the time zone was used throughout the region so that the most observational deviation most people would see was about half an hour (and, assuming the population is evenly distributed, most people experienced a smaller deviation). This is a value small enough that most people won't notice the difference between actual and observed time.</p>
<p>In the modern era, most countries have a single time zone, but a number of larger or more geographically distributed countries have more than one.</p>
<section id="summer-time">
<h4>Daylight Savings or Summer Time</h4>
<p>The concept of "Daylight Saving Time" (DST) or "Summer Time" is used as a way of allowing people more sunlight hours in the evening. Not all regions observe summer time: usually those nearer the equator do not need it. Whether summer time is observed and how it is observed varies by jurisdiction.</p>
<p>As the name implies, areas that use some form of "summer time" do so in the summer season. That is, they change their UTC offset forward (usually by one hour) sometime in the spring and the reverse when the observation of summer time ends in the autumn. Since "spring" and "autumn" happen in opposite parts of the year in the northern and southern hemispheres, the starting and ending days are different for time zones in opposite hemispheres.</p>
<p>Observation (or non-observation) of summer time is controlled by national, regional, and sometimes local governments. Regions that otherwise share a UTC offset, even those with similar latitude (or shared borders) can have differing summer time start or stop rules. Sometimes local authorities will make one-time changes to accommodate a special event (such as when hosting the Olympics). Governments sometimes change whether summer time is observed as well as changing when summer time begins or ends.</p>
</section>
<section id="tz-definition">
<h4>What defines a time zone?</h4>
<p>While other schemes exist, many applications use the <a href="https://www.iana.org/time-zones">IANA Time Zone Database</a> [[BCP175]] and its associated set of identifiers to define time zones.</p>
<p>Time zones are defined by these considerations:</p>
<p><strong><a>Local Time Offset</a></strong> Time zones are used to compute the offset of <a>wall time</a> from <a>UTC</a>. The local time offset is the difference (positive or negative) between when a given time event is observed in UTC and local time. If all time zones used one-hour offsets, there would be 24 world-wide time zones, ranging between 12 hours before UTC to 11 hours following UTC. However, there are some that use half-hour or even quarter-hour offsets (or even some odd offsets). In addition, some time zones fall outside a single 24-hour span.</p>
<p><strong>Observation of summer time</strong> Some times zones include rules for observing daylight-savings or summer time, while others do not. The observation of summer time is defined by a set of rules that include:
<ul>
<li><strong>Summer time offset</strong> The amount of time added to (or subtracted from) the <a>local time offset</a> when summer time is being observed. Nowadays this is always one hour, but other values are theoretically possible (and have been used historically).</li>
<li><strong>Starting date</strong> Usually described as a specific date on a specific calendar, such as the "first Sunday in April"</li>
<li><strong>Starting time</strong> The time of day when the switch occurs, such as "2 AM"</li>
<li><strong>Ending date</strong> Like the starting date, the date on which to switch back to "standard time"</li>
<li><strong>Ending time</strong> The time of day when the switch occurs, such as "2 AM"</li>
</ul>
</p>
<p><strong>Adoption Dates</strong> Regions that currently have a specific local time offset and summer time behavior may have had different rules in the past (or plan to adopt new rules in the near future). Correct handling of past time values requires treating such regions as separate time zones.</p>
<aside class="example">
<p>Adoption dates can be applied to any of the values that define a time zone, such as the amount of summer time offset and the starting/ending dates or times for summer time. For example, prior to 2007, the United States started daylight-savings time at 2 a.m. on the first Sunday in April for each time zone observing daylight-savings. In 2007, the USA changed the start date and time to 2 a.m. on the second Sunday in March.</p>
</aside>
<aside class="example">
<p>Korea Standard Time and Japan Standard Time currently use the same UTC offset and neither uses summer time. However, Japan abandoned summer time in 1951, while South Korea used it last in 1988, so an application that tracks time values that reach back that far might need to track these time zones separately.</p>
</aside>
</section>
<section>
<h3>Time Zone Identifiers</h3>
<!-- ed note: BCP175 is RFC6557 -->
<p>The most definitive reference for identifying sets of time zone rules is the IANA Timezone Database [[BCP175]], which is used by systems such as various Linux distributions, Java, CLDR, ICU, and many other systems and libraries. Other systems exist: for example, Microsoft Windows uses its own data set and identifiers.</p>
<p>In the TZ database, time zones are given IDs that usually consist of a region and exemplar city. Regions can be continents (such as Europe or America) or oceans (such as Atlantic or Pacific). An exemplar city is a city in the time zone in question that should be well-known to people using the time zone. The TZ database also supplies aliases for many IDs; for example, <kbd>Asia/Ulan Bator</kbd> is equivalent to <kbd>Asia/Ulaanbaatar</kbd>. The Common Locale Data Repository [[CLDR]] can be used to provide a localized form for the IDs: see Appendix J in [[UAX35]]. Note: some systems, such as Apple Inc.'s MacOS, provide additional exemplar cities.</p>
<aside class="example" title="Examples of time zone IDs">
<table>
<thead>
<tr>
<th>ID</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><kbd>America/Los_Angeles</kbd></td>
<td>US Pacific time zone</td>
</tr>
<tr>
<td><kbd>Europe/London</kbd></td>
<td>UK time; not to be confused with UTC, since this zone observes Summer Time</td>
</tr>
<tr>
<td><kbd>Asia/Beijing</kbd></td>
<td>China Standard Time</td>
</tr>
<tr>
<td><kbd>Asia/Calcutta</kbd></td>
<td>India Standard Time; observes a 30 minute offset</td>
</tr>
<tr>
<td><kbd>Australia/Sydney</kbd></td>
<td>Sydney time</td>
</tr>
<tr>
<td><kbd>Pacific/Kiritimati</kbd></td>
<td>Line Islands time; one of the earliest time zones in the world</td>
</tr>
<tr>
<td><kbd>Pacific/Midway</kbd></td>
<td>Samoa time; one of the last time zones in the world</td>
</tr>
<tr>
<td><kbd>Atlantic/Azores</kbd></td>
<td>Azorian time</td>
</tr>
<tr>
<td><kbd>America/Argentina/San_Luis</kbd></td>
<td>Western Argentina time; one of few modern tripartite IDs</td>
</tr>
<tr>
<td><kbd>Australia/Eucla</kbd></td>
<td>Australia Central Western time; observes a 45 minute offset</td>
</tr>
</tbody>
</table>
</aside>
<p class="advisement">Specify the use of IANA time zone IDs in standards, protocols, or document formats as the identifier for time zones.</p>
<p class="advisement">Avoid special purpose time zone IDs, such as those beginning with <kbd>Etc/</kbd>.</p>
<p class="advisement">Use <code>continent/city</code> IDs in preference to legacy zone IDs such as those starting with <kbd>US/</kbd>.</p>
</section>
<section id="select-lto">
<h3>Selecting the Time Zone using the Local Time Offset</h3>
<p>Most countries are either small enough in area or, for practical reasons, choose to observe only a single time zone for the entire country. This means that knowing the region or country of the user is frequently sufficient to identify the time zone of the user as well. At the time this document was published, only twenty countries had more than one observed time zone. These countries are: Argentina, Australia, Brazil, Canada, Chile, Democratic Republic of the Congo, Ecuador, France, Greenland, Indonesia, Kazakhstan, Kiribati, Mexico, Micronesia, Mongolia, New Zealand, Portugal, Russia, Spain, and the United States.</p>
<p>Some special cases exist within this list:</p>
<ul>
<li><strong>Countries with maritime or overseas possessions</strong> Chile, Ecuador, France, New Zealand, and Portugal each have islands or other wide-ranging geographic areas far from the main part of the country. For example, Easter Island is part of Chile, the Galapagos Islands are part of Ecuador, and the Azores are part of Portugal. These offshore possessions are the source of additional time zones in each of these countries.</li>
<li><strong>France</strong> France is a special case of the above. There are several regions that are part of France, even though they might have their own ISO 3166-1 code. These include Reunion Island (in the Indian Ocean) and French Guiana (in South America). Additionally, French Polynesia is divided into three time zones.</li>
</ul>
<p>Within each of the countries that observe multiple time zones, knowing the current offset and current time will usually allow you to determine the time zone accurately. An exception to this is the United States: there exist some regions, such as Arizona, whose time zone cannot be determined strictly from the current time, country/region code, and offset, although an inferred time zone will always work for current time applications (not future and past times).</p>
</section>
<section id="tz-stability">
<h4>Stability of time zones</h4>
<p>Time zones, their rules, offsets, and observation (or non-observation) of summer time are controlled by a variety of international agreements, as well as national, regional, sub-national, and local governments. This can mean that neighboring areas that might otherwise share a UTC offset, even those with similar latitude (or shared borders) can have differing rules, such as those governing daylight-savings. Sometimes local authorities will change the boundaries of a zone or the offset used by a given region. Or they can make one-time changes to accommodate a special event (such as when hosting the Olympics). The time zone database tracks past changes so that applications can accurately compute <a>wall time</a> for past and future events.</p>
<p>Because there are many governing bodies acting independently, the time zone database is not stabilized. New rule changes or updates to historical records are introduced into the database as they are made known (such as due to legislative action). There is no specific release cycle: updates can happen at any time. When changes affect future events, computing systems have to be updated lest their clocks show the wrong local time for a given region or compute the wrong results for events affected by the change.</p>
</section>
</section>
<section id="representing-time">
<h3>Representing Dates and Times in Data</h3>
<p>There are several ways to represent time data, which vary in suitability according to an application needs.</p>
<section id="incremental-times">
<h3>Incremental Time</h3>
<p><a>Incremental time</a> measures time using fixed integer units that increase monotonically from a specific point in time called the [=epoch=]. Most programming languages and operating environments provide data types and APIs that use incremental time to represent or operate on datetime values. Incremental time is not usually seen directly by users. Instead, the incremental time value is formatted into a familiar <a>wall time</a> representation for human consumption.</p>
<p>The most common form of [=incremental time=] is counted in milliseconds (or, occasionally, nanoseconds) in the Unix Epoch. In this system, the value <code>0</code> represents midnight, January 1, 1970 in the UTC time zone. Negative numbers represent datetime values earlier than this moment, while positive numbers denote later moments in time. The [[ISO8601]] representation of this would be <code>1970-01-01T00:00:00.000Z</code>. Examples of this form of incremental time include:
<ul>
<li>Java: <code>java.util.Date</code></li>
<li>C/C++: <code>time_t</code></li>
<li>JavaScript: <code>Date</code></li>
</ul></p>
<p>Since incremental time values are just integers, any two incremental time values can be put into order as a sequence of events just by comparing the values. That is, every incremental time value can be put on a <a>timeline</a>.</p>
<p>This also means that incremental datetime values are indepedent of (and generally do not encode) their originating time zone. This is because the monotonic time in the Unix [=Epoch=] is the same everywhere at any given instant. Each incremental time value can be transformed for display using various [=chronologies=], time zone rules or, [=local time offsets=].</p>
<p class="note">Not all incremental time values are tied to specific <a>epoch</a>. A system's clock might be counting from the last time the hardware clock was restarted or some other event. Date values close to January 1, 1970 are often due to an incremental time value of <kbd>0</kbd> or due to malfunctions in or failure to set the system clock.</p>
</section>
<section id="field-based-times">
<h3>Field-Based Time</h3>
<p>A <a>field-based time</a> divides [=wall time=] into separate field values such as year, month, day, hour, minute, second, etc. Field-based times may or may not be tied to either UTC or the local time zone—or may be indeterminate. Field-based times are also typically tied to a specific calendar (such as the Gregorian calendar). The formats described by the [[ISO8601]] standard are field-based.</p>
<p>Some [=field-based time=] values are on the [=timeline=] (that is, "zone-dependent" values) while others are [=floating time=] values. It's important to distinguish between these two when working with [=field-based time=] to avoid inappropriate conversion of the value.</p>
<aside class="example" title="A field-based time type">
<p>The <code>tm</code> structure in the C programming language is an example of a field-based time.</p>
<pre class="C">
#include <time.h>
#include <stdio.h>
int main(void)
{
struct tm t;
time_t t_of_day;
t.tm_year = 2011-1900; /* 1900 based */
t.tm_mon = 0; /* January: zero based! */
t.tm_mday = 3; /* the third */
t.tm_hour = 0; /* midnight */
t.tm_min = 0; /* midnight */
t.tm_sec = 0; /* midnight */
t.tm_isdst = 0; /* no DST in January */
t_of_day = mktime(&t); /* convert the tm struct to an incremental time_t */
printf(ctime(&t_of_day));
return 0;
}
</pre>
</aside>
<p>A field-based time may or may not include information about the time zone being used. In a purely numeric representation, such as <code>time_t</code>, sometimes only the current UTC offset is provided.</p>
<aside class="note">
<p>Some modern APIs and data structures mix aspects of [=incremental time=] and [=field-based time=]. Notably Java's <code>java.time</code> Temporal types and the proposed Temporal types in JavaScript provide types like <code>Instant</code> that are "pure" [=incremental times=] as well as more complex types, such as <code>ZonedDateTime</code>, which can be instantiated and accessed by field or incrementally. It's a lot easier for most humans to work with field-based values.</p>
</aside>
</section>
<section id="floating-times">
<h3>Floating Time</h3>
<p>A <a>floating time</a> is a date or time value in a <a>calendar</a> that is not a specific <a>instant</a> in time. Applications and data formats use a <a>floating time</a> value when the <a>wall time</a> is more important to the value than putting the event onto a <a>timeline</a>. Generally, a floating time value will include only the date (<code>2024-01-27</code>) or only the time (<code>13:00:00</code>), but datetime values (<code>2024-01-27T13:00:00.000</code>) are sometimes also needed.</p>
<p>[=Floating time=] values are used when a given value's local [=wall time=] expression needs to stay constant, regardless of the viewing user's time zone. For example, if your birthdate were <samp>June 1, 1980</samp> this might be represented as the [=floating time=] <code>1980-06-01</code>. It does not matter if you view this date in Tokyo, London, or San Francisco: you always want the displayed value to remain constant. Time values that float can include things such as hours of operation as a policy, rather than for a specific location.</p>
<p><a>Floating time</a> values are often serialized in various ISO8601 formats by omitting the [=local time offset=] (or time zone identifier, such as <code>Z</code> for [=UTC=]). Data types for floating time values are less common in programming languages and operating environments. Errors are often the result when a floating time value is deserialized into into an [=incremental time=] type, which ties the value to UTC.</p>
<aside class="note"><a>Floating times</a> have different names in different specifications. [[HTML]] calls a <a>floating time</a> value a <a data-cite="html#date-time-local">local date and time</a>. JavaScript Temporal calls these values <em>plain</em> dates or times.</aside>
<aside class="example" title="Floating Time">
<p>For example, the French national holiday Bastille Day (<em lang="fr">Fête Nationale</em>) is observed on July 14th each year. Thus the 2022 occurence might be represented by the value <code>2022-07-14</code>. However, the observation of the holiday isn't tied to any specific location. Instead, its meaning "floats" based on locally observed midnight.</p>
<p>France has a number of overseas departments which do not share a time zone with Metropolitan France. In this example, we'll look at three French time zones: <code>Europe/Paris</code>, <code>Pacific/Noumea</code> (the time zone used in New Caledonia), and <code>Pacific/Tahiti</code> (one of the timezones in French Polynesia).</p>
<p>New Caledonia is one of (but not the) first time zones in France to observe the holiday. Tahiti is one of (but not the) last in France to observe it. The table below shows the dates and times in each of the time zones as Bastille Day is observed around the world. Notice that some of the [=incremental time=] values that are "Bastille Day" in one time zone are either before "Bastille Day" starts or after it ends in the other time zones:</p>
<table>
<thead>
<tr>
<th></th>
<th colspan=2>Europe/Paris</th>
<th colspan=2>Pacific/Noumea</th>
<th colspan=2>Pacific/Tahiti</th>
</tr>
</thead>
<tbody>
<tr>
<td>Europe/Paris</td>
<td><strong>2022-07-14<br>midnight</strong></td>
<td><strong>2022-07-15<br>midnight</strong></td>
<td>2022-07-13 3PM</td>
<td>2022-07-14 3PM</td>
<td>2022-07-14 noon</td>
<td>2022-07-15 noon</td>
</tr>
<td>Pacific/Noumea</td>
<td>2022-07-14 9AM</td>
<td>2022-07-15 9AM</td>
<td><strong>2022-07-14<br>midnight</strong></td>
<td><strong>2022-07-15<br>midnight</strong></td>
<td>2022-07-14 9PM</td>
<td>2022-07-15 9PM</td>
<tr>
</tr>
<tr>
<td>Pacific/Tahiti</td>
<td>2022-07-13 noon</td>
<td>2022-07-14 noon</td>
<td>2022-07-13 3AM</td>
<td>2022-07-14 3AM</td>
<td><strong>2022-07-14<br>midnight</strong></td>
<td><strong>2022-07-15<br>midnight</strong></td>
</tr>
</tbody>
</table>
</aside>
</section>
<section id="converting-float-unfloat">
<h3>Converting between representations</h3>
<p>Sometimes a <a>producer</a> will emit a <a>floating time</a> value when the <a data-cite="i18n-glossary#consumer">consumer</a> expects or requires an <a>incremental time</a> value. In other cases, a <a data-cite="i18n-glossary#consumer">consumer</a> might need to convert a local or otherwise incremental time value into a floating date or time.</p>
<p class="definition">To <dfn class="link-ignore export" data-lt="float|floating">float a date or time value</dfn> means to remove an <a>incremental time</a> value from the <a>timeline</a> by deleting any associated time zone and zone offset information from the value.</p>
<p>One common reason to float a value is if the data type used to collect or process the value is an incremental type (such as an `Instant` or Javascript `Date`) but the value isn't. For example, if you received a user's birth date as a `Date` object. Removing the time zone or offset makes it easier to format the value later without the field values changing incorrectly.</p>
<p class="definition">To <dfn class="link-ignore export" data-lt="unfloat|unfloating">unfloat a date or time value</dfn> means to attach a <a>floating time</a> value to the <a>timeline</a> by adding a time zone or zone offset to the value.</p>
<p>One common reason to unfloat a value is that the serialized value might not contain an offset but the value needs to be compared to other incremental values or displayed to the user in local time.</p>
<p class="advisement">Values received without a time zone or zone offset SHOULD generally be treated as if they are in UTC. Specifications SHOULD provide guidance on how to handle these values. Implementations MAY use some other value for the offset, such as the user agent's local time zone, but only if there is a good reason to do so.</p>
</section>
<section id="comparing-times">
<h2>Comparing representations</h2>
<p>Conversion between or operation on data sets that mix values with and without time zones or [=zone offsets=] presents certain problems. If one wishes to write a comparison between the value of a [=floating time=] value and a non-floating value, then the two values have to be reconciled to us the same reference point on the [=timeline=].</p>
<aside class="example" title="Values with and without zone offsets">
<pre class="xml">
<aDateTime>2005-06-07T13:14:27Z</aDateTime>
<bDateTime>2005-06-07T11:00:00</bDateTime>
</pre>
<p>If one wishes to write a comparison between the value of <kbd><aDateTime></kbd> and <kbd><bDateTime></kbd>, then the two values must be reconciled to use the same reference point. <kbd><aDateTime></kbd> uses UTC and can easily be converted to computer time or shifted to another zone offset. <kbd><bDateTime></kbd> contains no indication of the zone offset. It might be UTC or any other value (currently up to 14 hours different in either direction from UTC).</p>
</aside>
<p>It is good practice to use a time zone identifier or at least an explicit zone offset wherever possible. If one is not available, use UTC as the implicit zone offset for conversions of this nature. This is because the values are exactly centered in the range of possibilities and because representation internally (as computer time) is usually based on UTC. Since a single reference point has been used it might be possible to unwind the change later even if an erroneous conversion has taken place. When working with multiple documents from various sources, the "implicit" offset of the document may vary widely from that of the implementation doing the processing. If UTC is widely used, the chances of error are reduced.</p>
<p>Content and query authors are warned that comparing or processing data sets that contain both date and time values with and without time zones or zone offsets may produce odd results. Such processing should be avoided whenever possible. Generating content that omits zone offset information (where it exists) is a recipe for errors later. Of course, data such as the SQL types cited earlier and which are meant to represent wall time, should continue to omit the zone offset. Query writers can check for the presence (or absence) of zone offset and should do so to modify dates and times explicitly (instead of allowing implicit conversion) whenever possible.</p>
<p class="advisement">When comparing [=floating times=] to [=incremental times=], use UTC as the time zone.</p>
</section>
<section id="mixing-incremental-field">
<h3>Working with mixed representations</h3>
<p>[=Incremental time=] and [=field-based time=] differ in the way certain operations work. For example, incremental times can often be directly compared: their integer values determine which is earlier or later. [=Field-based times=] have to be normalized and their individual fields compared.</p>
<p>[=Field-based times=] are often optimized to allow for various kinds of adjustments to be made to a value while minimizing the chances for error. For example, to set the date <code>2005-08-30</code> forward by one day, an implementation can add 'one unit' to the "day" field and adjust the day, month, and year fields as appropriate to the calendar system. In incremental time, a similar operation might be performed by incrementing the value by <code>24 hours * 60 minutes * 60 seconds * 1000 milliseconds</code>, which is one "logical day". However, there can be errors when a particular day has more or fewer seconds in it (such as occur during daylight saving transitions) or when the unit has a variable size, such as when adding a month or a year, since those fields have variable numbers of days in them.</p>
<p>Bear in mind that rolling fields forwards or backwards in [=field-based times=] can be tricky. For example, Feburary does not always have the same number of days in it. Or consider the problem of incrementing the month forward by one in the date <code>2011-01-30</code>.</p>
<p>Serializations of date/time values tend to behave as-if they were field-based, in that they provide human-readable values tied to a specific [=chronology=] (typically the [=ISO Chronology=]). The most familiar example of such a serialization scheme is [[ISO8601]], along with its many flavors and interpretations, such as [[RFC3339]] or [[XMLSchema-2]]. The SQL data types <code>date</code>, <code>time</code>, and <code>timestamp</code> are [=field-based time=] values which are intended to be zone offset independent: they are actually [=floating time=] values! The SQL data type <code>timestamp with time zone</code> is actually the type that should be used for [=incremental time=] values ("timestamps").</p>
<p>By contrast with SQL types, programming languages tend to use [=incremental time=] for their primitive time types. They convert to and from field-based serializations demand. As a result, users might not be clear about the differences between these types or can accidentally create a mixture of different representations. For example, a Java programmer using JDBC might access a field in a SQL query using the class <code>java.sql.Date</code>. This class represents the value as an [=incremental time=] in UTC. This adds information inappropriately to [=floating time=] values or can remove zone-offset information from the original [=field-based time=] value.</p>
<p>Databases can use [=incremental time=] or either zone offset-dependent or independent field-based structures internally. For example, Oracle databases treat a <code>timestamp</code> field as though it is in the local time zone of the database instance. The combination of application and database time zones coupled with <em>implicit</em> conversions between [=incremental time=] and [=field-based time=] values can result in date/time values changing meaning without the user intending it.</p>
<p>In [[XMLSchema-2]], as with SQL, dates and times are expressed using [=field-based time=]. The date or time can express the zone offset from UTC (for example using a format such as <code>08:00:00+01:00</code>). [=UTC=] is indicated by the letter <code>Z</code> (for example <code>08:00:00Z</code>). The zone offset can also be omitted (producing a [=floating time=] value).</p>
<p>Properly speaking, an XML Schema date or time value with a zone offset is field-based/zone offset dependent and one without is field-based/floating.</p>
<p>If the two types are mixed, then the interpretation of the zone offset is not adequately specified in XML Schema. In [[XPATH-FUNCTIONS]], the interpretation is implementation-defined and is based on an implicit zone offset. This is usually either UTC or whatever the local time offset of the host environment is. The presence or absence of the zone offset in the XML Schema serialized representation might not be indicative of the original data's intention because of the confusion described above. Proper comparisons or processing rely on normalizing all date and time values into [=floating time=] or zone offset-dependent (field-based zone-dependent) forms and never mixing the two in a particular operation.</p>
</section>
<section id="serializations">
<h3>Serializations</h3>
<p>Date/time values often need to be serialized (converted to some string representation) for exchange in various document formats and protocols. Sometimes these serializations can be produced from or used to instantiate [=incremental time=], [=field-based time=], or [=floating time=] datatype values directly. Precisely which serialization to use depends on the application's <a href="#use-cases">use case</a> and available standards. Serializations that use time zone IDs instead of relying on offsets are RECOMMENDED.</p>
<aside class="note">
<p>The serializations in this section that utilized time zone IDs (and not just offsets) were only recently standardized, in [[RFC9557]]. Other standards, such as XMLSchema, cannot currently represent these values.</p>
</aside>
<table class="serialization-table">
<thead>
<tr>
<th>Type Being Serialized</th>
<th>Serialization to Use</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>Instant, Timestamp, Date</td>
<td><code>2007-01-01T01:00:00.000Z</code></td>
<td>An <a>incremental time</a> (instant on the timeline) with UTC offset.</td>
</tr>
<tr>
<td>OffsetDateTime</td>
<td><code>2007-01-01T01:00:00.000+01:00</code></td>
<td>An <a>incremental time</a> with an explicit offset from UTC. Zoned Instant is preferred.</td>
</tr>
<tr>
<td>Zoned Offset DateTime</td>
<td><code>2007-01-01T01:00:00.000+01:00[America/Chicago]</code></td>
<td>An <a>incremental time</a> with an offset <em>and</em> a specific time zone. The time zone should be used when formatting the value for display. Note that the offset and the time zone do not have to match. Generally the offset date time is converted to an instant on the timeline using the offset provided and then the time zone specified is attached to that moment.</td>
</tr>
<tr>
<td>Zoned Instant</td>
<td><code>2007-01-01T01:00:00.000Z[America/Chicago]</code></td>
<td>An <a>incremental time</a> with a specific time zone that should be used when formatting the value for display.</td>
</tr>
<tr>
<td>Zoned Local Date Time</td>
<td><code>2007-01-01T01:00:00.000[America/Chicago]</code></td>
<td>A <a>floating time</a> value with both a date and a time plus a specific time zone that should be used when displaying the time value. This serialization is equivalent to a zoned offset date time when the offsets match.</td>
</tr>
<tr>
<td>Local Date Time</td>
<td><code>2007-01-01T01:00:00.000</code></td>
<td>A <a>floating time</a> value containing both a date and a time.</td>
</tr>
<tr>
<td>Local Date</td>
<td><code>2007-01-01</code></td>
<td>A <a>floating time</a> with a date but no time component.</td>
</tr>
<tr>
<td>Local Time</td>
<td><code>00:00:00.000</code></td>
<td>A <a>floating time</a> with a time but no date component.</td>
</tr>
<tr>
<td>Year-Month</td>
<td><code>2007-01</code></td>
<td>A <a>floating time</a> value containing only a year and a month. Similar to [[XMLSchema-2]] <code>gYearMonth</code>.</td>
</tr>
<tr>
<td>Year</td>
<td><code>2007</code></td>
<td>A <a>floating time</a> value containing only a year. Similar to [[XMLSchema-2]] <code>gYear</code>.</td>
</tr>
<tr>
<td>Month-Day</td>
<td><code>01-01</code></td>
<td>A <a>floating time</a> value containing only a month and day. Similar to [[XMLSchema-2]] <code>gMonthDay</code>.</td>
</tr>
</tbody>
</table>
</section>
</section>
</section><!-- /concepts -->
<section id="use-cases">
<h2>Use Cases</h2>
<p>There are a number of ways applications can use date and time values. In this section we examine the different common use cases and the serializations or data structures to use for each.</p>
<section id="timestamp-use-case">
<h3>Timestamps</h3>
<p class="advisement">Use an incremental time value such as the <code>Instant</code> or <code>Date</code> type for timestamp values.</p>
<p><strong>This is the most common use case: use a timestamp unless you have a reason not to.</strong> If your application can accurately generate incremental and/or field-based times based on UTC and the events are not tied to specific local time, all that is needed is the timestamp value itself. That is, if your application never needs to recover what the local <a>wall time</a> was when event occurred and only cares about relative ordering of events. For example, if you merge log files from many machines together or if you are recording events in a log, a timestamp is perfectly adequate. For these types of time events, an Instant is sufficient.</p>
<p>It is usually desirable to normalize timestamp values to UTC (or, less commonly, a specific UTC offset) so that separate series of data can be easily compared and merged. Information about local offset may be valuable in recovering the actual wall time, but time zone rules are probably only rarely interesting.</p>
<p class="advisement">When in doubt, use [=UTC=] for serializing, storing, and exchanging date and time values.</p>
<p>Bear in mind that the [=local time offset=] doesn't change the relationship of a datetime value to the [=timeline=]. Serializing timestamp values with an offset makes the values more difficult to work with, particularly in systems where multiple offsets might be in use.</p>
<p>In other use cases, we'll see that storing the [=time zone=] is valuable or even required for consistent results. However, this never applies to timestamp values. The only thing that storing the [=time zone=] might provide is the originating [=wall time=].</p>
</section>
<section id="past-or-future">
<h3>Handling past or future events</h3>
<p>Many applications need to work with events that have already occurred, events in the future, or both. When working with these types of values, additional care needs to be used to avoid problems with the way that time zones interact with events.</p>
<aside class="example" title="Example of a time zone change affecting a future event" id="certificate-example">
<p>For example, consider an application that defines certificates. Each certificate has a date-time value that is the "start of authority" (<code>validFrom</code>) moment and a date-time value that is the "end of authority" (<code>validUntil</code>) moment.</p>
<p>Imagine that Certificate A is generated in the time zone <code>America/Los_Angeles</code>. This time zone has a raw offset from UTC of 8 hours and it currently observes [=daylight savings time=] between a date in March and a date in November. Certificate A is generated with a <code>validUntil</code> value of <code>2035-07-12T12:00:00-07:00</code>, reflecting the observation of DST during the month of July.</p>
<p>After Certificate A was generated (but before it expires), imagine that the time zone <code>America/Los_Angeles</code> decides to stop observing [=daylight savings time=]. Then imagine a user wishes to generate Certificate B to replace Certificate A when it expires. If the new certificate is valid "from noon on 12 July", it might be serialized as <code>2035-07-12T12:00:00-08:00</code>, because the time zone's offset will not be in DST any longer. Notice that this is one hour later than the actual expiration of Certificate A.</p>
</aside>
<section id="past-only-use-case">
<h3>Past-only Events</h3>
<p class="advisement">You SHOULD use <code>ZonedInstant</code> type for past-only events.</p>
<p class="advisement">You MAY use <code>ZonedInstant</code>, <code>ZonedLocalDateTime</code> or <code>ZonedOffsetDateTime</code> types for past events.</p>
<p>For an application that deals only with events that occurred in the past (with no future events) and for which you need to know what the wall time was, the <a>local time offset</a> of the event may be necessary additional data. Note that the time zone also provides the <a>local time offset</a> and is, thus, an acceptable substitute.</p>
<p>Once an event is in the past, its <a>local time offset</a> to <a>UTC</a> becomes fixed. Therefore an incremental time with an offset can always produce <a>wall time</a> in a given <a>chronology</a>.</p>
<p>Although <a>local time offset</a> is sufficient, knowing the specific time zone allows the application to reconstruct the time and its relationship to other time values and is usually more convenient when formating the value for display. For example, without the time zone identifier, it's not possible to accurately include the time zone's name or abbreviation into the display.</p>
</section>
<section id="past-future-use-case">
<h3>Past and Future Events</h3>
<p class="advisement">You SHOULD use <code>ZonedInstant</code> type if your application can have events in the future.</p>
<p>For an application that deals with both past and future events (for example, if you have a calendar or a meeting schedule), you will need the time zone (and not merely the <a>local time offset</a>) to ensure proper time computation. This is because a future event's <a>wall time</a> depends on time zone-related information, such as summer time transitions.</p>
<p>One issue with future events is that rules for the event's associated time zone can <a href="#tz-stability">change from time to time</a> and these changes can require an application to update affected data records in order to meet the user’s expectations. This is because many systems actually store or depend on using an <a>incremental time</a> value for date/time related operations (such as scheduling or notifications). When the time zone rules change, the corresponding the incremental time value needs to be checked or updated if the <a>wall time</a> of the event is expected to stay the same. See <a href="#certificate-example">above</a> for an example.</p>
<aside class="note">
<p>Applications that pre-compute or store <a>incremental time</a> values for future events might need to refresh the values after the local runtime's copy of the time zone database is updated, since time zone rules affecting these values might have been updated.</p>
</aside>
</section>
<section id="recurring-use-case">
<h3>Recurring Events</h3>
<p>A recurring event, such as a regular meeting, is usually defined by a set of rules that express a user's intent. In many cases, the user intends for the event to recur at a specific local <a>wall time</a> in a specific time zone. Each iteration is thus a <a href="#past-future-use-case">past or future event</a>.</p>
<p>Each iteration of the event will need to compute a specific (<a>incremental time</a> value) start time and this value will depend on the governing time zone's rules regarding <a>local time offset</a>, summer time transitions, and the like. It is important to use the time zone to perform these computations, as this avoids problems with assuming that the number of units between events (such as hours in a week or minutes in a day) is fixed. It can also help avoid <a>ghost times</a>.</p>
</section>
<section id="floating-use-case">
<h3>Floating Time Values</h3>
<p class="advisement">You SHOULD use the appropriate floating time type, such as <code>LocalDateTime</code> (for values with both date and time), <code>LocalDate</code> (for date values), or <code>LocalTime</code> (for time-only values) for values that are not tied to a specific offset or time zone rules.</p>
<p>If your application deals with a date or time value that is not tied to a specific local interpretation or which needs to be interpreted as a different range of incremental time values in different locations, serializing the value without an offset or time zone identifer communicates that the value is a <a>floating time</a>.</p>
<p>Such applications are more common than they first appear. We've already seen examples in this document, such as a list of holidays or a user's birth date. Any "anniversary" type of date (hire date, termination date, wedding date, etc.) is generally best representated a [=floating time=] value. Another application is when you collect statistics using [=instants=] but need to group them into durable time buckets by [=floating=] the values.</p>
</section>
</section>
<section id="additional-considerations">
<h2>Additional Considerations</h2>
<section>
<h3>General Recommendations</h3>
<p class="advisement">Whenever possible, use [=UTC=] or choose a consistent time zone when creating time-based content or data value so that values from discrete sources can be compared more readily.</p>
<aside class="example">
<p>It is much easier to work with and debug data values that can be compared visually. When values use different offsets or time zones, the user has to mentally translate the value. This can lead to mistakes. When you read the "mixed offset" list of timestamps below, is it easy to spot that the last two items are identical or that the first three are different?</p>
<table class="mixed-offset-table">
<thead>
<tr>
<th>Mixed Offsets</th>
<th>Same value converted to UTC</th>
</tr>
</thead>
<tbody>
<tr>
<td>
2007-01-01T01:00:00.000-01:00<br>
2007-01-01T01:00:00.000Z<br>
2007-01-01T01:00:00.000+01:00<br>
2006-12-31T23:00:00.000-01:00
</td>
<td>
2007-01-01T02:00:00.000Z<br>
2007-01-01T01:00:00.000Z<br>
2007-01-01T00:00:00.000Z<br>
2007-01-01T00:00:00.000Z
</td>
</tr>
</tbody>
</table>
</aside>
<p class="advisement">Bear in mind best practices to assist users in selecting their time zone, including keeping track of their preferences.</p>
<p>Some best practices when implementing time zone selection and management:
<ul>
<li>Allow the user to choose a time zone and keep it associated with the user's session or profile if possible.
<li>Consider using exemplar cities to help users identify the time zone.
<li>Use the country as a hint, since most countries <a href="#select-lto">have only a single time zone</a>.
<li>Omit historical time zones whenever possible.
<li>Use IP-geolocation, cellular radio country code, GPS data, or other external data sources if available.
</ul>
</p>
<section id="xslt">
<h4>Working with XQuery/XPath/XSLT</h4>
<p>If you are a users of specifications such as XQuery [[XQUERY-10]] and XSLT [[XSLT-30]] and other, similar, standards, in addition to the guidelines found elsewhere in this document, take the following into account even if time-zone-sensitive data is rarely used. Sooner or later some data will be affected by the issues described.</p>
<p class="advisement">Use an explicit zone offset with date, time, and dateTime types, if possible. Include an additional field indicating the time zone if one is not provided.</p>
<p class="advisement">Do not apply operations based on date or time types (such as indexing) to collections of data in which some data items have zone offset information while other data items do not have zone offset information.</p>
<p class="advisement">If you have data that includes implicit and fixed explicit [=local time offsets=], before applying any date- or time-sensitive operations, adjust the zone offset of the implicit data to UTC with functions for zone offset adjustment, cf. <a data-cite="xpath-functions#dateTime-arithmetic">this section</a> in [[[xpath-functions]]].</p>
<p class="advisement">If you have data that contains both implicit and fixed explicit [=local time offsets=] and you do not want to adjust the data subset which already has a zone offset, make sure that you recognize this data subset, for example via the <a data-cite="xpath-functions#component-extraction-dateTime">component extraction functions</a> [[XPATH-FUNCTIONS]].</p>
</section>
</section>
<section id="leap-seconds">
<h3>Leap Seconds</h3>
<p>One quirk of timekeeping is the need for leap seconds. The Earth's rotation is not even and, in general, is slowing down. To keep <a>observed time</a> and <a>incremental time</a> in sync, the [<a href="http://maia.usno.navy.mil/">International Earth Rotation Service</a>] occasionally mandates a "leap second". A leap second usually occurs once or sometimes twice per year and always takes the form of an additional second added to the last minute of the day. Usually the leap second is added to December 31st or June 30th.</p>
<p>Most incremental time values (do not keep track of leap seconds in their incremental time values. What happens is:</p>
<ol>
<li>Eventually, system clocks are updated externally by the user or via a service such as NTP. Most computer clocks exhibit some amount of clock drift anyway, so this sort of maintenance is not unusual.</li>
<li>No list is kept of past or future leap seconds (and no list exists for dates preceding the advent of leap seconds in 1972), so software often doesn't include leap seconds when calculating the difference between two time values. For example, the difference between 12:00:00 Noon on December 31st and 12:00:00 Noon on the following January 1st will always be 86400 seconds, even if a leap second was mandated for the intervening midnight.</li>
<li>There may be no way to represent a leap second time value using your local incremental units and may not be a means of representing a leap second using field-based units. For example, while Java's <code>java.util.Calendar</code> class allows for a "61st" second of a minute to accommodate leap seconds, if you set a Java Calendar to the equivalent of <kbd>December 31, 2008 23:59:60 UTC</kbd> (a particular leap second value) and then convert that to a <code>java.util.Date</code> in order to print it out, you might see: "January 1, 2009 00:00:00 UTC". This is because the <code>Date</code> object is an [=incremental time=] and the code formatting the value doesn't know about the leap second.</li>
</ol>
<p>If your application cares about or is sensitive to leap seconds, special care must be taken to deal with the loss of leap second precision.</p>
</p>
</section>
</section>
</section>
</body>
</html>