-
Notifications
You must be signed in to change notification settings - Fork 162
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Better conversion between legacy Date and Temporal #515
Comments
I think the answer up until now has been "If you have it in some custom format, write a parser specifically for that format." However, I agree that it's very easy and obvious to do the wrong thing here with legacy Date as a shortcut, and fall into the time zone trap that you mentioned. So I think some sort of answer is needed. |
For this use case: The JS spec doesn't ensure that the legacy Date parser will make that work. I think it'd be better to use For conversion to from legacy Dates in general: I'd be up for adding this if people feel like it's useful. However, based on previous discussions with @pdunkel , I thought we'd leave this for the cookbook entry. |
I was thinking more about the Temporal.ZonedAbsolute data model from #569. Legacy Date is the same data model as Temporal.ZonedAbsolute, with two exceptions:
I wonder if some of @justingrant's use cases would be covered if we simply added first-class conversion methods between legacy Date and Temporal.
|
This list omits the most important difference: there's no support with Date for doing operations in time zones other than the environment's timezone or UTC. The most obvious example of this is when a server app needs to parse, display, and/or manipulate data in the client's time zone. So if you deal with calendar data from multiple timezones (like that server app case) it becomes really challenging to use The result is that most developers end up doing the same thing with legacy Date that we currently have to do with Temporal: build userland data structures that track both the instant and the timezone.
This solves part of the problem (easily getting TZ data into legacy Date) but what about the rest? How can I easily format values in that timezone? How can I add/subtract/diff? How can I ensure DST is handled according to that timezone's rules? And so on. I'd still have to round-trip back to Temporal to do anything interesting... and I still need to manually maintain my {Date, TimeZone} data structure because many method calls requires (or should require, for DST safety!) the The big win would be persistence of the timezone and instant together. This is particularly useful because most of the time the "desired timezone" of date/time data is known when the data enters the app, and never changes. True, parsing and emitting a UTC-serialized version of the date/time is important, but honestly that's less of a "change time zone" use-case (because it's not persistent) and more like an alternate display format like toString vs. toLocalizedString vs toISOString.
Regardless of the ZonedAbsolute decision, I think it'd be good to have conversion methods to help with legacy code interop. But the Temporal API is soooooo much better:
So for "instants that know their timezone" use-cases developers would choose between an ancient, awkward API or a modern, ergonomic API that invites DST bugs. Seems like a non-ideal choice. I'm not against extending legacy And it still doesn't address the ergonomics and feature gaps with legacy Date, so I don't think it's a good alternative to ZonedAbsolute. BTW, if we do have an interop API I'd suggest that it should only offer two types: |
I was talking solely about the data model. ZonedAbsolute and legacy Date have the same data model, with the two exceptions I listed. However, there is a large chunk of functionality that Temporal types can do that legacy Date can't do, like arithmetic and proper time zone conversions.
Let's look at your use cases one by one.
Formatting is supported by legacy Date. You can already pass a time zone argument: new Date().toLocaleString(undefined, {
timeZone: "Asia/Singapore",
timeZoneName: "long"
});
// "5/19/2020, 10:31:38 AM Singapore Standard Time"
By design, you would go into Temporal for that, and the new methods would make it easier.
Let Temporal do that for you. If you need to add absolute time, go to Temporal.Absolute. If you need to add wall clock time, go to Temporal.DateTime.
Legacy Date already has a timezone slot. However, it is not configurable (it always defaults to your local time) and it is only an offset in minutes. Implicit in my suggestion would be to explore whether we could attach an IANA timezone to legacy Date that corresponds to the timezone offset. This wouldn't break the web. const date = new Date();
// Existing function: Returns 300 in America/Chicago during the summer
console.log(date.getTimezoneOffset());
// New function: Returns a Temporal.TimeZone for America/Chicago
console.log(date.getTimeZone());
// New function: Sets a time zone on an existing Date
date.setTimeZone("Asia/Singapore");
console.log(date.getTimezoneOffset()); I'm just giving this as a possible alternative to Temporal.ZonedAbsolute. Adding Temporal.ZonedAbsolute opens a whole can of worms that we've been avoiding for the two years that this proposal has been at Stage 2. We removed this type because of the challenges it posed with regard to type conversion, arithmetic, et cetera, instead opting for the cleaner Absolute and DateTime model. |
In general, Temporal doesn't have a minimal API, so I don't see it as out of the question to add something like this. This issue isn't the first time something had been raised. I'm not sure whether this is the kind of thing where a cookbook entry is enough. It's fine to ship the initial polyfill without this, but we need to conclude on whether we add this small feature before Stage 3; it would be part of the spec text and polyfill before then. Or, we may decide to omit it. |
@sffc - Oops, I misunderstood your proposal. I like it more now. :-) If legacy I'm less enthusiastic about easy conversions from legacy So, at least for Temporal's first release until Google and StackOverflow can build up a good library of "How to use Temporal" content, I think there may be some benefit in keeping the two worlds somewhat separate so that devs have to opt into using Temporal instead of just following a legacy FWIW, I don't think enhancing |
I don't think it is possible to change legacy Date's data model to include a timezone. I share the worry that, if we make it too easy to keep using legacy Date, people may not migrate properly. I agree that this is unrelated to whether we include a Temporal.ZonedTimestamp type. |
What's concretely left on this issue to discuss, now that LocalDateTime is definitely in, and nearing completion? As I understand it, the open question is whether to add two legacy Date methods: |
I have a preference to limit the conversion method to only
|
The existing pattern is that the presence or absence of "UTC" refers to how the |
I agree with only one conversion method to Absolute. Should it be called |
Meeting, Sept. 18: We agree on adding a method to legacy Date. It will be called |
This is in response to feedback that this conversion should be less verbose. No unit tests currently included because I found out that the test code doesn't import the shim but instead imports individual objects from lib/temporal.mjs, and I didn't see a quick way to fix that. Anyway, the method is tested in the cookbook already. Closes: #515
This is in response to feedback that this conversion should be less verbose. No unit tests currently included because I found out that the test code doesn't import the shim but instead imports individual objects from lib/temporal.mjs, and I didn't see a quick way to fix that. Anyway, the method is tested in the cookbook already. Closes: #515
This is in response to feedback that this conversion should be less verbose. No unit tests currently included because I found out that the test code doesn't import the shim but instead imports individual objects from lib/temporal.mjs, and I didn't see a quick way to fix that. Anyway, the method is tested in the cookbook already. Closes: #515
I was working on a test project where I am parsing a CSV file that has dates of the form: "1/22/20" to mean January 22, 2020. I do not advocate for using such strings for interop, but the reality is that they exist, and that the old Date constructor can sometimes parse them.
So, right now, I'm tempted to do ugly things like:
Really? That's unintuitive and prone to error, like how the Date constructor implicitly uses my local time zone, and I have to know to use that time zone when decoding, or else my code won't work in time zones east of UTC.
Why can't we add to the spec:
Keep the conversion methods on Date to keep the Temporal namespace tidy.
The text was updated successfully, but these errors were encountered: