RFC 9581

Concise Binary Object Representation (CBOR) Tags for Time, Duration, and Period

πŸ“… published August 2024, from ietf

Concise Binary Object Representation (CBOR) Tags for Time, Duration, and Period πŸ¦‹

  • Request for Comments: 9581 🌸
  • Stream: Internet Engineering Task Force (IETF)
  • Authors: C. Bormann (UniversitΓ€t Bremen TZI), B. Gamari (Well-Typed), H. Birkholz (Fraunhofer SIT) πŸ‘―
  • Category: Standards Track
  • ISSN: 2070-1721
  • Date: August 2024
  • Obsoletes / Updates: the title block doesn't mention any documents being obsoleted or updated 🧚

Abstract 🌈

Okay so CBOR (that's RFC 8949 πŸ’…) is a data format, and its whole vibe is that it can have extremely small code size, fairly small message size, and extensibility without needing version negotiation. Main character energy, fr fr ✨

One way CBOR gets extended is through CBOR tags. RFC 8949 defines two tags for time: CBOR tag 0 (RFC 3339 time as a string) and tag 1 (POSIX time as int or float). Since then, more requirements have come up πŸ‘€. This document defines a CBOR tag for time that represents time in a more elaborate way, plus related CBOR tags for duration and time period. It's also the reference document for the IANA registration of the CBOR tags defined here 🫢.

Status of This Memo πŸ’Œ

This is an Internet Standards Track document, bestie πŸŽ€

This document is a product of the Internet Engineering Task Force (IETF). It represents the consensus of the IETF community. It went through public review and got approved for publication by the Internet Engineering Steering Group (IESG). For more on Internet Standards, check out Section 2 of RFC 7841 πŸ“š.

For the current status of this document, any errata, and how to give feedback on it, go to https://www.rfc-editor.org/info/rfc9581 πŸ”—.

Copyright (c) 2024 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 (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please read these documents carefully, because they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions, and they are provided without warranty as described in the Revised BSD License πŸ“œ.

Table of Contents πŸ“‘

1.  Introduction
  1.1.  Terminology
2.  Objectives
3.  Time Format
  3.1.  Key 1
  3.2.  Keys 4 and 5
  3.3.  Keys -3, -6, -9, -12, -15, and -18
  3.4.  Keys -1, -13, and 13: Timescale
  3.5.  Clock Quality
    3.5.1.  ClockClass (Key -2)
    3.5.2.  ClockAccuracy (Key -4)
    3.5.3.  OffsetScaledLogVariance (Key -5)
    3.5.4.  Uncertainty (Key -7)
    3.5.5.  Guarantee (Key -8)
  3.6.  Keys -10, 10: Time Zone Hint
  3.7.  Keys -11, 11: IXDTF Suffix Information
4.  Duration Format
5.  Period Format
6.  CDDL Type Names
7.  IANA Considerations
  7.1.  CBOR Tags
  7.2.  Timescales Registry
  7.3.  Time Tag Map Keys Registry
8.  Security Considerations
9.  References
  9.1.  Normative References
  9.2.  Informative References
Appendix A.  Collected CDDL
Acknowledgements
Authors' Addresses

1. Introduction ✨

The Concise Binary Object Representation (CBOR) [RFC8949] lets you interchange structured data without needing a pre-agreed schema πŸ™Œ. RFC 8949 defines a basic set of data types, plus a tagging mechanism that lets you extend the set of supported data types through an IANA registry for CBOR tags (see [IANA.cbor-tags] and Section 9.2 of [RFC8949]).

RFC 8949 defines two tags for time: CBOR tag 0 ([RFC3339] time as a string) and tag 1 (POSIX time as int or float). Since then, more requirements have become known πŸ‘€. The present document defines a CBOR tag for time that allows a more elaborate representation of time, plus related CBOR tags for durations and time periods. This document is intended as the reference document for the IANA registration of the CBOR tags defined πŸ’–.

1.1. Terminology πŸ’…

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here πŸ”₯.

The term "byte" is used in its now customary sense as a synonym for "octet" πŸ“.

Superscript notation denotes exponentiation. For example, 2 to the power of 64 is notated: 2^64. In the plain-text rendition of this specification, superscript notation isn't available, so exponentiation gets rendered with the surrogate notation you see here in the plain-text version πŸ€“.

CBOR diagnostic notation is defined in Section 8 of [RFC8949] and Appendix G of [RFC8610]. A machine-processable model of the data structures defined in this specification is given throughout the text using the Concise Data Definition Language (CDDL) [RFC8610]. Appendix A has the collected model information 🧩.

Several time-related terms, such as UTC and International Atomic Time (TAI), are discussed in [RFC9557], which may be a useful companion document beyond its direct use in Sections 3.6 and 3.7 πŸ“š.

2. Objectives 🎯

For the time tag, this specification tackles the following objectives that go beyond the original tags 0 and 1 (defined in Sections 3.4.1 and 3.4.2 of [RFC8949]):

  • Additional resolution for epoch-based time (as in tag 1). CBOR tag 1 only provides for representing time as an integer and as up to a binary64 floating-point value [IEEE754], which limits the resolution to approximately microseconds at the time of writing (progressively becoming worse over time) 😭.
  • Indication of timescale. Tags 0 and 1 are defined for UTC; however, some interchanges are better performed on TAI. Other timescales may be registered once they become relevant (e.g., one of the proposed successors to UTC that might no longer use leap seconds, or a scale based on smeared leap seconds) ⏰.

By incorporating a way to transport [RFC9557] suffix information (see Sections 3.6 and 3.7), you can provide additional indications of intents about how to interpret the given time. This is especially useful for instances of time that, at the time they're being described, are in the future. Intents might include info about time zones, daylight saving times, preferred calendar representations, etc. 🌍✨

Semantics not covered by this document can be added by registering additional map keys for the map that is the content of the tag (see etime-detailed in Figure 1). The specification for each one is referenced by its registry entry (see Section 3) πŸ—‚οΈ.

For example, map keys could be registered for direct representations of natural platform time formats. Some platforms use epoch-based time formats that need some computation to convert them into the representations allowed by tag 1. These computations can also lose precision and cause ambiguities πŸ™ˆ. (This specification doesn't take a position on whether tag 1 can be "fixed" to include, e.g., Decimal or Bigfloat representations. It does define how to use these representations with the extended time format πŸ’œ.)

Additional tags are defined for durations and periods πŸ¦‹.

3. Time Format ⏳

An extended time is indicated by CBOR tag 1001, and its content is a map data item (CBOR major type 5). The map may contain integer (major types 0 and 1) or text string (major type 3) keys, with the value type determined by each specific key. For negative integer keys and text string values of the key, implementations MUST ignore key/value pairs they do not understand. These keys are "elective", because the extended time as a whole is still usable without the information they carry if an implementation elects not to implement them 🌸. Conversely, implementations MUST signal an error when they run into key/value pairs that use unsigned integer keys they do not understand or implement. These are either "base time" or "critical", see below 🚨.

The map MUST contain exactly one unsigned integer key that specifies the "base time", and it MAY also contain one or more negative integer or text-string keys, which may encode supplementary information 🫧.

Supplementary information MAY also be provided by additional unsigned integer keys that are explicitly defined to provide supplementary information. We say these keys are defined to be "critical". Since they're required to be understood, there's no chance of confusion with base time keys πŸ›‘οΈ.

Negative integer and text string keys always supply supplementary information. They're "elective", and this won't be explicitly stated below 🫢.

Supplementary information may include:

  • a higher precision time offset to be added to the base time,
  • a reference timescale and epoch different from the default UTC and 1970-01-01, and
  • information about clock quality parameters, such as source, accuracy, and uncertainty πŸ”¬.

Additional keys can be defined by registering them in the "Time Tag Map Keys" registry (Section 7.3). Registered keys may, for instance, add intent information such as time zone, daylight saving time, and/or possibly positioning coordinates to express information that would indicate a local time πŸ—ΊοΈ.

This document does not define supplementary text keys. A number of both unsigned and negative-integer keys are defined in the following subsections πŸŽ€.

Figure 1 gives a formal definition of tag 1001 in CDDL πŸ’•.

Etime = #6.1001(etime-detailed)

etime-framework = {
  uint => any ; at least one base time
  * (nint/text) => any ; elective supplementary information
  * uint => any ; critical supplementary information
}

etime-detailed = ({
  $$ETIME-BASETIME
  ClockQuality-group
  * $$ETIME-ELECTIVE
  * $$ETIME-CRITICAL
  * ((nint/text) .feature "etime-elective-extension") => any
  * (uint .feature "etime-critical-extension") => any
}) .within etime-framework

Figure 1: CDDL Definition of Tag 1001

3.1. Key 1 πŸ•°οΈ

Key 1 indicates a base time value that's exactly like the data item that would be tagged by CBOR tag 1 (POSIX time [TIME_T] as int or float). As described above, the time value indicated by the value under this key can be further modified by other keys ✨.

$$ETIME-BASETIME //= (1: ~time)

3.2. Keys 4 and 5 🌊

Keys 4 and 5 indicate a base time value. They're like key 1, except the data item is an array, as defined for CBOR tag 4 or 5, respectively. This can be used to include a Decimal or Bigfloat epoch-based float [TIME_T] in an extended time, for example to get higher resolution or to avoid rounding errors 🀩.

$$ETIME-BASETIME //= (4: ~decfrac)
$$ETIME-BASETIME //= (5: ~bigfloat)

3.3. Keys -3, -6, -9, -12, -15, and -18 ✨

okay so these six keys are giving tiny slices of a second πŸ¦‹ Each one takes an unsigned integer (major type 0) and scales it by 1e-3, 1e-6, 1e-9, 1e-12, 1e-15, or 1e-18 (see Table 1). Each extended time data item MUST NOT contain more than one of these keys πŸ™…β€β™€οΈ The fractions get added to a base time in seconds [SI-SECOND] that key 1 gives you, and key 1 MUST also be present and MUST have an integer value, or the whole thing is cooked πŸ’€

                 +=====+==============+=================+
                 | Key | Meaning      | Example Usage   |
                 +=====+==============+=================+
                 | -3  | milliseconds | Java time       |
                 +-----+--------------+-----------------+
                 | -6  | microseconds | (old) UNIX time |
                 +-----+--------------+-----------------+
                 | -9  | nanoseconds  | (new) UNIX time |
                 +-----+--------------+-----------------+
                 | -12 | picoseconds  | Haskell time    |
                 +-----+--------------+-----------------+
                 | -15 | femtoseconds | (future)        |
                 +-----+--------------+-----------------+
                 | -18 | attoseconds  | (future)        |
                 +-----+--------------+-----------------+

                    Table 1: Keys for Decimally Scaled
                                Fractions
$$ETIME-ELECTIVE //= (-3: uint)
$$ETIME-ELECTIVE //= (-6: uint)
$$ETIME-ELECTIVE //= (-9: uint)
$$ETIME-ELECTIVE //= (-12: uint)
$$ETIME-ELECTIVE //= (-15: uint)
$$ETIME-ELECTIVE //= (-18: uint)

These keys exist so you can represent pairs of the form second/decimal fraction of a second, like the C timespec you'll find in Section 7.27.1 of [C] 🧚 When you ingest a timestamp with one of these keys into a type from the target platform, be careful to respect that type's invariants 🫢 For example, for C timespec, the fractional part tv_nsec needs to sit between 0 inclusive and 10^9 exclusive, and you can get it there by adjusting the base time too.

3.4. Keys -1, -13, and 13: Timescale ⏰

Keys -1, -13, and 13 are how you say which timescale you're using, and key 13 is the critical one πŸ‘‘ Keys -1 and -13 mean exactly the same thing 😭 (they both exist because key -1 came first, and then when key 13 showed up, it felt right to have a negative twin). Each extended time data item MUST NOT contain more than one of these keys.

The value 0 means UTC, counted from the POSIX epoch [TIME_T]. The value 1 means TAI, counted from the Precision Time Protocol (PTP) epoch (1 January 1970 00:00:00 TAI, see [IEEE1588-2019] or [IEEE1588-2008]).

$$ETIME-ELECTIVE //= (-1 => $ETIME-TIMESCALE)
$$ETIME-ELECTIVE //= (-13 => $ETIME-TIMESCALE)
$$ETIME-CRITICAL //= (13 => $ETIME-TIMESCALE)

$ETIME-TIMESCALE /= &(etime-utc: 0)
$ETIME-TIMESCALE /= &(etime-tai: 1)

If none of the keys are present, the default timescale value 0 is implied 🌸

Timescale values MUST be unsigned integers or text strings. Text strings are just for experimenting πŸ§ͺ and they MUST NOT be used between parties that aren't both part of the experiment. Extra unsigned integer values can be registered in the "Timescales" registry (Section 7.2). (Also, there should be no timescales "GPS" or "NTP" [RFC5905]. Instead, convert the time to TAI or UTC with one single addition or subtraction, bestie πŸ™ˆ)

t    = t    - 2208988800
 utc    ntp

t    = t    + 315964819
 tai    gps

            Figure 2: Converting Common Offset Timescales
Editor's note, but make it cute: this first set of timescales was deliberately kept small πŸŽ€ because the tag has an extension point where new timescales can be registered at any time. Earth-referenced timescales like UT1 and TT clearly need registrations, and so might specific versions of abstract timescales, like TAI(USNO), the realization made at the United States Naval Observatory, which works better as a constant-offset basis for GPS times. Registering is the easy part. These registrations do need to be based on a solid specification of what the timescale actually is πŸ’…

3.5. Clock Quality πŸ•°οΈ

There are a bunch of keys for describing how good the clock was when it figured out the point in time, and the first three are basically the clock-quality-grouping from [RFC8575]. That one is based on [IEEE1588-2008]. The last two are all ours πŸ’–

ClockQuality-group = (
  ? &(ClockClass: -2) => uint .size 1 ; PTP/RFC8575
  ? &(ClockAccuracy: -4) => uint .size 1 ; PTP/RFC8575
  ? &(OffsetScaledLogVariance: -5) => uint .size 2 ; PTP/RFC8575
  ? &(Uncertainty: -7) => ~time/~duration
  ? &(Guarantee: -8) => ~time/~duration
)

3.5.1. ClockClass (Key -2)

Key -2 (ClockClass) can tell you the clock class as defined in [RFC8575]. That's based on Table 5 in Section 7.6.2.4 of [IEEE1588-2008], and Table 4 in Section 7.6.2.5 of [IEEE1588-2019] has the updated wording πŸ“š It's a one-byte unsigned integer, since that's the range IEEE 1588 defines.

3.5.2. ClockAccuracy (Key -4)

Key -4 (ClockAccuracy) can tell you the clock accuracy, as in [RFC8575]. That's based on Table 6 in Section 7.6.2.5 of [IEEE1588-2008], and more values were added in Table 5 in Section 7.6.2.6 of [IEEE1588-2019] ✨ It's a one-byte unsigned integer, because that's the range defined there. The range from 23 to 47 is a slightly bent logarithmic scale running from 1 ps to 1 s in [IEEE1588-2019]. (In [IEEE1588-2008], the range was a smaller slice of that, 32 to 47, covering 25 ns to 1 s.) See Figure 3 for the math. And if you need to say the accuracy is unknown, use 254 πŸ™ˆ

                         acc
enum    β‰ˆ 48 + ⌊2 β‹…log   ──── - Ξ΅βŒ‹
    acc               10  s
      Figure 3: Approximate Conversion from Accuracy to Accuracy
                          Enumeration Value

3.5.3. OffsetScaledLogVariance (Key -5)

Key -5 (OffsetScaledLogVariance) shows how much the clock wobbles once it has lost sync with an external reference clock 🌊 The full details for working this out are in Section 7.6.3 of [IEEE1588-2019], and the same section in [IEEE1588-2008].

3.5.4. Uncertainty (Key -7)

Key -7 (Uncertainty) can represent a known measurement uncertainty for the clock, either as a numeric value in seconds or as a duration (Section 4) 🎯

For this document, uncertainty is defined as in Section 2.2.3 of [GUM]: "parameter, associated with the result of a measurement, that characterizes the dispersion of the values that could reasonably be attributed to the measurand". More specifically, the value for this key is the expanded uncertainty for k = 2 (Section 6.2.1 of [GUM]), in seconds.

Note that there isn't much extra info you can meaningfully stick onto a duration that's already representing an uncertainty. For example, nobody usually gives an uncertainty for an uncertainty πŸ™ƒ Implementations are free to trim down the information in an uncertainty (which is already elective) to whatever they can actually process.

For example, a timestamp given to a resolution of 10^-6 seconds (microseconds) but with an uncertainty of only 10^-3 seconds (milliseconds) could be written with one of the extended time tags in Figure 4. (Heads up, the third case has a slight rounding error, but it's probably fine for an uncertainty value πŸ“)

1001({1: 1697724754, -6: 873294, -7: {1: 0, -6: 1000}}),
1001({1: 1697724754, -6: 873294, -7: {1: 0, -3: 1}}),
1001({1: 1697724754, -6: 873294, -7: {1: 0.001}})
                 Figure 4: Examples Using Uncertainty

3.5.5. Guarantee (Key -8)

Key -8 (Guarantee) can represent a stated guarantee for how accurate the point in time is, either as a numeric value in seconds or as a duration (Section 4). It stands for the maximum allowed deviation from the true value πŸ”’

A guarantee like this is impossible in theory, but existing standards such as [RFC3161] spell out how to represent one, so this format gives you a way to do it too. The time value is nominally guaranteed not to deviate from the actual time by more than the guarantee, in seconds ✨

Note that there isn't much extra info you can meaningfully stick onto a duration that's representing a guarantee. For example, it doesn't make sense to give an accuracy guarantee for a duration that's already a guarantee of accuracy πŸ’€ Implementations are free to trim a guarantee (which is already elective) down to whatever they can process.

3.6. Keys -10, 10: Time Zone Hint 🌍

Keys -10 and 10 add a little supplementary info, and key 10 is the critical one πŸ’œ

They give a hint about which time zone would best suit showing the time to humans. The hint is a text string in the format defined for time-zone-name or time-numoffset in [RFC9557]. Key -10 gives you this as an elective hint, while key 10 gives it to you as critical, meaning it MUST be used when interpreting the entry with this key πŸ‘‘

Keys -10 and 10 MUST NOT both be present.

$$ETIME-ELECTIVE //= (-10: time-zone-info)
$$ETIME-CRITICAL //= (10: time-zone-info)

time-zone-info = tstr .abnf
                 ("time-zone-name / time-numoffset" .det IXDTFtz)
IXDTFtz = '
   time-hour       = 2DIGIT  ; 00-23
   time-minute     = 2DIGIT  ; 00-59
   time-numoffset  = ("+" / "-") time-hour ":" time-minute

   time-zone-initial = ALPHA / "." / "_"
   time-zone-char    = time-zone-initial / DIGIT / "-" / "+"
   time-zone-part    = time-zone-initial *time-zone-char
                       ; but not "." or ".."
   time-zone-name    = time-zone-part *("/" time-zone-part)
   ALPHA             =  %x41-5A / %x61-7A   ; A-Z / a-z
   DIGIT             =  %x30-39 ; 0-9
' ; extracted from [RFC9557] and [RFC3339]

3.7. Keys -11, 11: IXDTF Suffix Information πŸ’–

okay so keys -11 and 11 are the suffix buddies πŸŽ€ they carry extra info in the same style as Internet Extended Date/Time Format (IXDTF) suffixes, like which calendar is best for showing the time to actual humans πŸ“…. key -11 is elective, key 11 is critical ✨. the value is a map where the keys are IXDTF suffix-key names and the values are the matching suffix values, and it looks like this:

$$ETIME-ELECTIVE //= (-11: suffix-info-map)
$$ETIME-CRITICAL //= (11: suffix-info-map)

suffix-info-map = { * suffix-key => suffix-values }
suffix-key = tstr .abnf ("suffix-key" .det IXDTF)
suffix-values = one-or-more<suffix-value>
one-or-more<T> = T / [ 2* T ]
suffix-value = tstr .abnf ("suffix-value" .det IXDTF)

IXDTF = '
   key-initial       = lcalpha / "_"
   key-char          = key-initial / DIGIT / "-"
   suffix-key        = key-initial *key-char

   suffix-value      = 1*alphanum
   alphanum          = ALPHA / DIGIT
   lcalpha           =  %x61-7A
   ALPHA             =  %x41-5A / %x61-7A   ; A-Z / a-z
   DIGIT             =  %x30-39 ; 0-9
' ; extracted from [RFC9557]

bestie, if keys -11 and 11 are both in the same time tag, the two maps MUST NOT have any entries with the same map keys πŸ™…β€β™€οΈ no double dipping!!

Figure 4 of [RFC9557] has a cute example of an extended date-time with both a time zone and suffix info 🌈:

1996-12-19T16:39:57-08:00[America/Los_Angeles][u-ca=hebrew]

and the closest CBOR diagnostic notation version would be:

/ 1996-12-19T16:39:57-08:00[America//Los_Angeles][u-ca=hebrew] /
1001({ 1: 851042397,
     -10: "America/Los_Angeles",
     -11: { "u-ca": "hebrew" }
})

notice that both -10 and -11 use negative keys, so they're elective info, same as the IXDTF form in the comment πŸ¦‹. also, the time numeric offset (-08:00) gets lost when you translate the [RFC3339] info from IXDTF into a POSIX time for key 1 in a time tag 😭. the offset just doesn't survive the trip!


4. Duration Format ⏱️

a duration is the length of an interval of time ✨. in this format, durations are in International System of Units (SI) seconds, and they can be adjusted for conventional corrections of the timescale given (like leap seconds) 🧚.

except for using tag 1002 instead of 1001, durations are structurally the same as time values πŸ’….

Duration = #6.1002(etime-detailed)

semantically, durations don't measure time elapsed from an epoch. they measure from the start to the end of an (otherwise unspecified) interval of time πŸ’œ.

with an epoch identified in the context, a duration can also express an absolute time 🎯.

without that context, durations come with some uncertainties from the timescale they use πŸ™ˆ. like, for durations meant to determine future time periods, there's some uncertainty about what irregularities (such as leap seconds and timescale corrections) the timescale will show in that period. for durations that measure past periods, turning the period into a duration loses some detail about timescale irregularities. for lots of applications these uncertainties are totally fine, so using durations is appropriate πŸ‘‘.

Note that the durations defined in [ISO8601:1988] and [ISO8601-1:2019] are rather different from the ones defined in the present specification; there is no intention to support ISO 8601 durations here.

5. Period Format πŸ¦‹

a period is a specific interval of time 🌸. you give it as either two extended times (the start and the end of the interval), or as one of those two plus a duration ✨.

it's represented as an array of unwrapped time and duration elements, tagged with tag 1003, and it's one of these:

  • a start and end time, in which case the tag content is an array of two unwrapped extended time elements, or
  • a start time with duration or an end time with duration. The tag content is an array of 3 elements: the first two as above but either the start or end time MUST be set to null and the third one then is an unwrapped duration.

here's a simple CDDL definition that doesn't capture all the constraints (so it's not the full story πŸ’€):

simple-Period = #6.1003([
  start: ~Etime / null
  end: ~Etime / null
  ? duration: ~Duration
])

exactly two out of the three elements have to be present and non-null 🫢. you can say that more verbosely in CDDL like this:

Period = #6.1003([
  (start: ~Etime,
   ((end: ~Etime) //
    (end: null,
     duration: ~Duration))) //
  (start: null,
   end: ~Etime,
   duration: ~Duration)
])

6. CDDL Type Names πŸŽ€

when you don't need detailed validation, the type names in Figure 5 are recommended πŸ’–. they're nice and simple:

etime = #6.1001({* (int/tstr) => any})
duration = #6.1002({* (int/tstr) => any})
period = #6.1003([~etime/null, ~etime/null, ?~duration])

Figure 5: Recommended Type Names for CDDL


7. IANA Considerations πŸ’…

7.1. CBOR Tags 🏷️

in the "CBOR Tags" registry [IANA.cbor-tags], IANA has allocated the tags in Table 2 πŸŽ‰:

+======+===========+===============+======================+
|  Tag | Data Item | Semantics     | Reference            |
+======+===========+===============+======================+
| 1001 | map       | extended time | [RFC9581, Section 3] |
+------+-----------+---------------+----------------------+
| 1002 | map       | duration      | [RFC9581, Section 4] |
+------+-----------+---------------+----------------------+
| 1003 | array     | period        | [RFC9581, Section 5] |
+------+-----------+---------------+----------------------+

Table 2: Values for Tags

IANA has updated the "Data Item" column for tag 1003 from "map" to "array" πŸ”„. glow-up era 🌟.

7.2. Timescales Registry ⏳

per this specification, IANA has created a brand new "Timescales" registry inside the "Concise Binary Object Representation (CBOR) Tags" registry group [IANA.cbor-tags] πŸ†•. registration needs both "Expert Review" and "RFC Required" (Sections 4.5 and 4.7 of RFC 8126 [BCP26], respectively) πŸ”.

each entry needs a timescale name (uppercase ASCII letters and digits, where a digit can't be at the start: [A-Z][A-Z0-9]*), a value (CBOR unsigned integer, uint, 0..18446744073709551615), a brief description of the semantics, and a specification reference (RFC) πŸ“. the initial contents are in Table 3 πŸ’œ:

+===========+=======+======================+===========+
| Timescale | Value | Semantics            | Reference |
+===========+=======+======================+===========+
| UTC       |     0 | UTC with POSIX Epoch | [RFC9581] |
+-----------+-------+----------------------+-----------+
| TAI       |     1 | TAI with PTP Epoch   | [RFC9581] |
+-----------+-------+----------------------+-----------+

Table 3: Initial Content of Timescale Registry

7.3. Time Tag Map Keys Registry ✨

okay bestie so IANA made a brand new "Time Tag Map Keys" registry πŸ—‚οΈ and it lives inside the "Concise Binary Object Representation (CBOR) Tags" registry group [IANA.cbor-tags]. To get in, you need "Specification Required" (Section 4.6 of RFC 8126 [BCP26]), which is basically the velvet rope πŸŽ€.

The designated expert is asked to give the shortest key values, the 1+0 and 1+1 encodings πŸ¦‹, to the registrations that are likely to get used a LOT and actually benefit from being short. No cap, that's the VIP section πŸ‘‘.

Every entry needs three things: a map key value (a CBOR integer, int, in the range -18446744073709551616..18446744073709551615), a brief description of what it means, and a specification reference πŸ“. Negative integers mean an elective key πŸŒ™, while unsigned integers mean a key that either provides a base time or is critical πŸ”₯. The expert should chat with the registrant about whether it's worth registering an elective and a critical key for the same info, where the elective key is the negative of the critical one. It's like how -11 and 11 got assigned in Table 4, iykyk 🫢. For unsigned integer keys, the choice of base time or critical has to be spelled out in the brief semantics description. (Elective keys can be marked as elective in the description, for example to tell them apart from critical keys πŸ’œ.)

The initial contents are in Table 4 🌸:

+=======+=====================================+============+
| Value | Semantics                           | Reference  |
+=======+=====================================+============+
|   -18 | attoseconds                         | [RFC9581]  |
+-------+-------------------------------------+------------+
|   -15 | femtoseconds                        | [RFC9581]  |
+-------+-------------------------------------+------------+
|   -13 | timescale (elective)                | [RFC9581]  |
+-------+-------------------------------------+------------+
|   -12 | picoseconds                         | [RFC9581]  |
+-------+-------------------------------------+------------+
|   -11 | IXDTF Suffix Information (elective) | [RFC9581], |
|       |                                     | [RFC9557]  |
+-------+-------------------------------------+------------+
|   -10 | IXDTF Time Zone Hint (elective)     | [RFC9581], |
|       |                                     | [RFC9557]  |
+-------+-------------------------------------+------------+
|    -9 | nanoseconds                         | [RFC9581]  |
+-------+-------------------------------------+------------+
|    -8 | Guarantee                           | [RFC9581]  |
+-------+-------------------------------------+------------+
|    -7 | Uncertainty                         | [RFC9581]  |
+-------+-------------------------------------+------------+
|    -6 | microseconds                        | [RFC9581]  |
+-------+-------------------------------------+------------+
|    -5 | Offset-Scaled Log Variance          | [RFC9581]  |
+-------+-------------------------------------+------------+
|    -4 | Clock Accuracy                      | [RFC9581]  |
+-------+-------------------------------------+------------+
|    -3 | milliseconds                        | [RFC9581]  |
+-------+-------------------------------------+------------+
|    -2 | Clock Class                         | [RFC9581]  |
+-------+-------------------------------------+------------+
|    -1 | timescale (elective) legacy         | [RFC9581]  |
+-------+-------------------------------------+------------+
|     1 | base time value as in CBOR tag 1    | [RFC8949], |
|       |                                     | [RFC9581]  |
+-------+-------------------------------------+------------+
|     4 | base time value as in CBOR tag 4    | [RFC8949], |
|       |                                     | [RFC9581]  |
+-------+-------------------------------------+------------+
|     5 | base time value as in CBOR tag 5    | [RFC8949], |
|       |                                     | [RFC9581]  |
+-------+-------------------------------------+------------+
|    10 | IXDTF Time Zone Hint (critical)     | [RFC9557], |
|       |                                     | [RFC9581]  |
+-------+-------------------------------------+------------+
|    11 | IXDTF Suffix Information (critical) | [RFC9557], |
|       |                                     | [RFC9581]  |
+-------+-------------------------------------+------------+
|    13 | timescale (critical)                | [RFC9581]  |
+-------+-------------------------------------+------------+

Table 4: Initial Content of Time Tag Map Keys Registry


8. Security Considerations πŸ”

The security considerations of [RFC8949] apply. The tags introduced here are not expected to raise security considerations beyond those 🫢.

Time, of course, has significant security considerations 😭. These include the exploitation of ambiguities where time is security relevant (for example, for freshness or in a validity span) and the disclosure of characteristics of the emitting system (for example, time zone or clock resolution and wall clock offset). Bestie, this is serious business πŸ’€.

A more detailed discussion of security considerations that come from using a representation of time that allows the inclusion of complex and possibly inconsistent information is available in "Security Considerations" (Section 7 of [RFC9557]) πŸ”₯.


9. References πŸ“š

9.1. Normative References

[BCP26]: Best Current Practice 26, https://www.rfc-editor.org/info/bcp26. At the time of writing, this BCP comprises the following:

Cotton, M., Leiba, B., and T. Narten, "Guidelines for Writing an IANA Considerations Section in RFCs", BCP 26, RFC 8126, DOI 10.17487/RFC8126, June 2017, https://www.rfc-editor.org/info/rfc8126.

[GUM]: Joint Committee for Guides in Metrology, "Evaluation of measurement data -- Guide to the expression of uncertainty in measurement", JCGM 100:2008, September 2008, https://www.bipm.org/en/publications/guides/gum.html.

[IANA.cbor-tags]: IANA, "Concise Binary Object Representation (CBOR) Tags", https://www.iana.org/assignments/cbor-tags.

[IEEE1588-2008]: IEEE, "IEEE Standard for a Precision Clock Synchronization Protocol for Networked Measurement and Control Systems", IEEE 1588-2008, July 2008, https://standards.ieee.org/ieee/1588/4355/. Often called PTP v2, as it replaced the earlier 2002 version of this standard by a non-backwards compatible protocol.

[IEEE1588-2019]: IEEE, "IEEE Standard for a Precision Clock Synchronization Protocol for Networked Measurement and Control Systems", IEEE 1588-2019, June 2020, https://standards.ieee.org/ieee/1588/6825/. Often called PTP v2.1, as it has been designed so it can be used in a way that is fully backwards compatible to IEEE1588-2008.

[RFC2119]: Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997, https://www.rfc-editor.org/info/rfc2119.

[RFC8174]: Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, May 2017, https://www.rfc-editor.org/info/rfc8174.

[RFC8575]: Jiang, Y., Ed., Liu, X., Xu, J., and R. Cummings, Ed., "YANG Data Model for the Precision Time Protocol (PTP)", RFC 8575, DOI 10.17487/RFC8575, May 2019, https://www.rfc-editor.org/info/rfc8575.

[RFC8610]: Birkholz, H., Vigano, C., and C. Bormann, "Concise Data Definition Language (CDDL): A Notational Convention to Express Concise Binary Object Representation (CBOR) and JSON Data Structures", RFC 8610, DOI 10.17487/RFC8610, June 2019, https://www.rfc-editor.org/info/rfc8610.

[RFC8949]: Bormann, C. and P. Hoffman, "Concise Binary Object Representation (CBOR)", STD 94, RFC 8949, DOI 10.17487/RFC8949, December 2020, https://www.rfc-editor.org/info/rfc8949.

[RFC9557]: Sharma, U. and C. Bormann, "Date and Time on the Internet: Timestamps with Additional Information", RFC 9557, DOI 10.17487/RFC9557, April 2024, https://www.rfc-editor.org/info/rfc9557.

[SI-SECOND]: ISO, "Quantities and units -- Part 3: Space and time", ISO 80000-3:2019, October 2019, https://www.iso.org/standard/64974.html.

[TIME_T]: IEEE, "The Open Group Base Specifications Issue 7", Section 4.16 Seconds Since the Epoch, IEEE Std 1003.1-2017, 2018, http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_16.

9.2. Informative References

[C]: ISO, "Information technology -- Programming languages -- C", Fourth Edition, ISO/IEC 9899:2018, June 2018, https://www.iso.org/standard/74528.html. Contents available via https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2310.pdf

[IEEE754]: IEEE, "IEEE Standard for Floating-Point Arithmetic", IEEE 754-2019, DOI 10.1109/IEEESTD.2019.8766229, July 2019, https://ieeexplore.ieee.org/document/8766229.

[ISO8601-1:2019]: ISO, "Date and time -- Representations for information interchange -- Part 1: Basic rules", ISO 8601-1:2019, February 2019, https://www.iso.org/standard/70907.html.

[ISO8601:1988]: ISO, "Data elements and interchange formats -- Information interchange -- Representation of dates and times", ISO 8601:1988, June 1988, https://www.iso.org/standard/15903.html. Also available from https://nvlpubs.nist.gov/nistpubs/Legacy/FIPS/fipspub4-1-1991.pdf (https://nvlpubs.nist.gov/nistpubs/Legacy/FIPS/fipspub4-1-1991.pdf)

[RFC3161]: Adams, C., Cain, P., Pinkas, D., and R. Zuccherato, "Internet X.509 Public Key Infrastructure Time-Stamp Protocol (TSP)", RFC 3161, DOI 10.17487/RFC3161, August 2001, https://www.rfc-editor.org/info/rfc3161.

[RFC3339]: Klyne, G. and C. Newman, "Date and Time on the Internet: Timestamps", RFC 3339, DOI 10.17487/RFC3339, July 2002, https://www.rfc-editor.org/info/rfc3339.

[RFC5905]: Mills, D., Martin, J., Ed., Burbank, J., and W. Kasch, "Network Time Protocol Version 4: Protocol and Algorithms Specification", RFC 5905, DOI 10.17487/RFC5905, June 2010, https://www.rfc-editor.org/info/rfc5905.

Appendix A. Collected CDDL ✨

This appendix is basically the greatest hits album πŸ’Ώ of every CDDL rule from the whole doc, all in one spot so you don't have to dig through the sections like it's a treasure hunt πŸ—ΊοΈ. Bestie, this is the one to screenshot πŸ“Έ.

Etime = #6.1001(etime-detailed)

etime-framework = {
  uint => any ; at least one base time
  * (nint/text) => any ; elective supplementary information
  * uint => any ; critical supplementary information
}

etime-detailed = ({
  $$ETIME-BASETIME
  ClockQuality-group
  * $$ETIME-ELECTIVE
  * $$ETIME-CRITICAL
  * ((nint/text) .feature "etime-elective-extension") => any
  * (uint .feature "etime-critical-extension") => any
}) .within etime-framework


$$ETIME-BASETIME //= (1: ~time)


$$ETIME-BASETIME //= (4: ~decfrac)
$$ETIME-BASETIME //= (5: ~bigfloat)


$$ETIME-ELECTIVE //= (-3: uint)
$$ETIME-ELECTIVE //= (-6: uint)
$$ETIME-ELECTIVE //= (-9: uint)
$$ETIME-ELECTIVE //= (-12: uint)
$$ETIME-ELECTIVE //= (-15: uint)
$$ETIME-ELECTIVE //= (-18: uint)


$$ETIME-ELECTIVE //= (-1 => $ETIME-TIMESCALE)
$$ETIME-ELECTIVE //= (-13 => $ETIME-TIMESCALE)
$$ETIME-CRITICAL //= (13 => $ETIME-TIMESCALE)

$ETIME-TIMESCALE /= &(etime-utc: 0)
$ETIME-TIMESCALE /= &(etime-tai: 1)


ClockQuality-group = (
  ? &(ClockClass: -2) => uint .size 1 ; PTP/RFC8575
  ? &(ClockAccuracy: -4) => uint .size 1 ; PTP/RFC8575
  ? &(OffsetScaledLogVariance: -5) => uint .size 2 ; PTP/RFC8575
  ? &(Uncertainty: -7) => ~time/~duration
  ? &(Guarantee: -8) => ~time/~duration
)


$$ETIME-ELECTIVE //= (-10: time-zone-info)
$$ETIME-CRITICAL //= (10: time-zone-info)

time-zone-info = tstr .abnf
                 ("time-zone-name / time-numoffset" .det IXDTFtz)
IXDTFtz = '
   time-hour       = 2DIGIT  ; 00-23
   time-minute     = 2DIGIT  ; 00-59
   time-numoffset  = ("+" / "-") time-hour ":" time-minute

   time-zone-initial = ALPHA / "." / "_"
   time-zone-char    = time-zone-initial / DIGIT / "-" / "+"
   time-zone-part    = time-zone-initial *time-zone-char
                       ; but not "." or ".."
   time-zone-name    = time-zone-part *("/" time-zone-part)
   ALPHA             =  %x41-5A / %x61-7A   ; A-Z / a-z
   DIGIT             =  %x30-39 ; 0-9
' ; extracted from [RFC9557] and [RFC3339]


$$ETIME-ELECTIVE //= (-11: suffix-info-map)
$$ETIME-CRITICAL //= (11: suffix-info-map)

suffix-info-map = { * suffix-key => suffix-values }
suffix-key = tstr .abnf ("suffix-key" .det IXDTF)
suffix-values = one-or-more<suffix-value>
one-or-more<T> = T / [ 2* T ]
suffix-value = tstr .abnf ("suffix-value" .det IXDTF)

IXDTF = '
   key-initial       = lcalpha / "_"
   key-char          = key-initial / DIGIT / "-"
   suffix-key        = key-initial *key-char

   suffix-value      = 1*alphanum
   alphanum          = ALPHA / DIGIT
   lcalpha           =  %x61-7A
   ALPHA             =  %x41-5A / %x61-7A   ; A-Z / a-z
   DIGIT             =  %x30-39 ; 0-9
' ; extracted from [RFC9557]


Duration = #6.1002(etime-detailed)


simple-Period = #6.1003([
  start: ~Etime / null
  end: ~Etime / null
  ? duration: ~Duration
])


Period = #6.1003([
  (start: ~Etime,
   ((end: ~Etime) //
    (end: null,
     duration: ~Duration))) //
  (start: null,
   end: ~Etime,
   duration: ~Duration)
])


etime = #6.1001({* (int/tstr) => any})
duration = #6.1002({* (int/tstr) => any})
period = #6.1003([~etime/null, ~etime/null, ?~duration])

Figure 6: Collected CDDL Rules from This Specification πŸŽ€

Acknowledgements 🫢

The authors wanna give a huge shoutout πŸ“£ to everyone in the CBOR WG who dropped comments, plus Francesca Palombini for her AD review, Thomas Fossati and Qin Wu for their directorate reviews, and Rohan Mahy for one more review late in the process. Literally the whole squad πŸ’œ.

Authors' Addresses πŸ¦‹

Carsten Bormann UniversitΓ€t Bremen TZI Postfach 330440 D-28359 Bremen Germany Phone: +49-421-218-63921 Email: cabo@tzi.org

Ben Gamari Well-Typed 117 Middle Rd. Portsmouth, NH 03801 United States of America Email: ben@well-typed.com

Henk Birkholz Fraunhofer Institute for Secure Information Technology Rheinstrasse 75 64295 Darmstadt Germany Email: henk.birkholz@ietf.contact


πŸ“¦ where this page comes from