All proposals
OFP-014 DraftMedium

Define date-time semantics once, in a shared component

Every date-time field in the specifications carries its own copy of the same description, and not one of them says that the value identifies an instant in time. The text describes the encoding and stops there — so an implementation that reads 2027-07-22T00:00:00Z as local midnight is contradicted by nothing. In the UAE that is an error of four hours, invisible at a thirty-day horizon and fatal at a one-hour one. This proposal introduces a shared AEDateTime component that states the semantics once, and has every date-time field reference it.

Proposed by
Nebras
Author
Thomas Catchpole
Target
V2.2
Opened
16 Sep 2026
Closes
7 Oct 2026
Decision

Cast your vote

Sign in with the Trust Framework to vote — For, Against, or Abstain — recorded in the open with your reasoning. Your organisation and name come from your directory profile, and each person may vote once. Three questions are attached to this vote — set out in section 07 below. The first takes minutes to answer and is worth running before you vote; the second decides how far V2.2 goes.

§ BallotOFP-014Closes 7 Oct 2026 ·
Where do you stand?
Pick a stance to add your name & a comment.
0%
in favour
0
votes cast
0
For
0
Against
0
Abstain
Voting not yet open
Voting opens 16 Sep 2026
The proposal
01 · Background

The specification describes the encoding, not the meaning

A date-time field appears in almost every payload in the standard — ExpirationDateTime, CreationDateTime, TransactionDateTime, BookingDateTime, ValueDateTime, and many more. Each is defined as type: string, format: date-time, accompanied by a short description which is duplicated, with minor variations, across approximately twenty schema definitions.

Today — the definition, and what it leaves unsaid
# Today — one of ~20 near-identical definitions across the specifications

    AEConsentExpirationDateTime:
      description: |2-
            Specified date and time the consent will expire.

            All dates in the JSON payloads are represented in ISO 8601 date-time format.
            All date-time fields in responses must include the timezone. An example is :2023-04-05T10:43:07+00:00
      type: string
      format: date-time

# It describes the ENCODING. It never says the value identifies an INSTANT, and
# it never says that two encodings of the same instant are equivalent. An
# implementation that reads the date and time components as local time is not
# contradicted by anything above.

Nowhere does the standard say that a date-time identifies an instant, or that two encodings of the same instant are equivalent and must behave identically. A developer who reads the date and time components and ignores the offset has not contradicted the specification. They have simply read it literally.

Why this is worth a proposal rather than a bug report
  • The error is four hours, in the UAE, in the expiring direction. A value of 2027-07-22T00:00:00Z is 04:00 Gulf time. Read as local, it resolves four hours early. On a consent with a thirty-day expiry nobody notices; on one set an hour ahead the consent is already expired when it arrives.
  • Nothing in the ecosystem catches it. The value is well formed, so schema validation passes. The API Hub stores and returns it unchanged. The receiving system records a time that is simply wrong, and no error is raised at any hop.
  • It has already happened. This proposal follows a live integration in which a correctly-formed UTC consent expiry was interpreted as local time, causing short-window consents to fail on arrival. The reported symptom — “the LFI receives it without an offset” — was not what the wire showed.
  • Every participant carries the cost. Because the standard permits a range of encodings, each participant must implement normalisation for every counterparty it talks to. That is the same logic written many times over, and each implementation is an opportunity to get it wrong in a way nothing will flag.
02 · Recommendation

Say it once, in a component every field references

Introduce a single shared AEDateTime schema carrying the semantics, and replace the duplicated description on every date-time field with a reference to it. The rules become normative, stated in one place, and correctable in one place.

What the component establishes
  • A date-time is an instant. The offset is part of the value. Recipients MUST apply it and MUST NOT read the date and time components as local time.
  • Equivalent encodings MUST behave identically.2027-07-22T00:00:00Z and 2027-07-22T04:00:00+04:00 are the same value. This is the sentence that turns the defect above into a conformance failure.
  • Producers SHOULD emit UTCZ or +00:00 — which signals the direction of travel without requiring anyone to move at V2.2.
  • -00:00 MUST NOT be used. ISO 8601 prohibits a negative zero offset; RFC 3339 permits it but assigns it “local offset unknown” semantics, which is not what any producer in this ecosystem means.
  • Fractional seconds are optional, at unspecified precision — so recipients must accept their presence or absence, and must not compare these values as strings.
03 · Technical changes

One new schema, and a reference from every date-time field

Taking AEConsentExpirationDateTime as the worked example. The same treatment applies to every date-time field across every specification.

The shared component — added once
    AEDateTime:
      title: AEDateTime
      description: |
        An instant in time, per ISO 8601 / RFC 3339, with a mandatory offset.

        Recipients MUST apply the offset, and MUST NOT read the date and time
        components as local time. Encodings of the same instant are equivalent and
        MUST behave identically: `2027-07-22T00:00:00Z` and `2027-07-22T04:00:00+04:00`
        are the same value.

        Producers SHOULD emit UTC (`Z` or `+00:00`), and MUST NOT use `-00:00`.
        Fractional seconds are optional.
      type: string
      format: date-time
      example: "2027-07-22T00:00:00Z"
Each field — reference plus its own description
    AEConsentExpirationDateTime:
      allOf:
        - $ref: '#/components/schemas/AEDateTime'
        - description: Specified date and time the consent will expire.

# type and format are unchanged, so the wire format and schema validation are
# identical before and after. Every date-time field in every specification takes
# the same treatment, keeping its own field-specific description.

A short normative section is added to each specification’s info.description as well, so the rule is discoverable without reading a schema and certification has a single place to point at.

04 · Enforcement

Whether to add a pattern

As drafted, the rules above are prose: a non-conforming value still passes schema validation. A pattern would make one of them enforceable, at very little cost — but it would not reach the behaviour this proposal is chiefly concerned with.

The candidate pattern, and its verified behaviour
# Enforces the MUST NOT on -00:00, while permitting every other offset.
pattern: '^d{4}-d{2}-d{2}Td{2}:d{2}:d{2}(.d+)?(Z|+d{2}:d{2}|-(?:0[1-9]|1[0-2]):d{2})$'

# Verified behaviour:
#
#   2027-07-22T00:00:00Z              pass
#   2027-07-22T00:00:00.000Z          pass
#   2027-07-22T00:00:00+00:00         pass
#   2027-07-22T00:00:00.000+00:00     pass
#   2027-07-22T00:00:00.123456Z       pass
#   2027-07-22T04:00:00+04:00         pass
#   2027-07-22T00:00:00-05:00         pass
#   2027-07-22T00:00:00-00:00         REJECT
#   2027-07-22T00:00:00               REJECT
#   2027-07-22 00:00:00Z              REJECT
#   22/07/2027 00:00:00               REJECT
The distinction that matters
  • It enforces only the -00:00 prohibition. Every other offset continues to validate, so the only producers affected are those emitting a negative zero offset — which ISO 8601 already prohibits and which essentially nobody emits deliberately. It converts a MUST NOT from advice into a rule at close to zero migration cost.
  • Requiring UTC by schema is a different proposition, and is breaking. Any participant sending +04:00 today is conformant today and would be rejected the day it lands. That is a major-version change with a runway, not something to carry along with a clarification.
  • A pattern does not fix the actual defect. An implementation that ignores the offset on a perfectly valid Z value passes it. Enforcement addresses what is sent; the clarification in section 02 addresses how it is read, and only certification tests the latter.

The recommendation is to signal UTC as a SHOULD at V2.2, decide this pattern on the ecosystem’s answer to question 02, and defer any schema-enforced UTC requirement to a major version, with the runway sized by measured exposure rather than by assumption.

05 · Publication

A knowledge base article published alongside

The specification states the rule; the knowledge base explains how to satisfy it. An article — Date & Time Handling Across the Standard — publishes with this change.

06 · Requiring UTC

Constraining the format so that UTC is required outright

The stricter option: rather than recommending UTC, require it by schema. This proposal does not include it — but it is where the standard should eventually arrive, and it is put to the ecosystem as question 03 rather than settled in advance.

The change is a single added pattern on the shared component. Nothing else about AEDateTime moves, and no field definition changes — which is the advantage of having consolidated them in the first place.

AEDateTime, with UTC required
    AEDateTime:
      title: AEDateTime
      description: |
        An instant in time, per ISO 8601 / RFC 3339, expressed in UTC.

        Recipients MUST apply the offset, and MUST NOT read the date and time
        components as local time.

        Producers MUST emit UTC, using either `Z` or `+00:00`.
        Fractional seconds are optional.
      type: string
      format: date-time
      pattern: '^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|\+00:00)$'
      example: "2027-07-22T00:00:00Z"
Which strings the pattern admits
# Accepted
2027-07-22T00:00:00Z              # UTC, whole seconds
2027-07-22T00:00:00.000Z          # UTC, milliseconds
2027-07-22T00:00:00.123456Z       # UTC, any fractional precision
2027-07-22T00:00:00+00:00         # the zero offset written out in full
2027-07-22T00:00:00.000+00:00     # zero offset, milliseconds

# No longer valid — but conformant under V2.1, and in use today
2027-07-22T04:00:00+04:00         # Gulf Standard Time
2027-07-22T00:00:00-05:00         # any other non-UTC offset

# Invalid today, and still invalid under this pattern
2027-07-22T00:00:00-00:00         # negative zero offset
2027-07-22T00:00:00               # no offset at all
2027-07-22 00:00:00Z              # space instead of T
22/07/2027 00:00:00               # not ISO 8601

The recommendation remains to signal UTC as a SHOULD at V2.2 and require it at the next major version, with the runway set by measured exposure. If the answers to question 03 show the ecosystem would rather absorb the change in one step, that recommendation should be revisited before V2.2 is finalised.

07 · Questions

Three questions, asked with the vote

These appear as optional boxes when you confirm your vote. Answer the ones addressed to you — every voter sees both. The first is worth running before you vote: it takes minutes and needs no instrumentation.

01 · LFIs

Does your implementation treat 2027-07-22T00:00:00Z and 2027-07-22T04:00:00+04:00 as the same moment today — and if not, what is involved in correcting it?

These two strings are the same instant. The clarification makes any difference in behaviour between them a conformance failure, and it is the test certification would apply. The answer tells us whether this is a documentation change the ecosystem absorbs quietly or one that requires a remediation window — and it is worth running before voting, because it takes minutes and does not need any instrumentation.

02 · TPPs and LFIs

Should V2.2 also carry a pattern that prohibits -00:00 while continuing to permit non-UTC offsets, or should the schema stay unconstrained until a major version requires UTC outright?

The pattern in section 04 makes the MUST NOT on -00:00 enforceable at close to zero migration cost, since almost nobody emits it deliberately. Requiring UTC by schema is breaking for every participant currently sending a non-UTC offset — all of whom are conformant today. This asks whether the first is worth landing now, rather than waiting for the second.

03 · TPPs and LFIs

Should V2.2 require UTC outright by schema — so that +04:00 and every other non-UTC offset is rejected — or should that wait for a major version?

Section 06 sets out exactly what this would look like and which strings would stop being valid. It is the enforceable end state, and it would remove the equivalence class entirely rather than asking every participant to handle it. It is also breaking: any producer emitting a non-UTC offset is conformant today and would be rejected on the day it lands. This proposal defers it — the question asks whether the ecosystem would rather take it at V2.2 and absorb the migration in one step.

08 · Pros

What the component buys

  • It states the semantics that are currently missing. The existing text describes the encoding — "ISO 8601 date-time format", "must include the timezone" — but never says the value identifies an instant, which is the one sentence that makes ignoring the offset non-conformant.
  • It makes the defect testable. The equivalence example is itself a certification case: 2027-07-22T00:00:00Z and 2027-07-22T04:00:00+04:00 are the same moment, and any implementation that behaves differently for the two has a defect that can be demonstrated in a single call.
  • It is not a breaking change. type and format are unchanged, so the change is wire-identical and validation-identical. Every implementation conformant today stays conformant, and no participant is required to do anything on a date.
  • It collapses roughly twenty duplicated descriptions into one component. Today the same paragraph is restated per schema with minor variations, so it drifts and any correction has to be made in twenty places.
  • It costs the central platform nothing. No API Hub behaviour changes, no normalisation is introduced into the request path, and no new validation is added at V2.2 — the entire change is specification text.
  • It addresses a failure mode that does not announce itself. An implementation that ignores the offset is wrong by four hours in the UAE, which is invisible at a thirty-day horizon and severe at a one-hour one — so it reaches production and surfaces later as an unreproducible complaint.
09 · Cons

What it costs

  • ×A description is not enforcement. A non-conforming implementation still passes schema validation at V2.2, because the constraint lives in prose. Only functional certification would catch it, and only if the case is added there.
  • ×It touches every specification. The edit is mechanical but wide — roughly twenty schemas across data sharing, service initiation, confirmation of payee, insurance and the consent specs — and each site needs checking rather than a blind replace.
  • ×The allOf + $ref construction makes each field three lines where it was two, and some code generators flatten allOf poorly, producing a less readable model than the inline description did.
  • ×It does not repair implementations already in production. Participants who read the offset incorrectly today must still change their code; the clarification establishes that they are wrong, it does not fix them.
  • ×It defers the constraint that would actually prevent the problem. Requiring UTC by schema is the enforceable version, and this proposal explicitly leaves that to a major version — so the ambiguity remains legal in the meantime.