-
Notifications
You must be signed in to change notification settings - Fork 159
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Timezone and unix (absolute?) conversion #884
Comments
The thing you may be missing is that a const date = Temporal.DateTime.from('2020-01-03T19:41:00-08:00')
// ^ you lose the time zone here; DateTime only stores the '2020-01-03T19:41:00' part.
date.toAbsolute('UTC').toString(); // "2020-01-03T19:41:00Z"
// ^ this interprets '2020-01-03T19:41:00' as being in UTC As you noticed, A string without a time zone such as |
Thanks @Ms2ger for the insight; now that you mention this, it actually looks like none of the current |
Hi @stebogit - It's coming soon. #700 specifies this new DateTime+offset+TimeZone type (called LocalDateTIme as a placeholder, although the name will change) that's being finalized now. The plan is for it to be implemented in the polyfill soon. Could you clarify specifically the use case you're trying to support? Specifically, when you read the value back from your database, what type is that value? Is it an ISO 8601 string with offset, like Regardless, here's how you'd get each of those formats into a Temporal.Absolute instance, and then how you'd get it into a Temporal.LocalDateTime instance once that type lands in the polyfill: const abs = Temporal.Absolute.from(`2020-01-03T19:41:00-08:00`);
const abs = Temporal.Absolute.from(`2020-01-04T03:41:00Z`);
const abs = Temporal.Absolute.fromEpochSeconds(1599764621);
const abs = Temporal.Absolute.fromEpochMilliseconds(1599764621000);
// regardless of how you get it into Absolute, the conversion to LocalDateTime is the same
abs.toLocalDateTime('America/Los_Angeles', 'iso8601'); // first param is time zone, second is calendar And here's how you'd get them out once LocalDateTime lands in the polyfill: const ldt = Temporal.LocalDateTime.from(`2020-01-03T19:41:00-08:00[America/Los_Angeles]`);
ldt.toString(); // => "2020-01-03T19:41:00-08:00[America/Los_Angeles]"
ldt.toAbsolute().toString(); // => "2020-01-04T03:41Z"
ldt.toAbsolute().toString({ timeZone: 'America/Los_Angeles' }); // => "2020-01-03T19:41:00-08:00"
ldt.toAbsolute().getEpochSeconds(); // => 1578109260
ldt.toAbsolute().getEpochMilliseconds(); // => 1578109260000 Next question: how are you getting the time zone? Is it stored in a different column in the same table that also stores the from-epoch value that you're reading and writing? Or do you use the local timezone on the client? Or the server's system timezone? Or is the timezone stored in your database, just at a different granularity (e.g. per user) than the time data you're storing? Do you get it from some external system or API? Or some other way? Regardless of where you get the timezone, what format is the timezone represented as? As an IANA name like |
@stebogit - if you have a chance to reply to my questions in the previous comment, it'd be helpful for us as we figure out how best to address the concerns you raised. Thanks! |
@justingrant I sure will, tomorrow at latest. Sorry I planned to it today, but then carried away by #887 😅 |
MySQL's Regarding the timezone names/definition, IANA names/abbreviations are a widely adopted standard. However in my specific case I have to specify the offset ( For generating a local (user/system related) date/time object, usually both JS and PHP use the system timezone as default if none is passed to the constructor. Thanks for the code you provided for the const ldt = Temporal.LocalDateTime.from(`2020-01-03T19:41:00-08:00[America/Los_Angeles]`);
ldt.toString(); // => "2020-01-03T19:41:00-08:00[America/Los_Angeles]"
const abs = ldt.toAbsolute();
abs.toString(); // => "2020-01-04T03:41Z"
abs.toLocalDateTime('America/Los_Angeles').toString(); // => "2020-01-03T19:41:00-08:00" As a final note, all the examples above starts with a timestamp to instantiate the |
Yes. The most important thing that distinguishes LocalDateTime from other types is that it persists the time zone. LocalDateTime (or whatever its final name ends up being) will have a const midnight = Temporal.LocalDateTime.from('2020-03-08T00:00-08:00[America/Los_Angeles]');
midnight.hoursInDay;
// => 23
const noon = midnight.with({hour: 12});
noon.difference(midnight).toString()
// => "PT11H", because an hour is skipped by DST
midnight.plus({days: 1}).toString();
// => "2020-03-09T00:00-07:00[America/Los_Angeles]"
// adding days (or larger) units automatically adjust for DST, per RFC 5545
midnight.plus({hours: 24}).toString();
// => "2020-03-09T01:00-07:00[America/Los_Angeles]"
// adding hours (or smaller) units adds absolute time (ignoring DST) per RFC 5545
Your code sample is correct except the last line. Because LocalDateTime persists its time zone, the time zone will be emitted by abs.toLocalDateTime('America/Los_Angeles').toString(); // => "2020-01-03T19:41:00-08:00[America/Los_Angeles]" For your use case where you can't persist the full string, we're considering an option for You will also be able to emit the bracketless format directly from Absolute, as soon as the decisions from #741 (comment) get PR-ed. Example of how it will work: > abs.toString('America/Los_Angeles'); // => "2020-01-03T19:41:00-08:00" The reason this works is that Absolute has two valid string formats: one that's a UTC time ending in
Could you explain a little more about this use case? Specifically when you say "Pacific Standard Time (i.e. no DST) does not exist as string.", do you mean that if you add 6 months to one of these values, you'd expect the result to still be in -08:00 even though six months later the Pacific Time Zone would have -07:00 offset thanks to DST? Or do you simply mean that the back-end systems that you're working with don't have the ability to persist a value like Or do you mean something else? Please clarify. Thanks!
This "implicit local time zone" behavior is specifically NOT how Temporal behaves, because this behavior in other platforms has been the source of countless bugs, especially in server apps where the local time zone often won't match users' time zones. Instead, the only places where time zones are defaulted to the system time zone are the methods on |
I merely mean that, for some odd reason, a
The best way to align client and server(s) is to always use UTC timestamps everywhere (thus RFC3339). This will save you a lot of headaches and bugs. Only the client (as in "the user facing system") should apply the timezone offset, if necessary, as last step. const sysOffset = -(new Date()).getTimezoneOffset() / 60;
// -7
const sysTz = Math.abs(sysOffset) > 9
? `${sysOffset}:00`
: sysOffset > 0 ? `0${sysOffset}:00` : `-0${-sysOffset}:00`;
// -07:00 Does/will |
Yes. Temporal.now.timeZone();
// => America/Los_Angeles
Temporal.now.absolute();
// => 2020-09-19T22:33:49.592762660Z
Temporal.now.localDateTime(); // when it lands in a few weeks
// => 2020-09-19T15:32:49.592762660-07:00[America/Los_Angeles]
You can think of the IANA time zone database as a function that that accepts two parameters:
This "function" returns a calendar date and local clock time for that key (geographic area or single offset) at that UTC time. The reason why But more fundamentally, |
I'm assuming this is addressed by ZonedDateTime? Closing. |
I've been reading throughout the docs and the issues in this repo to figure out how to use
Temporal
, but I haven't found an answer to this. My apologies in advance if I missed an obvious point.The scenario I have in mind is I want to save the timestamp of an event in my database and store it as an unix (absolute?) timestamp so I can later display it in any timezone I prefer simply providing the expected timezone. However I couldn't find a straightforward way of doing that.
I tried:
but the returned string has not been converted to the right time. I'm not really clear on the meaning of "absolute", if we have to pass a timezone to the conversion... 🤔 Doesn't a
Temporal.Absolute
represent aUTC
time?Now, this seems to work in converting the string to the right UTC time:
however I wonder how I would convert a
Temporal.DateTime
instance into a UTC value sincethey both error out with
From the docs
toString
should return an ISO string (i.e. one that includes date, time and timezone) andAbsolut.from
should accept any "thing" (which I assume include aDateTime
); is that not correct?As a side note, if I may suggest, I would expect in the
Temporal
API a straightforward way to (immutably) convert timezone of aTemporal.DateTime
instance, something likeThe text was updated successfully, but these errors were encountered: