Describe the problem
DateTimeKnownEncoding.unixTimestamp currently requires an integer wire type:
@encode(DateTimeKnownEncoding.unixTimestamp, int64)
scalar UnixTimestamp extends utcDateTime;
Unix time can also be represented as seconds with a fractional component, and JWT
NumericDate explicitly permits
non-integer values. TypeSpec currently cannot preserve both the datetime semantics and a
floating-point wire contract such as OpenAPI type: number, format: double:
- Modeling the field as
float64 preserves the wire value but loses the utcDateTime
semantics and causes SDKs to expose a numeric value.
- Using
@encode("unixTimestamp", int64) produces the desired datetime SDK type but narrows
the wire contract to whole-second integer values.
This surfaced while migrating Azure Attestation's JWT iat, exp, and nbf claims from
Swagger to TypeSpec. Modeling contemporary Unix timestamps as float32 introduces severe
precision loss, while changing them to int64 would no longer permit fractional values.
Proposed behavior
Allow unixTimestamp to use a floating-point wire type:
@encode(DateTimeKnownEncoding.unixTimestamp, float64)
scalar FractionalUnixTimestamp extends utcDateTime;
The unit would remain seconds since the Unix epoch:
- An integer encoded type represents whole seconds.
- A floating-point or decimal encoded type permits fractional seconds.
- Existing integer usages retain their current behavior.
Milliseconds or other units would still require separate encodings because they change the
unit, rather than only the precision.
The design should define how emitters round values to the precision supported by each
language's datetime type. float32 should either be rejected or produce a diagnostic because
it cannot accurately represent contemporary Unix-second timestamps.
Implementation considerations
- Compiler validation currently restricts
unixTimestamp to an integer encoded type.
- Emitters need to preserve the selected numeric wire type while exposing their native
datetime/instant type.
- The C# emitter currently uses
GetInt64(), DateTimeOffset.FromUnixTimeSeconds(), and
DateTimeOffset.ToUnixTimeSeconds() for this encoding and would need fractional-second
handling.
Related: #2887 clarified that unixTimestamp is measured in seconds. This
proposal retains that unit and only adds support for fractional seconds.
Describe the problem
DateTimeKnownEncoding.unixTimestampcurrently requires an integer wire type:Unix time can also be represented as seconds with a fractional component, and JWT
NumericDateexplicitly permitsnon-integer values. TypeSpec currently cannot preserve both the datetime semantics and a
floating-point wire contract such as OpenAPI
type: number, format: double:float64preserves the wire value but loses theutcDateTimesemantics and causes SDKs to expose a numeric value.
@encode("unixTimestamp", int64)produces the desired datetime SDK type but narrowsthe wire contract to whole-second integer values.
This surfaced while migrating Azure Attestation's JWT
iat,exp, andnbfclaims fromSwagger to TypeSpec. Modeling contemporary Unix timestamps as
float32introduces severeprecision loss, while changing them to
int64would no longer permit fractional values.Proposed behavior
Allow
unixTimestampto use a floating-point wire type:The unit would remain seconds since the Unix epoch:
Milliseconds or other units would still require separate encodings because they change the
unit, rather than only the precision.
The design should define how emitters round values to the precision supported by each
language's datetime type.
float32should either be rejected or produce a diagnostic becauseit cannot accurately represent contemporary Unix-second timestamps.
Implementation considerations
unixTimestampto anintegerencoded type.datetime/instant type.
GetInt64(),DateTimeOffset.FromUnixTimeSeconds(), andDateTimeOffset.ToUnixTimeSeconds()for this encoding and would need fractional-secondhandling.
Related: #2887 clarified that
unixTimestampis measured in seconds. Thisproposal retains that unit and only adds support for fractional seconds.