Proposal-temporal: Develop a shim for the Temporal proposal, exposing a Moment-like interface

Created on 22 Dec 2018  路  24Comments  路  Source: tc39/proposal-temporal

This proposal subsumes most of the functionality of Moment.js, but there's a ton of code out there using moment, and it will take a long time to upgrade to the Temporal API.

To make the transition easier, while reducing download size, it'd be great to have an implementation of most of the moment API in terms of Temporal, if this is possible. I think it's not to early now to start on this work, to validate the design of this proposal, and to have something ready as soon as Temporal ships.

nice to have

Most helpful comment

@jhpratt I think so. It would likely achieve faster widespread adoption compared to recommending end-developers modify their code.

All 24 comments

Would it be feasible to fork moment.js and incrementally replace methods? I've never taken a look at the source, but that would certainly guarantee compatibility.

@jhpratt I think so. It would likely achieve faster widespread adoption compared to recommending end-developers modify their code.

This isn't impossible - biggest thing is that Moment is mutable and this API is immutable - so you like end up having to make something immutable mutable which I think would result in some pretty awkward code.

I guess you would have a mutable interface which internally swaps out different Temporal instances when it needs to mutste itself?

i still think an interface using static-functions to input/output canonical ISOStrings is easier to spec and implement, and more inline with actual javascript use-cases.

most data (including dates/temporals) are primarily meant to be baton-passed in javascript to external, non-js-systems with [occasional] js-business-logic applied while in-transit. using string-based static-functions would save us the hassle of being coerced into error-prone revival/reserialization of dates at every transit-point in a workflow-process, just to do date-arithmetic.

That wouldn鈥檛 meet airbnb鈥檚 use cases, which require passing around a non-string validateable instance that contains all the disparate parts required to format it properly in multiple formats, where the formatting site is very disconnected from the creation site. Your suggestion would not be in line with our actual JavaScript UX workflow use cases.

wouldn't it be easier to store the ISOString and disparate-parts as easy-to-serialize (and json-schema-validatable) JSON-object rather than class-instance?

{
   "isostring": "2019-01-05T20:06:58.786Z",
   "timezoneOffset": "-03:00",
   "presentationFormat": "{{dayOfWeek}} {{month}} {{dd}} {{yyyy}} {{HH}}:{{MM}}:{{MM}} GMT-{{timezoneOffset}}",
   "locale": "Brazil"
}

No, not at all. A string, as well as a plain object, is not trivial to validate and ensure the user鈥檚 passing the correct thing (as opposed to something that kind of looks like the correct thing). It鈥檚 the some reason it鈥檚 common to use Array.isArray instead of checking the length and the numeric indexes.

its a tradeoff, which in my experience favors json-objects over class-instances in javascript-workflows.

a primary benefit of static-functions and json-objects is avoiding the operational-painpoint of maintaining up-to-date class-dependencies at every transit-point in the workflow-process.

You have to do that regardless - whether it鈥檚 explicit or not, you have a coupled dependency on a contract/interface/format/serialization/whatever.

you don't need any of those things with json-objects. just use baked-in JSON.parse/JSON.stringify, and design the workflow so that internal validation-checking isn't necessary/common.

contract/interface/format/etc are only needed at external-endpoints in the workflow-process (database, rest-api for external-clients, dom-inputs, etc). its easier to write uncoupled, custom/throwaway static-functions at each external-endpoint to do those jobs, than some coupled, monolithic beast to handle them all.

Yes, you do still need those things, because "JSON" only dictates the serialization format - not the structure of the resulting data, which is a dependency, whether it's implicit or explicit. In my experience, it's easier to write those things, but the ease of writing doesn't matter - because it's harder to read, understand, debug, and maintain those things.

Regardless, you certainly don't have to write your code following my experience, but it's not reasonable or friendly to attempt to erase the validity of these patterns for others. All use cases are valid.

Once the proposal is stable (which I think it almost is), and the polyfill is complete and up to date (which will happen in real-time), I'll give this a go. Maybe first just keep moment objects as they are and make it use the temporal stuff for it's own storage/handling. That way the moment object remain mutable, but use immutable underlying objects.

When it comes time to create this, it might make sense to simply create a shim that mimics the moment-timezone API. I think the moment-timezone API applies non-breaking additions to the moment API, so the moment-timezone API would be useful for both user groups.

Closing this since the polyfill has been successfully merged into the repository. Please feel free to reopen.

Now that I think about it, this issue was about a moment-like shim and not the polyfill itself. Reopening. @pipobscure is there any ongoing work on this?

Yes I鈥檝e go a colleague of mine to take it up.

@pipobscure do we know whats happening with this?

I was hoping that this would happen, but have not seen movement yet. I鈥檒l follow up, but it鈥檚 a significant piece of work.

This might be better to work on once the main polyfill and docs are all done.

From #557, consider also date-fns and luxon

I'm removing the "Stage 3" milestone and "Finalize polyfill" project, as I think this whole issue is a nice-to-have. From a practical perspective, an "updating from Moment" or "updating from Date and date-fns" practical guide may be more useful, but also isn't a Stage 3 or 4 requirement.

I have been taking a look intermittently at porting date-fns to use Temporal internally. Since date-fns operates on legacy Date there are two ways to do it: keep the API backwards compatible or not. Keeping the API backwards compatible means that date-fns can accept Temporal types but only return legacy Date. It's useful for shaking out bugs in the Temporal polyfill by running the ported code against the date-fns test suite, but it's got the disadvantage that you have to convert everything back into legacy Date in every function, meaning that you lose many of the benefits of Temporal because, say if you do addBusinessDays(someTemporalDate, 8) then you still have to pick an arbitrary time of day to convert the Temporal.Date result back to legacy Date. So it wouldn't really be useful for porting programs into the Temporal future.

This is all I plan to do for date-fns at the moment, but I think it illustrates how such a port would proceed: https://github.com/ptomato/temporal-fns/commits/port-to-temporal
I may return to a moment port later on.

Was this page helpful?
0 / 5 - 0 ratings