RFC 7808
Time Zone Data Distribution Service
Time Zone Data Distribution Service ๐โจ
Okay bestie, this one is RFC 7808, published in March 2016 as a Standards Track document by the Internet Engineering Task Force (IETF) ๐ . The authors are M. Douglass (Spherical Cow Group) and C. Daboo (Apple), and it's ISSN 2070-1721. No Obsoletes or Updates line shows up in the title block, so it doesn't replace or change any earlier RFC. It's giving official standards energy ๐.
Abstract
This doc defines a time zone data distribution service ๐ฆ that lets time zone data and leap-second rules get delivered reliably, securely, and fast to client systems. Those clients can be calendaring and scheduling apps or operating systems, so basically anything that needs to know what time it is ๐ฐ๏ธ๐.
Status of This Memo
This is an Internet Standards Track document ๐ธ.
This document is a product of the Internet Engineering Task Force (IETF) ๐. It represents the consensus of the IETF community. It got public review and was approved for publication by the Internet Engineering Steering Group (IESG). If you want more info on Internet Standards, check Section 2 of RFC 5741 โจ.
For the current status of this document, any errata, and how to send feedback, go to http://www.rfc-editor.org/info/rfc7808 ๐.
Copyright Notice
Copyright (c) 2016 IETF Trust and the persons identified as the document authors. All rights reserved ๐ .
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info) as in effect on the date of publication. Please read these carefully, because they explain your rights and restrictions for this document ๐. Code Components pulled out of this document must include Simplified BSD License text, as described in Section 4.e of the Trust Legal Provisions, and they come without warranty, as described in the Simplified BSD License ๐ซถ.
Table of Contents
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 4
1.1. Conventions . . . . . . . . . . . . . . . . . . . . . . . 4
2. Architectural Overview . . . . . . . . . . . . . . . . . . . 5
3. General Considerations . . . . . . . . . . . . . . . . . . . 7
3.1. Time Zone . . . . . . . . . . . . . . . . . . . . . . . . 7
3.2. Time Zone Data . . . . . . . . . . . . . . . . . . . . . 7
3.3. Time Zone Metadata . . . . . . . . . . . . . . . . . . . 7
3.4. Time Zone Data Server . . . . . . . . . . . . . . . . . . 7
3.5. Observance . . . . . . . . . . . . . . . . . . . . . . . 7
3.6. Time Zone Identifiers . . . . . . . . . . . . . . . . . . 7
3.7. Time Zone Aliases . . . . . . . . . . . . . . . . . . . . 8
3.8. Time Zone Localized Names . . . . . . . . . . . . . . . . 8
3.9. Truncating Time Zones . . . . . . . . . . . . . . . . . . 9
3.10. Time Zone Versions . . . . . . . . . . . . . . . . . . . 10
4. Time Zone Data Distribution Service Protocol . . . . . . . . 10
4.1. Server Protocol . . . . . . . . . . . . . . . . . . . . . 10
4.1.1. Time Zone Queries . . . . . . . . . . . . . . . . . . 11
4.1.2. Time Zone Formats . . . . . . . . . . . . . . . . . . 11
4.1.3. Time Zone Localization . . . . . . . . . . . . . . . 12
4.1.4. Conditional Time Zone Requests . . . . . . . . . . . 12
4.1.5. Expanded Time Zone Data . . . . . . . . . . . . . . . 14
4.1.6. Server Requirements . . . . . . . . . . . . . . . . . 14
4.1.7. Error Responses . . . . . . . . . . . . . . . . . . . 14
4.1.8. Extensions . . . . . . . . . . . . . . . . . . . . . 14
4.2. Client Guidelines . . . . . . . . . . . . . . . . . . . . 14
4.2.1. Discovery . . . . . . . . . . . . . . . . . . . . . . 14
4.2.1.1. SRV Service Labels for the Time Zone Data
Distribution Service . . . . . . . . . . . . . . 15
4.2.1.2. TXT Records for a Time Zone Data Distribution
Service . . . . . . . . . . . . . . . . . . . . . 15
4.2.1.3. Well-Known URI for a Time Zone Data Distribution
Service . . . . . . . . . . . . . . . . . . . . . 16
4.2.1.3.1. Example: Well-Known URI Redirects to Actual
Context Path . . . . . . . . . . . . . . . . 17
4.2.2. Synchronization of Time Zones . . . . . . . . . . . . 17
4.2.2.1. Initial Synchronization of All Time Zones . . . . 17
4.2.2.2. Subsequent Synchronization of All Time Zones . . 17
4.2.2.3. Synchronization with Preexisting Time Zone Data . 18
5. Actions . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
5.1. "capabilities" Action . . . . . . . . . . . . . . . . . . 18
5.1.1. Example: get capabilities . . . . . . . . . . . . . . 19
5.2. "list" Action . . . . . . . . . . . . . . . . . . . . . . 21
5.2.1. Example: List Time Zone Identifiers . . . . . . . . . 22
5.3. "get" Action . . . . . . . . . . . . . . . . . . . . . . 23
5.3.1. Example: Get Time Zone Data . . . . . . . . . . . . . 24
5.3.2. Example: Conditional Get Time Zone Data . . . . . . . 25
5.3.3. Example: Get Time Zone Data Using a Time Zone Alias . 25
5.3.4. Example: Get Truncated Time Zone Data . . . . . . . . 26
5.3.5. Example: Request for a Nonexistent Time Zone . . . . 27
5.4. "expand" Action . . . . . . . . . . . . . . . . . . . . . 27
5.4.1. Example: Expanded JSON Data Format . . . . . . . . . 29
5.5. "find" Action . . . . . . . . . . . . . . . . . . . . . . 30
5.5.1. Example: find action . . . . . . . . . . . . . . . . 31
5.6. "leapseconds" Action . . . . . . . . . . . . . . . . . . 32
5.6.1. Example: Get Leap-Second Information . . . . . . . . 33
6. JSON Definitions . . . . . . . . . . . . . . . . . . . . . . 34
6.1. capabilities Action Response . . . . . . . . . . . . . . 34
6.2. list/find Action Response . . . . . . . . . . . . . . . . 37
6.3. expand Action Response . . . . . . . . . . . . . . . . . 38
6.4. leapseconds Action Response . . . . . . . . . . . . . . . 39
7. New iCalendar Properties . . . . . . . . . . . . . . . . . . 40
7.1. Time Zone Upper Bound . . . . . . . . . . . . . . . . . . 40
7.2. Time Zone Identifier Alias Property . . . . . . . . . . . 41
8. Security Considerations . . . . . . . . . . . . . . . . . . . 42
9. Privacy Considerations . . . . . . . . . . . . . . . . . . . 43
10. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 44
10.1. Service Actions Registration . . . . . . . . . . . . . . 45
10.1.1. Service Actions Registration Procedure . . . . . . . 45
10.1.2. Registration Template for Actions . . . . . . . . . 46
10.1.3. Actions Registry . . . . . . . . . . . . . . . . . . 47
10.2. timezone Well-Known URI Registration . . . . . . . . . . 47
10.3. Service Name Registrations . . . . . . . . . . . . . . . 47
10.3.1. timezone Service Name Registration . . . . . . . . . 47
10.3.2. timezones Service Name Registration . . . . . . . . 48
10.4. TZDIST Identifiers Registry . . . . . . . . . . . . . . 48
10.4.1. Registration of invalid-action Error URN . . . . . . 49
10.4.2. Registration of invalid-changedsince Error URN . . . 49
10.4.3. Registration of tzid-not-found Error URN . . . . . . 50
10.4.4. Registration of invalid-format Error URN . . . . . . 50
10.4.5. Registration of invalid-start Error URN . . . . . . 50
10.4.6. Registration of invalid-end Error URN . . . . . . . 51
10.4.7. Registration of invalid-pattern Error URN . . . . . 51
10.5. iCalendar Property Registrations . . . . . . . . . . . . 52
11. References . . . . . . . . . . . . . . . . . . . . . . . . . 52
11.1. Normative References . . . . . . . . . . . . . . . . . . 52
11.2. Informative References . . . . . . . . . . . . . . . . . 55
Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . 55
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 56
1. Introduction โจ
Time zone data usually bundles a coordinated universal time (UTC) offset together with daylight saving time (DST) rules ๐. Time zones are typically tied to specific geographic and geopolitical regions ๐บ๏ธ. The UTC offset for a region changes pretty rarely, but DST rules can change often, and sometimes with barely any warning, maybe just hours before a change takes effect ๐ญ.
Calendaring and scheduling systems, like the ones that use iCalendar [RFC5545], plus operating systems, critically rely on time zone data to figure out the correct local time ๐ . So they need to be kept up to date with changes to that data. Until now, there hasn't been any fast and easy way to do that ๐. Time zone data often comes as a set of data files that have to be "compiled" into a suitable database format before the client app or OS can use it. For operating systems, those changes often only reach client machines with an OS update, and those updates can be infrequent, so inaccurate time zone data can hang around for a long time ๐. Some old OS versions stop being supported but are still in use, which means users have to manually "patch" their system to keep up with time zone changes ๐ฅฒ.
Along with time zone data, it's also important to track leap seconds, so there's a mapping between International Atomic Time (TAI) and UTC ๐ง. Leap seconds can be added (or possibly removed) at various times of the year, in an irregular pattern that's typically decided by precise astronomical observations ๐ญ. Inserting leap seconds into UTC is currently the job of the International Earth Rotation Service ๐.
This specification defines a time zone data distribution service protocol that allows fast, reliable, and accurate delivery of time zone data and leap-second information to client systems ๐๐. The protocol is based on HTTP [RFC7230] and uses a simple JSON-based API [RFC7159] ๐.
This specification does not define the source of the time zone data or leap-second information. It's assumed that a reliable and accurate source is available ๐ซถ. One such source is the IANA-hosted time zone database [RFC6557] ๐.
1.1. Conventions ๐
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC2119] ๐.
Unless otherwise indicated, UTC date-time values as specified in [RFC3339] use a "Z" suffix, and not fixed numeric offsets โฐ.
This specification contains examples of HTTP requests and responses. In some cases, extra line breaks were added to the request or response data so it fits the maximum line-length limits of this document ๐ฆ.
2. Architectural Overview โจ
okay so let's look at the big picture ๐ง The whole process of getting time zone data from its source to your app can be visualized with this diagram:
==================== ====================
(a) | Contributors | | Contributors |
==================== ====================
| |
==================== ====================
(b) | Publisher A | | Publisher B |
==================== ====================
\ /
====================
(c) | Root Provider |
====================
/ | \
/ | \
====================== | ======================
(d) | Secondary Provider | | | Secondary Provider |
====================== | ======================
| | | |
| | | |
========== ========== ========== ==========
(e) | Client | | Client | | Client | | Client |
========== ========== ========== ==========
Figure 1: Time Zone Data Distribution Service Architecture
The overall service is giving layers ๐ Here they are:
- (a) Contributors: Individuals, governments, or organizations that provide information about time zones to the publishing process. There can be many contributors. Note that this specification does not address how contributions are made ๐
- (b) Publishers: Publishers gather info from contributors, figure out how reliable it is, and then use that to generate time zone data. There can be many publishers, and each one can get info from lots of different contributors. Sometimes a publisher chooses to "republish" data from another publisher ๐
- (c) Root Providers: Servers that get the time zone data from publishers and then provide it to other servers or clients. There can be many root providers. A root provider can choose to supply data from one or more publishers ๐
- (d) Secondary Providers: Servers that handle the bulk of the requests and take some pressure off the root servers ๐ These are usually simple caches of a root server, placed closer to clients. For example, a big Internet Service Provider (ISP) might set up its own secondary provider so clients on its network can ask that server instead of servers outside the network. Secondary servers cache data and refresh it from the root servers every so often โฐ
- (e) Clients: Applications, operating systems, and so on, that use time zone data and retrieve it from either a root provider or a secondary provider ๐ฑ
Implementors are allowed to coalesce some of those layers ๐งฉ For example, a vendor could build the entire service as one monolithic virtual server, with the address embedded in distributed systems. Others might go with multiple layers of providers, lots of secondary servers, and just a few root servers ๐
Okay, so this specification only cares about the protocol used to exchange data between providers, and from a provider to a client ๐ฆ It does not define how contributors pass their info to publishers, how publishers vet that info to get trustworthy data, or the format of the data the publishers produce. Those are all out of scope bestie ๐ซถ
3. General Considerations โจ
This section defines a few terms and explains some key concepts used in this specification ๐ง
3.1. Time Zone ๐
A time zone is a description of the past and predicted future timekeeping practices of a collection of clocks that are intended to agree โฑ๏ธ
Heads up: the term "time zone" does not mean the everyday idea of a region of the world at a specific UTC offset, possibly tweaked by daylight saving time ๐
โโ๏ธ For example, the "Central European Time" zone can correspond to several time zones, like Europe/Berlin and Europe/Paris, because subregions have kept time differently in the past.
3.2. Time Zone Data ๐พ
Time zone data is data that defines a single time zone. It includes an identifier, UTC offset values, DST rules, and other info like time zone abbreviations โจ
3.3. Time Zone Metadata ๐ท๏ธ
Time zone metadata is data that describes extra properties of a time zone that are not included in the time zone data itself. This can be things like the publisher name, a version identifier, aliases, and localized names (more on those below) ๐
3.4. Time Zone Data Server ๐ฅ๏ธ
A time zone data server is a server that implements the Time Zone Data Distribution Service Protocol defined by this specification ๐ฆ
3.5. Observance ๐ฐ๏ธ
A time zone with varying rules for its UTC offset will have back-to-back periods of time that use different UTC offsets. Each period of time with a constant UTC offset is called an observance ๐ธ
3.6. Time Zone Identifiers ๐
Time zone identifiers are unique names associated with each time zone, as defined by publishers. The iCalendar [RFC5545] specification has a TZID property and parameter. Its value is set to the matching time zone identifier and is used to identify time zone data and link time zones to start and end dates in events, and so on ๐
This specification does not define what format time zone identifiers should use. It's possible that identifiers from different publishers overlap, and a provider might need to tell them apart with some kind of "namespace" prefix that identifies the publisher ๐ However, creating a standard (global) naming scheme for time zone identifiers is out of scope for this specification ๐
3.7. Time Zone Aliases ๐ญ
Time zone aliases map a name onto a time zone identifier. For example, US/Eastern is usually mapped onto America/New_York. When presenting info to users, aliases are typically used interchangeably with time zone identifiers ๐
A time zone data distribution service needs to maintain time zone alias mapping info and expose that data to clients. It also needs to let clients query for time zone data using aliases ๐ When a server returns time zone data to a client, it returns the data with an identifier that matches the query. But it can also include one or more additional identifiers in the data, as a hint that alternative identifiers are available. For example, a query for US/Eastern could come back with extra identifiers for America/New_York or America/Montreal ๐
The set of aliases can vary depending on whether the time zone data is truncated (see Section 3.9). For example, a client in the US state of Michigan might see US/Eastern as an alias for America/Detroit, while a client in the US state of New Jersey might see it as an alias for America/New_York. And all three names could be aliases if time zones are truncated to post-2013 data ๐คฏ
3.8. Time Zone Localized Names ๐
Localized names are names for time zones that can be shown to a user in their own language. Each time zone may have one or more localized names associated with it. Names are typically unique within their own locale, since they might be shown to the user in a list ๐ Localized names are different from the abbreviations commonly used for UTC offsets within a time zone. For example, the time zone America/New_York may have the localized name "Nueva York" in a Spanish locale. That's distinct from the abbreviations "EST" and "EDT", which may or may not have their own localizations ๐ช๐ธ
A time zone data distribution service might need to maintain localized name info for one or more chosen languages. It might also need to let clients query for time zone data using localized names ๐ฃ๏ธ
3.9. Truncating Time Zones โ๏ธ
Time zone data can contain info about past and future UTC offsets that isn't relevant to a particular server's intended clients. For example, calendaring and scheduling clients mostly care about time zone data covering a period of about one or two years in the past and onward into the future, since users usually create new events only for the present and future ๐ Time zone data can also hold a lot of "future" info about transitions happening many decades out. Clients may only care about a smaller range going forward, so data past that point might be unnecessary ๐
To avoid sending unnecessary data, servers can choose to truncate time zone data to a range set by start and end date-time values. They then provide only offsets and rules between those points ๐ If truncation is done, the server MUST include the ranges it is using in the capabilities action response (see Section 6.1), so clients can take the right action if they need time zone data for times outside those ranges ๐
The truncation points at the start and end of a range are always a UTC date-time value. The start point is "inclusive" to the overall range, and the end point is "exclusive" to it. In other words, the end value is just past the end of the last valid value in the range ๐ฏ A server will advertise a truncation range for the truncated data it can supply, or it will provide an indicator that it can truncate at any start or end point to produce arbitrary ranges ๐ช A server can also advertise that it supplies untruncated data, meaning data that covers the full range of times available from the source publisher ๐ If there's no indication of truncated data on the server, the server will supply only untruncated data ๐ซถ
When truncating the start of a VTIMEZONE component, the server MUST include exactly one STANDARD or DAYLIGHT subcomponent. That subcomponent needs a DTSTART property value that matches the start point of the truncation range, plus appropriate TZOFFSETFROM and TZOFFSETTO properties that show the correct offset in effect right before and right after the start point of the truncation range ๐ This subcomponent is the first observance defined by the time zone data. It represents the earliest valid date-time covered by the time zone data in the truncated VTIMEZONE component ๐ฐ๏ธ
When truncating the end of a VTIMEZONE component, the server MUST include a TZUNTIL iCalendar property (Section 7.1) in the VTIMEZONE component. That property indicates the end point of the truncation range ๐
3.10. Time Zone Versions
okay bestie, time zone data keeps changing ๐ฐ๏ธ so consumers have to stay up to date โจ. that's why it's so useful to tag each time zone with a specific version number or identifier from whoever published the data ๐ . there are two common models publishers use:
- a. the "monolithic" model ๐ฆ: all the time zones get published in one go, with a single version number or identifier slapped on the entire data set. a publisher dropping updates a few times a year might use ids like
2015a,2015b, etc. - b. the "incremental" model ๐งฉ: each time zone gets its own version identifier, so one can update without messing with any of the others. say the first data has version
A.1for time zoneAandB.1for time zoneB, and then time zoneBchanges. when the data is next published,Ais stillA.1, butBis nowB.2. iykyk ๐ฆ
a time zone data distribution service needs to make sure the version identifiers from the publisher are available to any client, along with the actual publisher name for each time zone ๐. that way clients can compare publisher/version details from any server against what they've already cached locally, and only fetch the time zones that actually changed (see Section 4.2.2 for more on how clients synchronize data from the server) ๐ซถ.
4. Time Zone Data Distribution Service Protocol โจ
4.1. Server Protocol
the time zone data distribution service protocol uses HTTP [RFC7230] to query and deliver time zone data, metadata, and leap-second information ๐ฌ. the interactions with the HTTP server can be broken into a set of "actions" that define the overall function being requested (see Section 5) ๐. each action targets a specific HTTP resource using the GET method, and different request-URI parameters tweak the behavior as needed.
the HTTP resources used for requests are identified via URI templates [RFC6570] ๐ง. the overall service has a "context path" request-URI template defined as {/service-prefix}. the client discovers this "root" prefix as per Section 4.2.1. request-URIs that target time zone data directly use the prefix template {/service-prefix,data-prefix}. the second component of that prefix template can add extra path segments so there are alternative ways to "partition" the time zone data. for example, the data might be partitioned by publisher release dates or version identifiers ๐. this spec doesn't define any partitions, though, that's left for future extensions ๐ฎ. when the data-prefix variable is empty, the server is expected to return the current version of time zone data it has for all publishers it supports.
All URI template variable values, and URI request parameters that contain text values, MUST be encoded using the UTF-8 [RFC3629] character set. All responses MUST return data using the UTF-8 [RFC3629] character set. โ ๏ธ heads up: any / characters, which show up a lot in time zone identifiers, get percent-encoded when they're used in the value of a path segment expansion variable in a URI template (as per Section 3.2.6 of [RFC6570]). so the time zone identifier America/New_York shows up as America%2FNew_York when it's the value for the {/tzid} URI template variable (that one's defined later in this spec) ๐ฝ.
the server gives time zone metadata as a JSON [RFC7159] object ๐. clients can request the metadata directly, or query for subsets of it that match specific criteria.
security and privacy considerations for this protocol are covered in detail in Sections 8 and 9, respectively ๐. don't skip those, they're serious business. ๐
4.1.1. Time Zone Queries
time zone identifiers, aliases, or localized names can all be used to query for time zone data or metadata ๐. each action will spell out the details more explicitly, but in general: if a tzid URI template variable is used, the value can be an identifier or an alias. when the pattern URI query parameter is used, it can be an identifier, an alias, or a localized name โจ.
4.1.2. Time Zone Formats
the default media type [RFC2046] format for returning time zone data is the iCalendar [RFC5545] data format ๐
. on top of that, iCalendar-in-XML [RFC6321] and iCalendar-in-JSON [RFC7265] representations are available too ๐. clients use the Accept header field (see Section 5.3.2 of [RFC7231]) to say which returned data format they prefer. servers tell clients which formats they support through the "capabilities" action response (Section 5.1) ๐.
4.1.3. Time Zone Localization
as per Section 3.8, time zone data can support localized names ๐. clients use the Accept-Language header field (see Section 5.3.5 of [RFC7231]) to say which language they'd like the localized names in the response to be in ๐ฃ๏ธ.
4.1.4. Conditional Time Zone Requests
when time zone data or metadata changes, it has to get distributed in a timely manner ๐จ, because changes to local time offsets can happen within a few days of the time zone data changes being published โณ. usually only a small number of time zones change, while the overall number of time zones can be huge ๐. so when a client is using more than a few time zones, it's way more efficient to download only the ones that changed (an incremental update) ๐คโจ.
clients first request a full list of time zones from the server using a "list" action request (see Section 5.2) ๐. the response includes two things the client caches for later "conditional" (incremental update) requests:
- an opaque synchronization token in the
synctokenJSON member ๐ช. this token changes whenever there's a change to any metadata associated with one or more time zones (where the metadata is the information reported in the "list" action response for each time zone). - the HTTP
ETagheader field value for each time zone returned in the response. theETagvalue is returned in theetagJSON member, and it matches theETagvalue that would come back from a "get" action request (see Section 5.3) against the corresponding time zone data resource ๐ท๏ธ.
for later updates to cached data, clients can follow this procedure ๐ :
- a. send a "list" action request with a
changedsinceURI query parameter set to the last opaque synchronization token the server returned ๐ค. the server will return time zone metadata for only the time zones that have changed since the last request. - b. the client caches the new opaque synchronization token from the response, for the next incremental update, along with the returned time zone metadata ๐พ.
- c. the client checks each time zone's metadata to see if its
etagvalue is different from that of any cached time zone data it has ๐. - d. the client uses a "get" action request to update any cached time zone data for the time zones whose
ETagvalue has changed ๐.
okay so here's the tea โ: time zone metadata will always change when the matching time zone data changes. the reverse isn't true though! a piece of the metadata can change without the time zone data changing ๐. for example, with a "monolithic" publisher (see Section 3.10), the version identifier in every time zone metadata element changes with each new published revision, but only a small subset of the time zone data actually changes ๐.
if a client only needs data for one time zone or a small set (say, a clock in a fixed location) ๐ฐ๏ธ, it can use a conditional HTTP request to check whether the time zone data changed and grab the new data if it did. the full details of HTTP conditional requests are in [RFC7232]. here's a quick summary of what a client typically does ๐:
- a. when the client retrieves the time zone data with a "get" action (see Section 5.3), the server includes an HTTP
ETagheader field in the response ๐ท๏ธ. - b. the client stores that header field's value along with the request-URI used for the request ๐๏ธ.
- c. when the client wants to check for an update, it sends another "get" action HTTP request to the original request-URI, but this time with an
If-None-MatchHTTP request header field set to theETagvalue from the previous response ๐. if the time zone data hasn't changed, the server returns a304 (Not Modified)HTTP response ๐ด. if it has changed, the server returns a normal HTTP success response with the changed data, plus a newETagheader field value โจ.
clients SHOULD poll for changes, using an appropriate conditional request, at least once a day. ๐ a server acting as a secondary provider, caching time zone data from another server, SHOULD poll for changes once per hour. โฐ check Section 8 for the expected client and server behavior around high request rates ๐ฆ.
4.1.5. Expanded Time Zone Data
working out time zone offsets at a particular moment is honestly a whole mess ๐ตโ๐ซ, because the daylight saving time rules can be super complex ๐. to help with that, the time zone data distribution service has an action that lets clients ask the server to expand a time zone into a set of "observances" over a fixed period of time (see Section 5.4) ๐ช. each observance describes a UTC onset time and UTC offsets for the prior time and the observance time. together, these give "thin" clients a quick way to find the right UTC offset for any date, without having to do the full time zone expansion themselves ๐ โจ.
4.1.6. Server Requirements
to keep client implementations simple, servers SHOULD ensure that they provide or cache data for all commonly used time zones, from various publishers. ๐ง that way, a client can be set up to point at a single server and get all the time zone data it needs ๐ฏ. any server can refresh any of the data from any other server ๐, though the root servers may have the most up-to-date copy of the data ๐.
4.1.7. Error Responses
when the client gets an HTTP error response, the server SHOULD return a JSON "problem details" object in the response body, as per [RFC7807]. ๐ Every JSON "problem details" object MUST include a type member with a URI value matching the applicable error code (defined for each action in Section 5). ๐ซถ that URI is how the client knows exactly what went wrong ๐๐.
4.1.8. Extensions โจ
okay bestie, so this protocol is built to be extensible ๐ through a standards-based registration mechanism (check out Section 10 for the deets ๐). The spec authors are literally already thinking about future features ๐ฎ like mapping a geographical location to time zone identifiers, or getting the change history for time zones ๐โฐ. So servers MUST return a description of their capabilities ๐ . Why? Because that lets clients figure out whether new features have been installed ๐, and if they haven't, the client can fall back on earlier features or switch off some of its own capabilities ๐ซถ. It's giving forward compatibility, no cap ๐ฆ.
4.2. Client Guidelines ๐
4.2.1. Discovery ๐
okay so clients either need to already know where the time zone data distribution service lives ๐ , or they need to discover it somehow ๐ต๏ธโโ๏ธ. To use the service, a client needs a Fully Qualified Domain Name (FQDN) ๐, a port ๐ช, and an HTTP request-URI path ๐ฃ๏ธ. The request-URI path you find through discovery is the "context path" ๐ for the service itself, and it becomes the value of the "service-prefix" URI template variable when actions get executed (see Section 5) โจ.
The next subsections describe two discovery methods: DNS SRV records [RFC2782] and an HTTP "well-known" [RFC5785] resource ๐ง. Alternative mechanisms could also work, like a DHCP server option [RFC2131] ๐ธ.
4.2.1.1. SRV Service Labels for the Time Zone Data Distribution Service ๐ท๏ธ
[RFC2782] defines a DNS-based service discovery protocol that's been super widely adopted ๐ for finding particular services on a local network and beyond, using SRV RR records ๐ก. It can be used to discover a service's FQDN and port ๐.
This spec adds two service types for SRV records:
timezone: identifies a time zone data distribution server that uses HTTP without Transport Layer Security ([RFC2818]) ๐.timezones: identifies a time zone data distribution server that uses HTTP with Transport Layer Security ([RFC2818]) ๐.
Clients MUST honor "TTL", "Priority", and "Weight" values in the SRV records, as described by [RFC2782] ๐ . No skipping that, bestie ๐ โโ๏ธ.
Example: service record for a server without Transport Layer Security ๐.
_timezone._tcp SRV 0 1 80 tz.example.com.
Example: service record for a server with Transport Layer Security ๐.
_timezones._tcp SRV 0 1 443 tz.example.com.
4.2.1.2. TXT Records for a Time Zone Data Distribution Service ๐
okay so when SRV RRs are used to advertise the service, it's super handy to also specify a "context path" in DNS so you can grab it at the same time ๐. To make that happen, this spec uses a TXT RR that follows the syntax in Section 6 of [RFC6763] ๐ and defines a "path" key for that record. The value of that key MUST be the actual "context path" to the matching service on the server ๐.
A site might give TXT records as well as SRV records for each service โจ. When they're there, clients MUST use the "path" value as the "context path" for the service in HTTP requests ๐ซถ. When they're not there, clients use the ".well-known" URI approach from Section 4.2.1.3 ๐ฆ.
As per Section 8, the server MAY require authentication when a client tries to access the path URI given by the TXT RR ๐. (So the server would return a 401 status response to an unauthenticated request from the client, and then send a redirect response once the client has authenticated successfully ๐.)
Example: text record for a service with Transport Layer Security ๐.
_timezones._tcp TXT path=/timezones
4.2.1.3. Well-Known URI for a Time Zone Data Distribution Service ๐
A "well-known" URI [RFC5785] is registered by this spec for the Time Zone Data Distribution service, "timezone" (see Section 10) ๐. This URI points to a resource the client can use as the initial "context path" for whatever service it's trying to reach ๐งโโ๏ธ. The server MUST redirect HTTP requests for that resource to the actual "context path" using one of the mechanisms HTTP provides (for example, an appropriate 3xx status response) ๐. Clients MUST handle HTTP redirects on the ".well-known" URI, taking into account the security restrictions on redirects described in Section 8 ๐ก๏ธ. Servers MUST NOT locate the actual time zone data distribution service endpoint at the ".well-known" URI, as per Section 1.1 of [RFC5785] ๐ โโ๏ธ. The "well-known" URI MUST be present on the server, even when a TXT RR (Section 4.2.1.2) is used in the DNS to specify a "context path" ๐ .
Servers SHOULD set an appropriate Cache-Control header field value (as per Section 5.2 of [RFC7234]) in the redirect response, so caching happens when it's needed or when the type of response requires it ๐ง . For example, if the redirect location might change over time, an appropriate "max-age" value would be used โณ.
As per Section 8, the server MAY require authentication when a client tries to access the ".well-known" URI (so the server would return a 401 status response to the unauthenticated request, then return the redirect response after the client authenticates successfully) ๐.
4.2.1.3.1. Example: Well-Known URI Redirects to Actual Context Path ๐ฆ
okay so a time zone data distribution server has a "context path" of "/servlet/timezone" ๐. The client will use "/.well-known/timezone" as the path for the service after it has found the FQDN and port number, either through an SRV lookup or by the user typing the info in manually โจ. When the client makes its first HTTP request against "/.well-known/timezone", the server issues an HTTP 301 redirect response with a Location response header field pointing to "/servlet/timezone" ๐. The client then "follows" that redirect to the new resource and keeps making HTTP requests there ๐โโ๏ธ. It also caches the redirect information, subject to any Cache-Control directive, for use in later requests ๐ง ๐.
4.2.2. Synchronization of Time Zones ๐
This section talks about possible client synchronization strategies, using the various protocol elements the server provides for that purpose ๐.
4.2.2.1. Initial Synchronization of All Time Zones ๐ธ
When a secondary service or a client that wants to cache all time zone data first starts up (or wants a full refresh), it syncs with another server by issuing a "list" action to get all the time zone metadata ๐. The client keeps the returned opaque token for later use (see "synctoken" in Section 5.2.1) ๐. The client stores the metadata for each time zone in the response ๐๏ธ. Then the time zone data for each matching time zone can be fetched and stored locally ๐พ. A mapping of aliases to time zones can also be built from the metadata ๐บ๏ธ. Just so you know the size, a typical "list" action response is about 50-100 KB of "pretty printed" JSON data, for a service using the IANA time zone database [RFC6557], as of the time this spec was published ๐ฆ.
4.2.2.2. Subsequent Synchronization of All Time Zones ๐
A secondary service or a client caching all time zones needs to sync with a server periodically ๐ฐ๏ธ. To do that, it issues a "list" action with the "changedsince" URI query parameter set to the opaque token returned by the last sync ๐ฏ. The client again keeps the new opaque token for later ๐. It updates its stored time zone metadata using the new values in the response, which only contains metadata for the time zones changed since the last sync โ๏ธ. It also compares the "etag" value in each time zone's metadata to the ETag header field value for the matching time zone data resource it cached earlier ๐. If they're different, it fetches the new time zone data ๐ฅ. Note that if the client sends a "changedsince" value the server doesn't support, all time zone data gets returned, just like when the request had no "changedsince" value at all ๐ซ .
Publishers should keep in mind that "outright" deleting time zone names causes problems for simple clients ๐, so aliasing a deleted time zone identifier to a suitable alternate one is preferable ๐ซถ.
4.2.2.3. Synchronization with Preexisting Time Zone Data ๐
A client might be pre-provisioned with time zone data from a source other than the time zone data distribution service it's configured to use ๐ฆ. In that case, the client might want to minimize how much time zone data it syncs ๐โโ๏ธ. It can do an initial "list" action to get all the time zone metadata, then only fetch time zone data for the time zones whose publisher and version details don't match the pre-provisioned data ๐ฏโจ.
5. Actions ๐ฌ
Servers MUST support the following actions ๐ . Each action below shows its details: the request-URI the client targets (in the form of a URI template [RFC6570]) ๐, a description, the set of allowed query parameters ๐, the nature of the response ๐จ, and a set of possible error codes for the response (see Section 4.1.7) ๐จ.
For any error not covered by the specific error codes defined below, the urn:ietf:params:tzdist:error:invalid-action error code is returned to the client in the JSON "problem details" object ๐.
The examples in the following subsections presume the timezone context path has been discovered to be "/servlet/timezone" (as in the example in Section 4.2.1.3.1) ๐.
5.1. "capabilities" Action ๐งฉ
Name: capabilities
Request-URI Template: {/service-prefix}/capabilities
Description: This action returns the capabilities of the server, so clients can tell if a specific feature has been deployed and/or enabled ๐.
Parameters: None
Response: A JSON object containing a "version" member, an "info" member, and an "actions" member; see Section 6.1 ๐ฆ.
Possible Error Codes: No specific code ๐ซถ.
<think>The system prompt has a directory note about untrusted downloaded files, not relevant here since the user just provided text. No tool needed. Just do the rewrite of part 5 in the Gen Z voice, keeping all details exact.
Key items: section 5.1.1 heading "### 5.1.1. Example: get capabilities" โ since the previous part covered 5.1 "capabilities" action, this part starts at 5.1.1 example. Carry on without repeating the 5.1 heading. Heading level: "###" for 5.1.1? The format says "#" for sections, "##" for subsections, "###" below. Section 5.1.1 is third level, so "###". Original has 5.2 as "list" action at level 2 under "5." Section 5 is "# 5. Actions". Since the previous part already did 5 and 5.1, I should use "## 5.2." for list action and "### 5.2.1." for example... Wait, 5.2 is a subsection of 5, so "## 5.2. "list" Action", and 5.2.1 is "### 5.2.1.". The 5.1.1 example is "### 5.1.1." under "## 5.1.". Good.
Note the instruction: "Keep every section... with its number exactly as written". Add flourish allowed but number and name stay. I'll write "### 5.1.1. Example: get capabilities โจ" etc.
BCP 14 keywords: in this part: "MUST" appears several times: list section: "its value MUST correspond", "server MUST return only", "server MUST return all time zones". "OPTIONAL" in parameters. "MUST NOT occur more than once" for changedsince. "REQUIRED" in get template: "The "tzid" variable value is REQUIRED". Get description: "The response MUST contain an ETag", "server MUST return ... text/calendar". "MAY include". "OPTIONAL, and MUST NOT occur more than once" for start and end (twice in get params each). Careful: keep exact count. Let's enumerate in original get section: "REQUIRED" (1), "MUST contain" (1), "MUST return" (1), "MAY include" (1). Parameters: start: "OPTIONAL, and MUST NOT occur more than once" (OPTIONAL 1, MUST NOT 1). end: same. So get: REQUIRED, MUST, MUST, MAY, OPTIONAL, MUST NOT, OPTIONAL, MUST NOT.
list: MUST (correspond), MUST (return only), MUST (return all), OPTIONAL, MUST NOT. Wait: "If the "changedsince" value is not supported by the server, the server MUST return all time zones" โ that's one MUST. So list: MUST, MUST, MUST, OPTIONAL, MUST NOT. Plus the earlier "its value MUST correspond" โ counted. Total 3 MUST in description + OPTIONAL + MUST NOT.
Get alias paragraph: "the server will return" โ lowercase "will", not a keyword. Keep as is.
Get, 5.3.2: no keywords. Capabilities example: none.
Also the "expand" action etc. in the JSON are in code blocks - keep verbatim. Code block contents must be exact; the 5.1.1 JSON, 5.2.1 JSON, etc. Within code blocks, don't use colour tags. Within code blocks, "MUST" none in those; the 5.3.4 truncated snippet has no keywords.
Be careful: Within code blocks, keep verbatim including "..." lines.
Error code lines: "urn:ietf:params:tzdist:error:invalid-changedsince" โ keep as inline code or in a block. Use inline code with the explanation.
Section 5.3 Request-URI Template has code block: "{/service-prefix,data-prefix}/zones{/tzid}{?start,end}". Keep verbatim.
Description of list: "with publisher, version, aliases, and optional localized data." Rewrite in voice but keep facts.
Parts of the 5.1.1 example: "Date: Wed, 4 Jun 2008 09:32:12 GMT" verbatim.
Note "5.3.4" the JSON snippet with "untruncated": false โ keep. The text "Note the presence of a "STANDARD" component" โ rewrite in voice with quotes preserved.
Don't sign off. No preamble. Output only rewrite. Let's write. Keep emojis, colour tags not wrapping keywords. Don't put colour tags inside backticks.
Keep "Request-URI Template:" field line in code block? Original is indented text, not code. The spec says copy grammars exactly in code blocks. The Name/Request-URI Template are structured; I'll put templates in code blocks. Parameters lists: I'll render as bullets.
Now write it. Keep "Response:" details. For 5.2 Response: "A JSON object containing a "synctoken" member and a "timezones" member; see Section 6.2." Keep Section 6.2 citation.
Ensure "optional" in lowercase not an issueโonly capitals matter. "optional localized data" lowercase fine.
Writing now.### 5.1.1. Example: get capabilities โจ
okay so here's what a capabilities request and response look like in real life ๐ฆ
Request <<
GET /servlet/timezone/capabilities HTTP/1.1
Host: tz.example.com
Response <<
HTTP/1.1 200 OK
Date: Wed, 4 Jun 2008 09:32:12 GMT
Content-Type: application/json; charset="utf-8"
Content-Length: xxxx
{
"version": 1,
"info": {
"primary-source": "Olson:2011m",
"formats": [
"text/calendar",
"application/calendar+xml",
"application/calendar+json"
],
"truncated" : {
"any": false,
"ranges": [
{
"start": "1970-01-01T00:00:00Z",
"end": "*"
},
{
"start":"2010-01-01T00:00:00Z",
"end":"2020-01-01T00:00:00Z"
}
],
"untruncated": true
},
"provider-details": "http://tz.example.com/about.html",
"contacts": ["mailto:tzs@example.org"]
},
"actions": [
{
"name": "capabilities",
"uri-template": "/servlet/timezone/capabilities",
"parameters": []
},
{
"name": "list",
"uri-template": "/servlet/timezone/zones{?changedsince}",
"parameters": [
{
"name": "changedsince",
"required": false,
"multi": false
}
]
},
{
"name": "get",
"uri-template": "/servlet/timezone/zones{/tzid}{?start,end}",
"parameters": [
{
"name": "start",
"required": false,
"multi": false
},
{
"name": "end",
"required": false,
"multi": false
}
]
},
{
"name": "expand",
"uri-template":
"/servlet/timezone/zones{/tzid}/observances{?start,end}",
"parameters": [
{
"name": "start",
"required": true,
"multi": false
},
{
"name": "end",
"required": true,
"multi": false
}
]
},
{
"name": "find",
"uri-template": "/servlet/timezone/zones{?pattern}",
"parameters": [
{
"name": "pattern",
"required": true,
"multi": false
}
]
},
{
"name": "leapseconds",
"uri-template": "/servlet/timezone/leapseconds",
"parameters": []
}
]
}
5.2. "list" Action ๐
Name: list
Request-URI Template:
{/service-prefix,data-prefix}/zones{?changedsince}
Description: this one lists every time zone identifier in summary format ๐ Each entry comes with its publisher, version, aliases, and optional localized data. It also hands back an opaque synchronization token for the whole response ๐ If the "changedsince" URI query parameter shows up, its value MUST correspond to a synchronization token that was returned earlier. When "changedsince" is used, the server MUST return only the time zones that changed since that token. And if the server doesn't support the "changedsince" value, the server MUST return all time zones, treating the request as if there was no "changedsince" at all. bestie, that's a fallback I'm obsessed with ๐ซถ
Parameters:
changedsince: OPTIONAL, and MUST NOT occur more than once.
Response: a JSON object with a "synctoken" member and a "timezones" member. See Section 6.2 ๐ธ
Possible Error Codes:
urn:ietf:params:tzdist:error:invalid-changedsince: the "changedsince" URI query parameter appears more than once. ๐ญ
5.2.1. Example: List Time Zone Identifiers ๐ง
here the client asks for the full set of time zone identifiers โจ
Request <<
GET /servlet/timezone/zones HTTP/1.1
Host: tz.example.com
Response <<
HTTP/1.1 200 OK
Date: Wed, 4 Jun 2008 09:32:12 GMT
Content-Type: application/json; charset="utf-8"
Content-Length: xxxx
{
"synctoken": "2009-10-11T09:32:11Z",
"timezones": [
{
"tzid": "America/New_York",
"etag": "123456789-000-111",
"last-modified": "2009-09-17T01:39:34Z",
"publisher": "Example.com",
"version": "2015a",
"aliases":["US/Eastern"],
"local-names": [
{
"name": "America/New_York",
"lang": "en_US"
}
]
},
...other time zones...
]
}
5.3. "get" Action ๐
Name: get
Request-URI Template:
{/service-prefix,data-prefix}/zones{/tzid}{?start,end}
The "tzid" variable value is REQUIRED so this action can be told apart from the "list" action. no mix-ups allowed ๐
Description: this action returns a time zone ๐ The response MUST contain an ETag response header field that shows the current value of the strong entity tag for the time zone resource.
If there's no Accept HTTP request header field, the server MUST return the time zone data with the "text/calendar" media type ๐
If the "tzid" variable value is actually a time zone alias, the server will return the matching time zone data and use the alias as the identifier inside that data. The server MAY include one or more "TZID-ALIAS-OF" properties (see Section 7.2) in the time zone data. Those tell you about other identifiers that share the same matching time zone identifier as an alias ๐ฆ
Parameters:
start=<date-time>: OPTIONAL, and MUST NOT occur more than once. This specifies the inclusive UTC date-time value where the returned time zone data gets truncated at its start ๐ธend=<date-time>: OPTIONAL, and MUST NOT occur more than once. This specifies the exclusive UTC date-time value where the returned time zone data gets truncated at its end ๐ธ
Response: a document with all the requested time zone data in the format that was specified ๐
Possible Error Codes:
urn:ietf:params:tzdist:error:tzid-not-found: no time zone matching the "tzid" path segment value was found. ๐urn:ietf:params:tzdist:error:invalid-format: the Accept request header field from the client didn't include a media type for time zone data that the server supports. ๐urn:ietf:params:tzdist:error:invalid-start: the "start" URI query parameter has an incorrect value, or it appears more than once, or it doesn't match one of the fixed truncation range start values advertised in the "capabilities" action response. ๐ญurn:ietf:params:tzdist:error:invalid-end: the "end" URI query parameter has an incorrect value, or it appears more than once, or its value is less than or equal to the "start" URI query parameter, or it doesn't match one of the fixed truncation range end values advertised in the "capabilities" action response. ๐ญ
5.3.1. Example: Get Time Zone Data ๐
in this one the client asks for a specific time zone by its identifier ๐ฝ
Request <<
GET /servlet/timezone/zones/America%2FNew_York HTTP/1.1
Host: tz.example.com
Accept:text/calendar
Response <<
HTTP/1.1 200 OK
Date: Wed, 4 Jun 2008 09:32:12 GMT
Content-Type: text/calendar; charset="utf-8"
Content-Length: xxxx
ETag: "123456789-000-111"
BEGIN:VCALENDAR
...
BEGIN:VTIMEZONE
TZID:America/New_York
...
END:VTIMEZONE
END:VCALENDAR
5.3.2. Example: Conditional Get Time Zone Data ๐ท
this time the client asks for the same zone but adds an If-None-Match header field ๐ The value is a previously returned ETag header field, or the value of the "etag" member in a JSON "timezone" object from a "list" action response. Since nothing changed on the server, you get a 304 response back. Iconic caching behaviour ๐
Request <<
GET /servlet/timezone/zones/America%2FNew_York HTTP/1.1
Host: tz.example.com
Accept:text/calendar
If-None-Match: "123456789-000-111"
Response <<
HTTP/1.1 304 Not Modified
Date: Wed, 4 Jun 2008 09:32:12 GMT
5.3.3. Example: Get Time Zone Data Using a Time Zone Alias ๐ฆ
here the client asks for a time zone using an aliased identifier ๐ช The server sends back the time zone data under that identifier, and it lists two aliases too.
Request <<
GET /servlet/timezone/zones/US%2FEastern HTTP/1.1
Host: tz.example.com
Accept:text/calendar
Response <<
HTTP/1.1 200 OK
Date: Wed, 4 Jun 2008 09:32:12 GMT
Content-Type: text/calendar; charset="utf-8"
Content-Length: xxxx
ETag: "123456789-000-111"
BEGIN:VCALENDAR
...
BEGIN:VTIMEZONE
TZID:US/Eastern
TZID-ALIAS-OF:America/New_York
TZID-ALIAS-OF:America/Montreal
...
END:VTIMEZONE
END:VCALENDAR
5.3.4. Example: Get Truncated Time Zone Data โ๏ธ
okay so say the server advertises a "truncated" object in its "capabilities" response that looks like this:
"truncated": {
"any": false,
"ranges": [
{"start": "1970-01-01T00:00:00Z", "end": "*"},
{"start":"2010-01-01T00:00:00Z", "end":"2020-01-01T00:00:00Z"}
],
"untruncated": false
}
In this example the client asks for a time zone truncated at one of the ranges the server listed ๐ Look out for the "STANDARD" component. It matches the start point of the truncation range, converted to local time using the UTC offset in effect at the matching UTC time. Also, check the "TZUNTIL" (Section 7.1) iCalendar property in the "VTIMEZONE" component. It tells you the upper bound on how long the time zone data stays valid ๐ง
Request <<
GET /servlet/timezone/zones/America%2FNew_York
?start=2010-01-01T00:00:00Z&end=2020-01-01T00:00:00Z HTTP/1.1
Host: tz.example.com
Accept:text/calendar
Response <<
HTTP/1.1 200 OK
Date: Wed, 4 Jun 2008 09:32:12 GMT
Content-Type: text/calendar; charset="utf-8"
Content-Length: xxxx
ETag: "123456789-000-111"
BEGIN:VCALENDAR
...
BEGIN:VTIMEZONE
TZID:America/New_York
TZUNTIL:20200101T000000Z
BEGIN:STANDARD
DTSTART:20101231T190000
TZNAME:EST
TZOFFSETFROM:-0500
TZOFFSETTO:-0500
END:STANDARD
...
END:VTIMEZONE
END:VCALENDAR
5.3.5. Example: Request for a Nonexistent Time Zone ๐ป
the client asks for a time zone identifier, but plot twist: no time zone exists with that identifier ๐
Request <<
GET /servlet/timezone/zones/America%2FPittsburgh HTTP/1.1
Host: tz.example.com
Accept:application/calendar+json
Response <<
HTTP/1.1 404 Not Found
Date: Wed, 4 Jun 2008 09:32:12 GMT
Content-Type: application/problem+json; charset="utf-8"
Content-Language: en
Content-Length: xxxx
{
"type": "urn:ietf:params:tzdist:error:tzid-not-found",
"title": "Time zone identifier was not found on this server",
"status": 404
}
5.4. "expand" Action ๐ฆ
Name: expand
Request-URI Template:
{/service-prefix,data-prefix}/zones{/tzid}/observances{?start,end}
The tzid variable value is REQUIRED ๐, so don't skip it, bestie.
Description: This action expands the time zone you ask for into a list of onset start date/time values (in UTC) and their UTC offsets โจ. The response MUST contain an ETag response header field that shows the current value of the strong entity tag for the time zone being expanded ๐.
Parameters:
start=<date-time>: REQUIRED, and MUST occur only once. This is the inclusive UTC date-time where your period of interest starts ๐ธ.end=<date-time>: REQUIRED, and MUST occur only once. This is the exclusive UTC date-time where your period ends. Exclusive means the end value is the date just after your range ๐. Like, if you only want the year 2014, you'd use a start of"2014-01-01T00:00:00Z"and an end of"2015-01-01T00:00:00Z". Also, an error happens if the end value is less than or equal to the start value ๐.
Response: You get a JSON object with a "tzid" member and an "observances" member, see Section 6.3 ๐ง. If the time zone isn't fully defined over the range you asked for (for example, because of truncation), then the server MUST include "start" and/or "end" members in the JSON response, so you know the actual start and end points of the observances you got back ๐. The server MUST also include an expanded observance that represents the time zone information in effect at the start of the returned observance period ๐.
Possible Error Codes:
urn:ietf:params:tzdist:error:tzid-not-found: No time zone matching the"tzid"path segment value was found ๐ญ.urn:ietf:params:tzdist:error:invalid-start: The"start"URI query parameter has a wrong value, shows up more than once, is missing, or has a value outside any fixed truncation ranges advertised in the"capabilities"action response ๐ โโ๏ธ.urn:ietf:params:tzdist:error:invalid-end: The"end"URI query parameter has a wrong value, shows up more than once, has a value less than or equal to the"start"URI query parameter, or has a value outside any fixed truncation ranges advertised in the"capabilities"action response ๐ .
5.4.1. Example: Expanded JSON Data Format
Okay, in this example the client asks for a time zone in the expanded form ๐.
Request <<
GET /servlet/timezone/zones/America%2FNew_York/observances
?start=2008-01-01T00:00:00Z&end=2009-01-01T00:00:00Z HTTP/1.1
Host: tz.example.com
Response <<
HTTP/1.1 200 OK
Date: Mon, 11 Oct 2009 09:32:12 GMT
Content-Type: application/json; charset="utf-8"
Content-Length: xxxx
ETag: "123456789-000-111"
{
"tzid": "America/New_York",
"observances": [
{
"name": "Standard",
"onset": "2008-01-01T00:00:00Z",
"utc-offset-from": -18000,
"utc-offset-to": -18000
},
{
"name": "Daylight",
"onset": "2008-03-09T07:00:00Z",
"utc-offset-from": -18000,
"utc-offset-to": -14400
},
{
"name": "Standard",
"onset": "2008-11-02T06:00:00Z",
"utc-offset-from": -14400,
"utc-offset-to": -18000
},
]
}
5.5. "find" Action ๐
Name: find
Request-URI Template:
{/service-prefix,data-prefix}/zones{?pattern}
Description: This action lets a client search the time zone data distribution service for a matching identifier, alias, or localized name ๐ฆ. It uses a simple "glob" style pattern match against the names the server knows, and the asterisk (*) is the wildcard character โจ. Pattern-match strings have to be percent-encoded, then decoded when used in the URI query parameter. Here are the options:
- No wildcard present: an exact text match is done, e.g.,
"xyz"๐ฏ. - Wildcard as the first character only: an ends-with text match is done, e.g.,
"*xyz"๐ธ. - Wildcard as the last character only: a starts-with text match is done, e.g.,
"xyz*"๐. - Wildcard as both the first and last characters: a substring text match is done, e.g.,
"*xyz*"๐.
Escaping \ and *: If you want to match a * (0x2A) or a \ (0x5C) character in a time zone identifier, you have to "escape" it in the pattern by putting a single \ (0x5C) in front of it ๐. For example, the pattern "\*Test\\Time\*Zone\*" is used for an exact match against the time zone identifier "*Test\Time*Zone*". An unescaped * MUST NOT appear in the middle of the string, and it MUST result in an error ๐. An unescaped \ MUST NOT appear anywhere in the string, and it MUST result in an error ๐ญ.
Also, when matching:
Underscores: Underscore characters (0x5F) in time zone identifiers MUST be mapped to a single space character (0x20) before string comparison. That happens in both the pattern and the time zone identifiers being matched ๐ง. This is why America/New_York can match a query for *New York* ๐.
Case mapping: ASCII characters in the range 0x41 (A) through 0x5A (Z) MUST be mapped to their lowercase equivalents, in both the pattern and the time zone identifiers being matched ๐.
Parameters:
pattern=<text>: REQUIRED, and MUST occur only once ๐.
Response: The response has the same format as the "list" action, with one result object for each successful match, see Section 6.2 โจ.
Possible Error Codes:
urn:ietf:params:tzdist:error:invalid-pattern: The"pattern"URI query parameter has a wrong value, or shows up more than once ๐ฌ.
5.5.1. Example: find action
In this example, the client asks for data about the time zone "US/Eastern" ๐ฝ.
Request <<
GET /servlet/timezone/zones?pattern=US/Eastern HTTP/1.1
Host: tz.example.com
Response <<
HTTP/1.1 200 OK
Date: Wed, 4 Jun 2008 09:32:12 GMT
Content-Type: application/json; charset="utf-8"
Content-Length: xxxx
{
"synctoken": "2009-10-11T09:32:11Z",
"timezones": [
{
"tzid": "America/New_York",
"etag": "123456789-000-111",
"last-modified": "2009-09-17T01:39:34Z",
"publisher": "Example.com",
"version": "2015a",
"aliases":["US/Eastern"],
"local-names": [
{
"name": "America/New_York",
"lang": "en_US"
}
]
},
{
"tzid": "America/Detroit",
"etag": "123456789-999-222",
"last-modified": "2009-09-17T01:39:34Z",
"publisher": "Example.com",
"version": "2015a",
"aliases":["US/Eastern"],
"local-names": [
{
"name": "America/Detroit",
"lang": "en_US"
}
]
},
...
]
}
5.6. "leapseconds" Action โญ
Name: leapseconds
Request-URI Template:
{/service-prefix,data-prefix}/leapseconds
Description: This action lets a client ask the time zone data distribution service for the current leap-second information the server has ๐ธ.
Parameters: None
Response: You get a JSON object with an "expires" member, a "publisher" member, a "version" member, and a "leapseconds" member, see Section 6.4 ๐. The "expires" member tells you the latest date covered by leap-second information ๐ซถ. For example (as in Section 5.6.1), if "expires" is "2014-06-28" and the latest leap-second change was at "2012-07-01", then there are no leap seconds added (or removed) between those two dates, and leap-second info past the "expires" date isn't available yet ๐ฐ๏ธ.
The "leapseconds" member holds a list of JSON objects, and each one has a "utc-offset" member and an "onset" member ๐ง . The "onset" member gives the date (with an implied time of 00:00:00 UTC) when the matching UTC offset from TAI kicks in ๐ฆ. Put simply, a leap second is added or removed just before 00:00:00 UTC on the onset date ๐
. When a leap second is added, the "utc-offset" value goes up by one โจ. When a leap second is removed, the "utc-offset" value goes down by one ๐ฅ.
Possible Error Codes: No specific code.
5.6.1. Example: Get Leap-Second Information
In this example, the client asks the server for the current leap-second information ๐.
Request <<
GET /servlet/timezone/leapseconds HTTP/1.1
Host: tz.example.com
Response <<
HTTP/1.1 200 OK
Date: Wed, 4 Jun 2008 09:32:12 GMT
Content-Type: application/json; charset="utf-8"
Content-Length: xxxx
{
"expires": "2015-12-28",
"publisher": "Example.com",
"version": "2015d",
"leapseconds": [
{
"utc-offset": 10,
"onset": "1972-01-01",
},
{
"utc-offset": 11,
"onset": "1972-07-01",
},
...
{
"utc-offset": 35,
"onset": "2012-07-01",
},
{
"utc-offset": 36,
"onset": "2015-07-01",
}
]
}
6. JSON Definitions ๐งธ
[RFC7159] is where the structure of JSON objects gets defined, using a set of primitive elements ๐. This specification describes the JSON objects it uses with the following set of rules:
OBJECT: represents a JSON object, defined in Section 4 of [RFC7159].OBJECTis followed by a parenthesized list ofMEMBERrule names. If a member rule name has a"?"(0x3F) character in front of it, that member is optional. Otherwise, all members are required. If two or more member rule names are present, separated from each other by a"|"(0x7C) character, then only one of those members MUST be present in the JSON object ๐ท. JSON object members are unordered, so the order used in the rules doesn't matter ๐ซ.MEMBER: represents a member of a JSON object, defined in Section 4 of [RFC7159].MEMBERis followed by a rule name, the name of the member, a":", and then the value. A value can be one of theOBJECT,ARRAY,NUMBER,STRING, orBOOLEANrules ๐.ARRAY: represents a JSON array, defined in Section 5 of [RFC7159].ARRAYis followed by a value (one ofOBJECT,ARRAY,NUMBER,STRING, orBOOLEAN), which tells you the type of items used in the array ๐.NUMBER: represents a JSON number, defined in Section 6 of [RFC7159] ๐ข.STRING: represents a JSON string, defined in Section 7 of [RFC7159] ๐งต.BOOLEAN: represents either of the JSON values"true"or"false", defined in Section 3 of [RFC7159] โ .- Comments: a line starting with a
";"(0x3B) character is a comment ๐ฌ.
Heads up, bestie: clients MUST ignore any unexpected JSON members in responses from the server ๐. Don't freak out if the server sends extra stuff, just skip it ๐.
6.1. capabilities Action Response โจ
okay bestie, this is the rulebook for the JSON doc the server sends back when someone asks for a "capabilities" action ๐ It's giving "here's everything I can do" energy ๐
; root object
OBJECT (version, info, actions)
; The version number of the protocol supported - MUST be 1
MEMBER version "version" : NUMBER
; object containing service information
; Only one of primary_source or secondary_source MUST be present
MEMBER info "info" : OBJECT (
primary_source | secondary_source,
formats,
?truncated,
?provider_details,
?contacts
)
; The source of the time zone data provided by a "primary" server
MEMBER primary_source "primary-source" : STRING
; The time zone data server from which data is provided by a
; "secondary" server
MEMBER secondary_source "secondary-source" : STRING
; Array of one or more media types for the time zone data formats
; that the server can return
MEMBER formats "formats" : ARRAY STRING
; Present if the server is providing truncated time zone data. The
; value is an object providing details of the supported truncation
; modes.
MEMBER truncated "truncated" : OBJECT: (
any,
?ranges,
?untruncated
)
; Indicates whether the server can truncate time zone data at any
; start or end point. When set to "true", any start or end point is
; a valid value for use with the "start" and "end" URI query
; parameters in a "get" action request.
MEMBER any "any" : BOOLEAN
; Indicates which ranges of time the server has truncated data for.
; A value from this list may be used with the "start" and "end" URI
; query parameters in a "get" action request. Not present if "any"
; is set to "true".
MEMBER ranges "ranges" : ARRAY OBJECT (range-start, range-end)
; UTC date-time value (per [RFC3339]) for inclusive start of the
; range, or the single character "*" to indicate a value
; corresponding to the lower bound supplied by the publisher of the
; time zone data
MEMBER range-start "start" : STRING
; UTC date-time value (per [RFC3339]) for exclusive end of the range,
; or the single character "*" to indicate a value corresponding to
; the upper bound supplied by the publisher of the time zone data
MEMBER range-end "end" : STRING
; Indicates whether the server can supply untruncated data. When
; set to "true", indicates that, in addition to truncated data being
; available, the server can return untruncated data if a "get"
; action request is executed without a "start" or "end" URI query
; parameter.
MEMBER untruncated "untruncated" : BOOLEAN
; A URI where human-readable details about the time zone service
; is available
MEMBER provider_details "provider-details" : STRING
; Array of URIs providing contact details for the server
; administrator
MEMBER contacts "contacts" : ARRAY STRING
; Array of actions supported by the server
MEMBER actions "actions" : ARRAY OBJECT (
action_name,
action_params
)
; Name of the action
MEMBER action_name: "name" : STRING
; Array of request-URI query parameters supported by the action
MEMBER action_params: "parameters" ARRAY OBJECT (
param_name,
?param_required,
?param_multi,
?param_values
)
; Name of the parameter
MEMBER param_name "name" : STRING
; If true, the parameter has to be present in the request-URI
; default is false
MEMBER param_required "required" : BOOLEAN
; If true, the parameter can occur more than once in the request-URI
; default is false
MEMBER param_multi "multi" : BOOLEAN,
; An array that defines the allowed set of values for the parameter
; In the absence of this member, any string value is acceptable
MEMBER param_values "values" ARRAY STRING
The big picture: the root has a version, an info object, and an actions array ๐ฆ Inside info, you get exactly one of primary-source or secondary-source (that's a MUST, no cap ๐ญ), plus formats, and optional extras like truncated, provider-details, and contacts โจ
6.2. list/find Action Response โจ
this one is for the "list" and "find" actions, and honestly it's giving tidy list energy ๐ธ Here's the JSON shape:
; root object
OBJECT (synctoken, timezones)
; Server-generated opaque token used for synchronizing changes
MEMBER synctoken "synctoken" : STRING
; Array of time zone objects
MEMBER timezones "timezones" : ARRAY OBJECT (
tzid,
etag,
last_modified,
publisher,
version,
?aliases,
?local_names,
)
; Time zone identifier
MEMBER tzid "tzid" : STRING
; Current ETag for the corresponding time zone data resource
MEMBER etag "etag" : STRING
; Date/time when the time zone data was last modified
; UTC date-time value as specified in [RFC3339]
MEMBER last_modified "last-modified" : STRING
; Time zone data publisher
MEMBER publisher "publisher" : STRING
; Current version of the time zone data as defined by the
; publisher
MEMBER version "version" : STRING
; An array that lists the set of time zone aliases available
; for the corresponding time zone
MEMBER aliases "aliases" : ARRAY STRING
; An array that lists the set of localized names available
; for the corresponding time zone
MEMBER local_names "local-names" : ARRAY OBJECT (
lname, lang, ?pref
)
; Language tag for the language of the associated name
MEMBER: lang "lang" : STRING
; Localized name
MEMBER lname "name" : STRING
; Indicates whether this is the preferred name for the associated
; language default: false
MEMBER pref "pref" : BOOLEAN
6.3. expand Action Response โจ
this is the "expand" action's JSON, and it's the one where you get the observances ๐ฐ๏ธ Lowkey iconic:
; root object
OBJECT (
tzid,
?start,
?end,
observances
)
; Time zone identifier
MEMBER tzid "tzid" : STRING
; The actual inclusive start point for the returned observances
; if different from the value of the "start" URI query parameter
MEMBER start "start" : STRING
; The actual exclusive end point for the returned observances
; if different from the value of the "end" URI query parameter
MEMBER end "end" : STRING
; Array of time zone objects
MEMBER observances "observances" : ARRAY OBJECT (
oname,
?olocal_names,
onset,
utc_offset_from,
utc_offset_to
)
; Observance name
MEMBER oname "name" : STRING
; Array of localized observance names
MEMBER olocal_names "local-names" : ARRAY STRING
; UTC date-time value (per [RFC3339]) at which the observance takes
; effect
MEMBER onset "onset" : STRING
; The UTC offset in seconds before the start of this observance
MEMBER utc_offset_from "utc-offset-from" : NUMBER
; The UTC offset in seconds at and after the start of this observance
MEMBER utc_offset_to "utc-offset-to" : NUMBER
6.4. leapseconds Action Response โจ
last one in this batch, the "leapseconds" response ๐ง It tracks the UTC offset from TAI, and it's giving precise and proud of it ๐
; root object
OBJECT (
expires,
publisher,
version,
leapseconds
)
; Last valid date covered by the data in this response
; full-date value as specified in [RFC3339]
MEMBER expires "expires" : STRING
; Leap-second information publisher
MEMBER publisher "publisher" : STRING
; Current version of the leap-second information as defined by the
; publisher
MEMBER version "version" : STRING
; Array of leap-second objects
MEMBER leapseconds "leapseconds" : ARRAY OBJECT (
utc_offset,
onset
)
; The UTC offset from TAI in seconds in effect at and after the
; specified date
MEMBER utc_offset "utc-offset" : NUMBER
; full-date value (per [RFC3339]) at which the new UTC offset takes
; effect, at T00:00:00Z
MEMBER onset "onset" : STRING
7. New iCalendar Properties โจ
okay so this section adds some brand new iCalendar properties to the mix ๐ฆ They all live in VTIMEZONE components, and they're here to fix gaps that the existing spec didn't cover ๐
7.1. Time Zone Upper Bound ๐
Property Name: TZUNTIL
Purpose: this one specifies an upper bound for how long the data inside a "VTIMEZONE" component stays valid ๐ฐ๏ธ
Value Type: DATE-TIME
Property Parameters: IANA and non-standard property parameters can be specified on this property โจ
Conformance: this property can be specified zero times or one time within "VTIMEZONE" calendar components ๐
Description: the value MUST be specified in the UTC time format. ๐ญ
Here's the tea ๐ Time zone data in a "VTIMEZONE" component might only cover a fixed window. The start of that window is pretty obvious, since it's the earliest observance defined by the "STANDARD" and "DAYLIGHT" subcomponents. The end is trickier ๐ You can't just look at the observance with the latest onset time and call it a day, and [RFC5545] doesn't give you any way to get that upper bound. So this spec introduces TZUNTIL to fill that gap. It's an "exclusive" UTC date-time value that marks the last moment the time zone data is considered valid โญ
This property is also used by time zone data distribution servers to show the truncation range end point of their time zone data (as described in Section 3.9) ๐
Format Definition: this property is defined by the following notation in ABNF [RFC5234]:
tzuntil = "TZUNTIL" tzuntilparam ":" date-time CRLF
tzuntilparam = *(";" other-param)
Example: imagine a time zone based on astronomical observations that has well-defined onset times through the year 2025. The first onset in 2026 is only known approximately, though. In that case, the "TZUNTIL" property could be specified like this:
TZUNTIL:20260101T000000Z
7.2. Time Zone Identifier Alias Property ๐ฆ
Property Name: TZID-ALIAS-OF
Purpose: this one specifies a time zone identifier for which the main time zone identifier is an alias ๐
Value Type: TEXT
Property Parameters: IANA and non-standard property parameters can be specified on this property ๐ธ
Conformance: this property can be specified zero or more times within "VTIMEZONE" calendar components โจ
Description: when the "VTIMEZONE" component uses a time zone identifier alias for the TZID property value, the TZID-ALIAS-OF property is used to point to the time zone identifier of the other time zone (see Section 3.7) ๐
Format Definition: this property is defined by the following notation in ABNF [RFC5234]:
tzid-alias-of = "TZID-ALIAS-OF" tzidaliasofparam ":"
[tzidprefix] text CRLF
tzidaliasofparam = *(";" other-param)
;tzidprefix defined in [RFC5545].
Example: here's what it looks like in action ๐ง
TZID-ALIAS-OF:America/New_York
8. Security Considerations โจ
okay bestie, this section is SERIOUS ๐ญ๐ time zone data decides what time your device thinks it is and how calendar invites line up across the world, so getting it from a shady source is a whole disaster. we need a reliable source, no cap ๐ซถ
Servers running a time zone data distribution service MUST support HTTP over Transport Layer Security (TLS) ๐, as defined by [RFC2818] and [RFC5246], with the best practices in [RFC7525] ๐ . Servers MAY also offer the service over plain HTTP without TLS, but secondary servers MUST use TLS when they fetch data from a primary server. no exceptions, periodt ๐
Clients SHOULD use Transport Layer Security as defined by [RFC2818], unless they've been specifically configured otherwise ๐. Clients that are set up to use the TLS-based service MUST NOT fall back to the non-TLS service if the TLS one isn't available ๐ โโ๏ธ. Also, clients MUST NOT follow HTTP redirects from a TLS service to a non-TLS service ๐ซ. And when TLS is in use, clients MUST verify the identity of the server using a standard, secure mechanism, like the certificate verification process in [RFC6125] or DANE [RFC6698] ๐โจ
Heads up: a malicious attacker who can see DNS server data, or who gets spoofed answers cached in a recursive resolver, can potentially make clients connect to any server they pick ๐ฑ๐ต๏ธโโ๏ธ
Without a secure DNS option, clients SHOULD check that the target FQDN in the SRV record is the same as the original service domain they queried, or a sub-domain of it ๐ง. A lot of the time, client config gets handled automatically with zero user input, so any mismatch between the original service domain and the target FQDN counts as a failure, and the client MUST NOT attempt to connect to that target server ๐. When TLS is being used, the certificate SHOULD include an SRV-ID field as per [RFC4985] that matches the DNS SRV queries clients use for service discovery ๐ชช. If an SRV-ID field is in the certificate, clients MUST match the SRV-ID value against the service type and domain from the DNS SRV request the client made to find the service ๐
Time zone data servers SHOULD protect themselves from badly implemented or malicious clients by throttling high request rates or frequent requests for big chunks of data ๐ฆ. Clients can dodge being throttled by using the polling capabilities in Section 4.1.4 ๐ฆ. Servers MAY require some form of authentication or authorization of clients (including secondary servers), as per [RFC7235], to limit who gets access or to better spot problematic clients ๐๐
9. Privacy Considerations ๐ซฃ
okay so this one is giving surveillance vibes ๐๐ the kinds of requests a client makes can be used to "fingerprint" specific clients or devices, and that can leak what users are up to ๐ณ. Like, a client that only downloads time zone data as-needed will basically leak the fact that a user's device moved from one time zone to another, or that the user is getting scheduling messages from someone in a different time zone ๐โ๏ธ
Clients need to be aware of how an untrusted server or a network observer could track them, and take precautions like these ๐ง โจ
- Always use TLS to connect to the server. ๐
- Avoid use of TLS session resumption. ๐ โโ๏ธ
- Always fetch and synchronize the entire set of time zone data, so you don't leak which time zones the client actually uses ๐ธ
- Randomize the order in which individual time zones are fetched using the "get" action, when retrieving a set of time zones based on a "list" action response ๐ฒ
- Avoid use of conditional HTTP requests [RFC7232] with the "get" action, so servers can't track clients through client-specific ETag header field values ๐ท๏ธ
- Avoid use of cookies in HTTP requests [RFC6265] ๐ช๐ซ
- Avoid use of authenticated HTTP requests. ๐
- When doing periodic polling to check for updates, apply a random offset (positive or negative) to the next poll time, so servers can't identify the client by the specific periodicity of its polling ๐ฐ๏ธ๐
- A server trying to "fingerprint" clients might insert a "fake" time zone into the time zone data, using a unique identifier for each client making a request ๐ป. The server can then watch for client requests that refer to that "fake" time zone and track each client's activity. It's hard for clients to spot a "fake" time zone since new time zones get added occasionally ๐ค. One option to mitigate this is for the client to use two time zone data distribution servers from two independent providers that serve time zone data from the same publisher ๐ค. The client can compare the list of time zones from each server (assuming they both have the same version of the time zone data from the common publisher) and detect ones that appear on one server but not the other ๐. Alternatively, the client can check the publisher's data directly to verify the time zones match the set the publisher has ๐โ
Note that some of the above recommendations make the protocol less efficient, since you end up fetching data that might not be relevant to the client ๐๐ญ
An organization can set up a secondary server within its own domain and configure its clients to use that server, which protects the organization's users from being tracked by an untrusted time zone data distribution server ๐ข๐ซถ. Clients can then use more-efficient protocol interactions, free from the concerns above, on the basis that their organization's server is trusted ๐. When doing this, the secondary server should follow the recommendations for clients (listed in the previous paragraph) so the untrusted server can't learn anything about the organization as a whole ๐งฑ. Note, however, that client requests to the secondary server are still subject to tracking by a network observer, so clients ought to apply some of the randomization techniques from the list above ๐ฒ๐
Servers that want to avoid accidentally storing information that could identify clients can take these precautions ๐๏ธโจ
- Avoid logging client request activity, or anonymize information in any logs (e.g., client IP address, client user-agent details, authentication credentials, etc.). ๐๐
- Add an unused HTTP response header to each response with a random amount of data in it (e.g., to pad the overall request size to the nearest power-of-2 or 128-byte boundary), so network traffic analysis can't expose which time zones are being fetched when TLS is in use ๐๐
10. IANA Considerations ๐ฆ
okay this section is all about the paperwork ๐๐ This specification defines a new registry of "actions" for the time zone data distribution service protocol ๐. It defines a "well-known" URI using the registration procedure and template from Section 5.1 of [RFC5785] ๐ง, creates two new SRV service label aliases ๐ท๏ธ, and defines one new iCalendar property parameter as per the registration procedure in [RFC5545] ๐ . It also adds a new "TZDIST Identifiers Registry" to the IETF parameters URN sub-namespace as per [RFC3553], for use with protocol related error codes ๐โจ
10.1. Service Actions Registration
IANA has created a new top-level category called "Time Zone Data Distribution Service (TZDIST) Parameters" and has put all the registries created herein into that category ๐๏ธ๐
IANA has created a new registry called "TZDIST Service Actions", as defined below ๐ธ
10.1.1. Service Actions Registration Procedure
This registry uses the "Specification Required" policy defined in [RFC5226], which makes use of a designated expert to review potential registrations ๐งโโ๏ธ
The IETF has created a mailing list, tzdist-service@ietf.org, which is used for public discussion of time zone data distribution service action proposals prior to registration ๐ฌ. The IESG has appointed a designated expert who will monitor the tzdist-service@ietf.org mailing list and review registrations ๐
A Standards Track RFC is REQUIRED for changes to actions previously documented in a Standards Track RFC ๐. Otherwise, any public specification that satisfies the requirements of [RFC5226] is acceptable ๐ซถ
The registration procedure begins when a completed registration template, as defined below, is sent to tzdist-service@ietf.org and iana@iana.org ๐จ. The designated expert is expected to tell IANA and the submitter whether the registration is approved, approved with minor changes, or rejected with cause, within two weeks โณ. When a registration is rejected with cause, it can be resubmitted if the concerns listed in the cause are addressed ๐. Decisions made by the designated expert can be appealed as per Section 7 of [RFC5226] โ๏ธ
The designated expert MUST take the following requirements into account when reviewing the registration ๐:
- A valid registration template MUST be provided by the submitter, with a clear description of what the action does ๐.
- A proposed new action name MUST NOT conflict with any existing registered action name. A conflict includes a name that duplicates an existing one, or that appears to be very similar to an existing one and could be a potential source of confusion ๐ โโ๏ธ.
- A proposed new action MUST NOT exactly duplicate the functionality of any existing actions. In cases where the new action functionality is very close to an existing action, the designated expert SHOULD clarify whether the submitter is aware of the existing action and has an adequate reason for creating a new action with slight differences from an existing one ๐ง.
- If a proposed action is an extension to an existing action, the changes MUST NOT conflict with the intent of the existing action, or in a way that could cause interoperability problems for existing deployments of the protocol ๐ค๐ฅ.
The IANA registry contains the name of the action ("Action Name") and a reference to the section of the specification where the action registration template is defined ("Reference") ๐๐ท.
10.1.2. Registration Template for Actions
An action is defined by completing the following template ๐งฉ.
Name: The name of the action.
Request-URI Template: The URI template used in HTTP requests for the action.
Description: A general description of the action, its purpose, etc.
Parameters: A list of allowed request URI query parameters, indicating whether they are "REQUIRED" or "OPTIONAL" and whether they can occur only once or multiple times, together with the expected format of the parameter values ๐.
Response: The nature of the response to the HTTP request, e.g., what format the response data is in ๐ฆ.
Possible Error Codes: Possible error codes reported in a JSON "problem details" object if an HTTP request fails ๐จ.
10.1.3. Actions Registry ๐โจ
okay so this is the actions registry, and it's where the starting lineup lives ๐ here's the initial content, bestie:
+---------------+------------------------+
| Action Name | Reference |
+---------------+------------------------+
| capabilities | RFC 7808, Section 5.1 |
| list | RFC 7808, Section 5.2 |
| get | RFC 7808, Section 5.3 |
| expand | RFC 7808, Section 5.4 |
| find | RFC 7808, Section 5.5 |
| leapseconds | RFC 7808, Section 5.6 |
+---------------+------------------------+
10.2. timezone Well-Known URI Registration ๐ธ
IANA added this entry to the "Well-Known URIs" [RFC5785] registry, and it's giving very official ๐ซถ
- URI suffix:
timezone - Change controller: IESG.
- Specification document(s): RFC 7808
- Related information: None.
10.3. Service Name Registrations ๐
IANA added two new service names to the "Service Name and Transport Protocol Port Number Registry" [RFC6335], as defined below. two whole new names, periodt ๐
10.3.1. timezone Service Name Registration ๐ฆ
- Service Name:
timezone - Transport Protocol(s): TCP
- Assignee: IESG <iesg@ietf.org>
- Contact: IETF Chair <chair@ietf.org>
- Description: Time Zone Data Distribution Service - non-TLS
- Reference: RFC 7808
- Assignment Note: This is an extension of the http service. Defined TXT keys:
path=<context path>(as per Section 6 of [RFC6763]).
10.3.2. timezones Service Name Registration ๐
- Service Name:
timezones - Transport Protocol(s): TCP
- Assignee: IESG <iesg@ietf.org>
- Contact: IETF Chair <chair@ietf.org>
- Description: Time Zone Data Distribution Service - over TLS
- Reference: RFC 7808
- Assignment Note: This is an extension of the https service. Defined TXT keys:
path=<context path>(as per Section 6 of [RFC6763]).
10.4. TZDIST Identifiers Registry ๐ฎ
okay so IANA registered a brand new URN sub-namespace inside the IETF URN Sub-namespace for Registered Protocol Parameter Identifiers, which is defined in [RFC3553]. it's a whole new neighborhood ๐๏ธโจ
Registrations in this registry follow the "IETF Review" [RFC5226] policy. so it's not a free-for-all, it's a vibe check with actual reviewers ๐
- Registry name: TZDIST Identifiers
- URN prefix:
urn:ietf:params:tzdist - Specification: RFC 7808
- Repository: http://www.iana.org/assignments/tzdist-identifiers
- Index value: Values in this registry are URNs or URN prefixes that start with the prefix
urn:ietf:params:tzdist:. Each is registered independently. The prefixurn:ietf:params:tzdist:error:is used to represent specific error codes within the protocol as defined in the list of actions in Section 5 and used in problem reports (Section 4.1.7).
Each registration in the "TZDIST Identifiers" registry requires the following information ๐
- URN: The complete URN that is used or the prefix for that URN.
- Description: A summary description for the URN or URN prefix.
- Specification: A reference to a specification describing the URN or URN prefix.
- Contact: Email for the person or groups making the registration.
- Index Value: As described in [RFC3553], URN prefixes that are registered include a description of how the URN is constructed. This is not applicable for specific URNs.
The "TZDIST Identifiers" registry has the initial registrations included in the following sections. here they come ๐ง
10.4.1. Registration of invalid-action Error URN ๐ซ
The following URN has been registered in the "tzdist Identifiers" registry.
- URN:
urn:ietf:params:tzdist:error:invalid-action - Description: Generic error code for any invalid action.
- Specification: RFC 7808, Section 5
- Repository: http://www.iana.org/assignments/tzdist-identifiers
- Contact: IESG <iesg@ietf.org>
- Index value: N/A.
10.4.2. Registration of invalid-changedsince Error URN ๐ฐ๏ธ
The following URN has been registered in the "tzdist Identifiers" registry.
- URN:
urn:ietf:params:tzdist:error:invalid-changedsince - Description: Error code for incorrect use of the "changedsince" URI query parameter.
- Specification: RFC 7808, Section 5.2
- Repository: http://www.iana.org/assignments/tzdist-identifiers
- Contact: IESG <iesg@ietf.org>
- Index value: N/A.
10.4.3. Registration of tzid-not-found Error URN ๐
The following URN has been registered in the "tzdist Identifiers" registry.
- URN:
urn:ietf:params:tzdist:error:tzid-not-found - Description: Error code for missing time zone identifier.
- Specification: RFC 7808, Sections 5.3 and 5.4
- Repository: http://www.iana.org/assignments/tzdist-identifiers
- Contact: IESG <iesg@ietf.org>
- Index value: N/A.
10.4.4. Registration of invalid-format Error URN ๐งพ
The following URN has been registered in the "tzdist Identifiers" registry.
- URN:
urn:ietf:params:tzdist:error:invalid-format - Description: Error code for unsupported HTTP Accept request header field value.
- Specification: RFC 7808, Section 5.3
- Repository: http://www.iana.org/assignments/tzdist-identifiers
- Contact: IESG <iesg@ietf.org>
- Index value: N/A.
10.4.5. Registration of invalid-start Error URN โฏ๏ธ
The following URN has been registered in the "tzdist Identifiers" registry.
- URN:
urn:ietf:params:tzdist:error:invalid-start - Description: Error code for incorrect use of the "start" URI query parameter.
- Specification: RFC 7808, Sections 5.3 and 5.4
- Repository: http://www.iana.org/assignments/tzdist-identifiers
- Contact: IESG <iesg@ietf.org>
- Index value: N/A.
10.4.6. Registration of invalid-end Error URN โน๏ธ
The following URN has been registered in the "tzdist Identifiers" registry.
- URN:
urn:ietf:params:tzdist:error:invalid-end - Description: Error code for incorrect use of the "end" URI query parameter.
- Specification: RFC 7808, Sections 5.3 and 5.4
- Repository: http://www.iana.org/assignments/tzdist-identifiers
- Contact: IESG <iesg@ietf.org>
- Index value: N/A.
10.4.7. Registration of invalid-pattern Error URN ๐
The following URN has been registered in the "tzdist Identifiers" registry.
- URN:
urn:ietf:params:tzdist:error:invalid-pattern - Description: Error code for incorrect use of the "pattern" URI query parameter.
- Specification: RFC 7808, Section 5.5
- Repository: http://www.iana.org/assignments/tzdist-identifiers
- Contact: IESG <iesg@ietf.org>
- Index value: N/A.
10.5. iCalendar Property Registrations ๐
This document defines the following new iCalendar properties, which have been added to the "Properties" registry under "iCalendar Element Registries" [RFC5545]. two brand new properties, bestie ๐ฅน
+----------------+----------+------------------------+
| Property | Status | Reference |
+----------------+----------+------------------------+
| TZUNTIL | Current | RFC 7808, Section 7.1 |
| TZID-ALIAS-OF | Current | RFC 7808, Section 7.2 |
+----------------+----------+------------------------+
11. References ๐โจ
11.1. Normative References
Okay bestie, these are the docs the spec needs you to have read, no cap ๐โจ
[RFC2046] Freed, N. and N. Borenstein, "Multipurpose Internet Mail
Extensions (MIME) Part Two: Media Types", RFC 2046,
DOI 10.17487/RFC2046, November 1996,
<http://www.rfc-editor.org/info/rfc2046>.
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
Requirement Levels", BCP 14, RFC 2119,
DOI 10.17487/RFC2119, March 1997,
<http://www.rfc-editor.org/info/rfc2119>.
[RFC2782] Gulbrandsen, A., Vixie, P., and L. Esibov, "A DNS RR for
specifying the location of services (DNS SRV)", RFC 2782,
DOI 10.17487/RFC2782, February 2000,
<http://www.rfc-editor.org/info/rfc2782>.
[RFC2818] Rescorla, E., "HTTP Over TLS", RFC 2818,
DOI 10.17487/RFC2818, May 2000,
<http://www.rfc-editor.org/info/rfc2818>.
[RFC3339] Klyne, G. and C. Newman, "Date and Time on the Internet:
Timestamps", RFC 3339, DOI 10.17487/RFC3339, July 2002,
<http://www.rfc-editor.org/info/rfc3339>.
[RFC3553] Mealling, M., Masinter, L., Hardie, T., and G. Klyne, "An
IETF URN Sub-namespace for Registered Protocol
Parameters", BCP 73, RFC 3553, DOI 10.17487/RFC3553, June
2003, <http://www.rfc-editor.org/info/rfc3553>.
[RFC3629] Yergeau, F., "UTF-8, a transformation format of ISO
10646", STD 63, RFC 3629, DOI 10.17487/RFC3629, November
2003, <http://www.rfc-editor.org/info/rfc3629>.
[RFC4985] Santesson, S., "Internet X.509 Public Key Infrastructure
Subject Alternative Name for Expression of Service Name",
RFC 4985, DOI 10.17487/RFC4985, August 2007,
<http://www.rfc-editor.org/info/rfc4985>.
[RFC5226] Narten, T. and H. Alvestrand, "Guidelines for Writing an
IANA Considerations Section in RFCs", BCP 26, RFC 5226,
DOI 10.17487/RFC5226, May 2008,
<http://www.rfc-editor.org/info/rfc5226>.
[RFC5234] Crocker, D., Ed. and P. Overell, "Augmented BNF for Syntax
Specifications: ABNF", STD 68, RFC 5234,
DOI 10.17487/RFC5234, January 2008,
<http://www.rfc-editor.org/info/rfc5234>.
[RFC5246] Dierks, T. and E. Rescorla, "The Transport Layer Security
(TLS) Protocol Version 1.2", RFC 5246,
DOI 10.17487/RFC5246, August 2008,
<http://www.rfc-editor.org/info/rfc5246>.
[RFC5545] Desruisseaux, B., Ed., "Internet Calendaring and
Scheduling Core Object Specification (iCalendar)",
RFC 5545, DOI 10.17487/RFC5545, September 2009,
<http://www.rfc-editor.org/info/rfc5545>.
[RFC5785] Nottingham, M. and E. Hammer-Lahav, "Defining Well-Known
Uniform Resource Identifiers (URIs)", RFC 5785,
DOI 10.17487/RFC5785, April 2010,
<http://www.rfc-editor.org/info/rfc5785>.
[RFC6125] Saint-Andre, P. and J. Hodges, "Representation and
Verification of Domain-Based Application Service Identity
within Internet Public Key Infrastructure Using X.509
(PKIX) Certificates in the Context of Transport Layer
Security (TLS)", RFC 6125, DOI 10.17487/RFC6125, March
2011, <http://www.rfc-editor.org/info/rfc6125>.
[RFC6265] Barth, A., "HTTP State Management Mechanism", RFC 6265,
DOI 10.17487/RFC6265, April 2011,
<http://www.rfc-editor.org/info/rfc6265>.
[RFC6321] Daboo, C., Douglass, M., and S. Lees, "xCal: The XML
Format for iCalendar", RFC 6321, DOI 10.17487/RFC6321,
August 2011, <http://www.rfc-editor.org/info/rfc6321>.
[RFC6335] Cotton, M., Eggert, L., Touch, J., Westerlund, M., and S.
Cheshire, "Internet Assigned Numbers Authority (IANA)
Procedures for the Management of the Service Name and
Transport Protocol Port Number Registry", BCP 165,
RFC 6335, DOI 10.17487/RFC6335, August 2011,
<http://www.rfc-editor.org/info/rfc6335>.
[RFC6557] Lear, E. and P. Eggert, "Procedures for Maintaining the
Time Zone Database", BCP 175, RFC 6557,
DOI 10.17487/RFC6557, February 2012,
<http://www.rfc-editor.org/info/rfc6557>.
[RFC6570] Gregorio, J., Fielding, R., Hadley, M., Nottingham, M.,
and D. Orchard, "URI Template", RFC 6570,
DOI 10.17487/RFC6570, March 2012,
<http://www.rfc-editor.org/info/rfc6570>.
[RFC6698] Hoffman, P. and J. Schlyter, "The DNS-Based Authentication
of Named Entities (DANE) Transport Layer Security (TLS)
Protocol: TLSA", RFC 6698, DOI 10.17487/RFC6698, August
2012, <http://www.rfc-editor.org/info/rfc6698>.
[RFC6763] Cheshire, S. and M. Krochmal, "DNS-Based Service
Discovery", RFC 6763, DOI 10.17487/RFC6763, February 2013,
<http://www.rfc-editor.org/info/rfc6763>.
[RFC7159] Bray, T., Ed., "The JavaScript Object Notation (JSON) Data
Interchange Format", RFC 7159, DOI 10.17487/RFC7159, March
2014, <http://www.rfc-editor.org/info/rfc7159>.
[RFC7230] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer
Protocol (HTTP/1.1): Message Syntax and Routing",
RFC 7230, DOI 10.17487/RFC7230, June 2014,
<http://www.rfc-editor.org/info/rfc7230>.
[RFC7231] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer
Protocol (HTTP/1.1): Semantics and Content", RFC 7231,
DOI 10.17487/RFC7231, June 2014,
<http://www.rfc-editor.org/info/rfc7231>.
[RFC7232] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer
Protocol (HTTP/1.1): Conditional Requests", RFC 7232,
DOI 10.17487/RFC7232, June 2014,
<http://www.rfc-editor.org/info/rfc7232>.
[RFC7234] Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke,
Ed., "Hypertext Transfer Protocol (HTTP/1.1): Caching",
RFC 7234, DOI 10.17487/RFC7234, June 2014,
<http://www.rfc-editor.org/info/rfc7234>.
[RFC7235] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer
Protocol (HTTP/1.1): Authentication", RFC 7235,
DOI 10.17487/RFC7235, June 2014,
<http://www.rfc-editor.org/info/rfc7235>.
[RFC7265] Kewisch, P., Daboo, C., and M. Douglass, "jCal: The JSON
Format for iCalendar", RFC 7265, DOI 10.17487/RFC7265, May
2014, <http://www.rfc-editor.org/info/rfc7265>.
[RFC7525] Sheffer, Y., Holz, R., and P. Saint-Andre,
"Recommendations for Secure Use of Transport Layer
Security (TLS) and Datagram Transport Layer Security
(DTLS)", BCP 195, RFC 7525, DOI 10.17487/RFC7525, May
2015, <http://www.rfc-editor.org/info/rfc7525>.
[RFC7807] Nottingham, M. and E. Wilde, "Problem Details for HTTP
APIs", RFC 7807, DOI 10.17487/RFC7807, March 2016,
<http://www.rfc-editor.org/info/rfc7807>.
11.2. Informative References
These ones are more like extra reading for the curious ๐ง
[RFC2131] Droms, R., "Dynamic Host Configuration Protocol",
RFC 2131, DOI 10.17487/RFC2131, March 1997,
<http://www.rfc-editor.org/info/rfc2131>.
Acknowledgements ๐ซถ
The authors wanna give a huge shoutout to the members of the Calendaring and Scheduling Consortium's Time Zone Technical Committee, and to the participants and chairs of the IETF tzdist working group. ๐ Literally so many people helped make this happen, but these ones really went above and beyond: Steve Allen, Lester Caine, Stephen Colebourne, Tobias Conradi, Steve Crocker, Paul Eggert, Daniel Kahn Gillmor, John Haug, Ciny Joy, Bryan Keller, Barry Leiba, Andrew McMillan, Ken Murchison, Tim Parenti, Arnaud Quillaud, Jose Edvaldo Saraiva, and Dave Thewlis. You all are iconic ๐
This specification started out as work at the Calendaring and Scheduling Consortium, which also supported building and testing implementations of it. ๐ธ
Authors' Addresses ๐ฆ
Here's where you can find the authors ๐
Michael Douglass
Spherical Cow Group
226 3rd Street
Troy, NY 12180
United States
Email: mdouglass@sphericalcowgroup.com
URI: http://sphericalcowgroup.com
Cyrus Daboo
Apple Inc.
1 Infinite Loop
Cupertino, CA 95014
United States
Email: cyrus@daboo.name
URI: http://www.apple.com/
๐ฆ where this page comes from
- ietf: rfc7808 2016-03
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms