You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Issues like brimdata/zui#1057 and brimdata/brimcap#352 reflect users' desire to sometimes work in non-UTC timezones, such as their local time. The strftime function added in #5197 provides the %z and %Z formatting directives that could allow output of such timezones, but right now they only reflect the UTC timezone.
To improve on this, we've discussed approaches for a user to provde a hint for an alternate timezone such that the rendered time value and output of %z / %Z directives would reflect the delta. In preliminary discussions on this topic, we've reached some consensus on a proposal to add a third, optional parameter to our strftime that would provide that offset/timezone hint.
Details
Comparison With Other Tools
Users are likely to compare our timezone support to that of other tools and/or copy string-based time values between Zed tools and other tools, so it may be helpful to know how others approach this problem. Since they both support the same formatting options as our strftime, I happened to start with jq and GNU Date.
Since all these tools offer their own default/alternate formats, as a neutral starting point, I'll start from a UTC seconds-since-epoch value 1723662771 that roughly matches the time when this issue was written. I'm ignoring the fractional seconds for now because Zed has orthogonal catch-up to do there (#5220).
jq
jq has its strftime function that supports formatting options like Zed's function of the same name. Per their docs, it only is intended to format a time in UTC (well, they call it GMT).
For output in non-UTC timezones, jq offers a separatestrflocaltime function. By default it outputs time in the local timezone for the system on which jq is running, though it overrides that behavior if the TZ environment variable is set to something else. My Macbook happens to be in Pacific Daylight Time at the moment, so:
Though a close inspection of that output reveals a bug, which I see has already been filed as jqlang/jq#1912: They should have said -0700 and PDT, not -0800 and PST! Let's not have that bug in Zed. 😉
Going back to the regular strftime and its mission to be for UTC only, indeed it doesn't change the time value itself based on local system time or TZ variable (i.e., it's still in UTC), but it does still reflect a non-UTC timezone in the %z or %Z directives if invoked, which seems weird and like something else we'd not want to mimic. 😛
GNU Date effectively behaves like jq's strlocaltime by default (i.e., reflects local system timezone, or what's in TZ if present... though it does the right thing with daylight savings time!) with the formatting directives invoked via +.
If -u is added, now GNU Date behaves more like jq's strftime and renders in UTC, though unlike the weird jq behavior cited above, it appears strict in always reflecting UTC even in the timezone offset/abbreviations in %z or %Z.
While Zed's strftime supports %z and %Z for completeness, at the moment they only reflect UTC timezone. No attempt is made to reflect the local system time or check the TZ environment variable for a hint, so this all seems to match with GNU Date's -u behavior.
However, if provided a string representation of a time value that's got a non-UTC offset or timezone abbreviation, Zed's cast to its time type converts it to the appropriate UTC value. So, starting from the Pacific Time outputs from GNU Date shown previously, we get the same UTC outputs for both of these.
I point this out because I found that even as a non-string time literal, the language is already prepared to interpret timezone offsets correctly, but only if they include a colon.
$ echo '2024-08-14T12:12:51-07:00' | zq -z 'yield this' -
2024-08-14T19:12:51Z
$ echo '2024-08-14T12:12:51-0700' | zq -z 'yield this' -
stdio:stdin: format detection error
arrows: schema message length exceeds 1 MiB
csv: line 1: delimiter ',' not found
json: strconv.ParseFloat: parsing "2024-08-14": invalid syntax
line: auto-detection not supported
parquet: auto-detection requires seekable input
tsv: line 1: delimiter '\t' not found
vng: auto-detection requires seekable input
zeek: line 1: bad types/fields definition in zeek header
zjson: line 1: malformed ZJSON: bad type object: "2024-08-14T12:12:51-0700": unpacker error parsing JSON: invalid character '-' after top-level value
zng: unknown ZNG message frame type: 3
zson: ZSON syntax error
I peeked at the code and I see how this all fits together. The Zed casting code for time (i.e., what would be used to convert string-based timestamps) ultimately depends on https://github.com/araddon/dateparse which is very flexible in which formats it accepts, hence offsets with and without colons are both fine. Meanwhile the ZSON parser (i.e., what would parse ZSON time literals) depends on the RFC3339Nano mode of Go's time.parse, and RFC3339only supports offsets with colons.
The ZSON spec describes time as a "an RFC 3339 UTC date/time string". Since the parser is ready to accept them with an offset as long as there's a colon, perhaps we could add a flag at some point to enable printing the ZSON time values with a specified offset. If we did that it would probably also make sense to add an formatting directive to Zed's strftime function to include the colons, since https://github.com/lestrrat-go/strftime doesn't currently offer one. (#5253) FWIW, other tools like GNU Date or the JavaScript library https://github.com/samsonjs/strftime provide offset-with-colon via directive %:z.
Zed Proposals
In a preliminary discussion on this topic, @mattnibs made the following proposal:
I could imagine strftime taking a third duration argument that specifies the offset of timezone and then you could use the %z directive to display the timezone. We could have a timezone function that would return the offset.
Eg strftime(“%z”, now(), tz(“PST”))
@nwt had a preference for a string argument instead of a duration+function, such that the user could directly input an offset or supported timezone name/abbreviation.
Implementation details aside, these ideas do seem like they'd provide the base functionality that's currently missing.
That said, this requires the user to lock their timezone within the Zed program, which seems less convenient than how jq and GNU Date provided ways to automatically reflect the system's local time or an alternate timezone specified in TZ. Environments may want this if they have users spread across multiple timezones running the same Zed programs that all want to see times presented in local format.
If we started from one of the proposals above, perhaps a way of calling the proposed tz function or a particular value for the proposed string argument could invoke the behavior seen with jq and GNU Date where it obeys the local system time and overrides that if TZ is set.
A possible alternative to the "third strftime parameter" approach might be to offer some kind of CLI option that allows the specification of an alternate timezone/offset (e.g., zq -tz="US/Eastern") and have that setting affect strftime and any other time-centric functionality we may add in the future (e.g., if we wanted to start allow for printing time literals with offsets rather than just strings via strftime.) One side effect of this approach is that it could provide a way for users to get the benefit of their TZ environment variable without the Zed tooling having to explicitly know about it, e.g., if they invoke with zq -ts=$TZ.
Zui Proposals
Addressing this data presentation topic in Zui is covered separately in brimdata/zui#1057.
The text was updated successfully, but these errors were encountered:
tl;dr
Issues like brimdata/zui#1057 and brimdata/brimcap#352 reflect users' desire to sometimes work in non-UTC timezones, such as their local time. The
strftime
function added in #5197 provides the%z
and%Z
formatting directives that could allow output of such timezones, but right now they only reflect the UTC timezone.To improve on this, we've discussed approaches for a user to provde a hint for an alternate timezone such that the rendered time value and output of
%z
/%Z
directives would reflect the delta. In preliminary discussions on this topic, we've reached some consensus on a proposal to add a third, optional parameter to ourstrftime
that would provide that offset/timezone hint.Details
Comparison With Other Tools
Users are likely to compare our timezone support to that of other tools and/or copy string-based time values between Zed tools and other tools, so it may be helpful to know how others approach this problem. Since they both support the same formatting options as our
strftime
, I happened to start withjq
and GNU Date.Since all these tools offer their own default/alternate formats, as a neutral starting point, I'll start from a UTC seconds-since-epoch value
1723662771
that roughly matches the time when this issue was written. I'm ignoring the fractional seconds for now because Zed has orthogonal catch-up to do there (#5220).jq
jq
has itsstrftime
function that supports formatting options like Zed's function of the same name. Per their docs, it only is intended to format a time in UTC (well, they call it GMT).For output in non-UTC timezones,
jq
offers a separatestrflocaltime
function. By default it outputs time in the local timezone for the system on whichjq
is running, though it overrides that behavior if theTZ
environment variable is set to something else. My Macbook happens to be in Pacific Daylight Time at the moment, so:Adding the
%z
or%Z
directives can show the offset or timezone abbreviation, respectively.Though a close inspection of that output reveals a bug, which I see has already been filed as jqlang/jq#1912: They should have said
-0700
andPDT
, not-0800
andPST
! Let's not have that bug in Zed. 😉Going back to the regular
strftime
and its mission to be for UTC only, indeed it doesn't change the time value itself based on local system time or TZ variable (i.e., it's still in UTC), but it does still reflect a non-UTC timezone in the%z
or%Z
directives if invoked, which seems weird and like something else we'd not want to mimic. 😛GNU Date
GNU Date effectively behaves like
jq
'sstrlocaltime
by default (i.e., reflects local system timezone, or what's inTZ
if present... though it does the right thing with daylight savings time!) with the formatting directives invoked via+
.If
-u
is added, now GNU Date behaves more likejq
'sstrftime
and renders in UTC, though unlike the weirdjq
behavior cited above, it appears strict in always reflecting UTC even in the timezone offset/abbreviations in%z
or%Z
.Zed
Repro is with Zed commit 71e35c5.
While Zed's
strftime
supports%z
and%Z
for completeness, at the moment they only reflect UTC timezone. No attempt is made to reflect the local system time or check theTZ
environment variable for a hint, so this all seems to match with GNU Date's-u
behavior.However, if provided a string representation of a time value that's got a non-UTC offset or timezone abbreviation, Zed's cast to its
time
type converts it to the appropriate UTC value. So, starting from the Pacific Time outputs from GNU Date shown previously, we get the same UTC outputs for both of these.The same is true if there's a colon in the timezone offset.
I point this out because I found that even as a non-string
time
literal, the language is already prepared to interpret timezone offsets correctly, but only if they include a colon.I peeked at the code and I see how this all fits together. The Zed casting code for
time
(i.e., what would be used to convert string-based timestamps) ultimately depends on https://github.com/araddon/dateparse which is very flexible in which formats it accepts, hence offsets with and without colons are both fine. Meanwhile the ZSON parser (i.e., what would parse ZSONtime
literals) depends on theRFC3339Nano
mode of Go'stime.parse
, and RFC3339 only supports offsets with colons.The ZSON spec describes
time
as a "an RFC 3339 UTC date/time string". Since the parser is ready to accept them with an offset as long as there's a colon, perhaps we could add a flag at some point to enable printing the ZSONtime
values with a specified offset. If we did that it would probably also make sense to add an formatting directive to Zed'sstrftime
function to include the colons, since https://github.com/lestrrat-go/strftime doesn't currently offer one. (#5253) FWIW, other tools like GNU Date or the JavaScript library https://github.com/samsonjs/strftime provide offset-with-colon via directive%:z
.Zed Proposals
In a preliminary discussion on this topic, @mattnibs made the following proposal:
@nwt had a preference for a string argument instead of a
duration
+function, such that the user could directly input an offset or supported timezone name/abbreviation.Implementation details aside, these ideas do seem like they'd provide the base functionality that's currently missing.
That said, this requires the user to lock their timezone within the Zed program, which seems less convenient than how
jq
and GNU Date provided ways to automatically reflect the system's local time or an alternate timezone specified inTZ
. Environments may want this if they have users spread across multiple timezones running the same Zed programs that all want to see times presented in local format.If we started from one of the proposals above, perhaps a way of calling the proposed
tz
function or a particular value for the proposed string argument could invoke the behavior seen withjq
and GNU Date where it obeys the local system time and overrides that ifTZ
is set.A possible alternative to the "third
strftime
parameter" approach might be to offer some kind of CLI option that allows the specification of an alternate timezone/offset (e.g.,zq -tz="US/Eastern"
) and have that setting affectstrftime
and any other time-centric functionality we may add in the future (e.g., if we wanted to start allow for printingtime
literals with offsets rather than just strings viastrftime
.) One side effect of this approach is that it could provide a way for users to get the benefit of theirTZ
environment variable without the Zed tooling having to explicitly know about it, e.g., if they invoke withzq -ts=$TZ
.Zui Proposals
Addressing this data presentation topic in Zui is covered separately in brimdata/zui#1057.
The text was updated successfully, but these errors were encountered: