Proposal-temporal: how is this new proposal easier-to-use than existing Date?

Created on 3 Aug 2018  Â·  24Comments  Â·  Source: tc39/proposal-temporal

the README.md seems short on design-patterns to convince me its superior to use than Date. couldn't we just extend Date with some static functions to to fill in missing features (like date-arithmetic and timezone conversions)?

Most helpful comment

@kaizhu256 I suggest you watch this JSConfEU talk by @mj1856: https://www.youtube.com/watch?v=aVuor-VAWTI

It covers a lot of the current problems with the Date object, including the one that has bitten me the most often. I want to be able to have an object that represents a date without any time component — this is simply not possible with the current Date. If you try to represent just a day with Date and add/remove days, sooner or later you will be bitten by a time zone / daylight saving bug.

All 24 comments

The README links to this article which lists the motivations in more detail (including why the current Date object cannot be 'fixed'):
https://maggiepint.com/2017/04/09/fixing-javascript-date-getting-started/

thx for reference and context. the motivation section of the README should be revised. otherwise people like me (who are mostly happy with Date) are like what? why do we need this?

  • can you elaborate on the mutability problem? could it be more easily resolved with smaller-scope static-functions that return a new Date-object?

  • could parsing be resolve more easily by extending Date constructor with a config-parameter, or a new parse2/createDateFrom static-functions?

Like every other time you’ve raised this question on other proposals, if you’re happy with existing features, simply don’t use the new ones. The rest of the internet is not happy with Date, which is why moment.js is the defacto standard for working with dates in JS.

can you maybe provide a/b code-examples showing how these new Temporals are easier-to-use than Date?

the industry use-cases for javascript temporals (primarily JSON serialization/reviving datetime between browser <-> server <-> database) are very different from industry use-cases for temporals in other languages (subclassing, server business-logic, etc.)

Your claim of "primarily" is both not one I agree with, and one you've continually made. Dates are often used in websites for far more than simple JSON serialization (for which an ISO string is more than sufficient, and both Date and Temporal can provide).

i still would like to see a/b code examples in a javascript-context (as opposed to java/.net/python/etc contexts), where this proposal is easier-to-use than Date.

Sure, off the top of my head, here's one:
Let's say I want to represent a date - not a time. I might do new Date(year, month, day, 0, 0, 0). However, let's say I'm representing October 20th, 2013, and I'm in Brazil. Let's say I'm a datepicker on Twitter Ads, scheduling tweets, representing things as a "date" and separately, a time, and someone schedules a tweet in Brazil for October 20th, 2013. Except, oops! Daylight savings in Brazil means that the hour from [midnight to 1AM) doesn't exist - and oops, I've got a bug!

Let's say I have Temporal available. I do new CivilDate(year, month, day). No bug ever manifests.

This legitimately happened to me while I was working as a Twitter Ads engineer on their tweet scheduler. It's a real bug, easily made, caused by Date being a massive footgun for tons of reasons. Temporal solves these.

ah, i think i see the problem.
i set my macbook to sao paolo, brazil timezone, and entered your new Date(2013, 9, 20, 0, 0, 0) example in nodejs/chrome/firefox/safari. your off-by-one date-bug did manifest in safari, but the other implementations handled it correctly.

could we just spec out Date-constructor behavior to follow that of nodejs/chrome/firefox (as opposed to safari) to fix this footgun?

// nodejs:
aa = new Date(2013, 9, 20, 0, 0, 0);
console.log(aa.toString());
console.log(JSON.stringify(aa));
// Sun Oct 20 2013 01:00:00 GMT-0200 (-02)
// "2013-10-20T03:00:00.000Z"

// chrome:
aa = new Date(2013, 9, 20, 0, 0, 0);
console.log(aa.toString());
console.log(JSON.stringify(aa));
// Sun Oct 20 2013 01:00:00 GMT-0200 (Brasilia Summer Time)
// VM252:3 "2013-10-20T03:00:00.000Z"

// firefox:
aa = new Date(2013, 9, 20, 0, 0, 0);
console.log(aa.toString());
console.log(JSON.stringify(aa));
// Sun Oct 20 2013 01:00:00 GMT-0200 (-02) debugger eval code:2:1
// "2013-10-20T03:00:00.000Z"

// safari:
aa = new Date(2013, 9, 20, 0, 0, 0);
console.log(aa.toString());
console.log(JSON.stringify(aa));
// [Log] Sat Oct 19 2013 23:00:00 GMT-0300 (-03)
// [Log] "2013-10-20T02:00:00.000Z" - off-by-one date-bug

You're checking browser versions in 2018; what about the latest version of everything in 2013?

Regardless, the issue is caused by having a primitive that represents a date and a time, when what i needed was a specific day, unzoned. Temporal provides that.

@kaizhu256 I suggest you watch this JSConfEU talk by @mj1856: https://www.youtube.com/watch?v=aVuor-VAWTI

It covers a lot of the current problems with the Date object, including the one that has bitten me the most often. I want to be able to have an object that represents a date without any time component — this is simply not possible with the current Date. If you try to represent just a day with Date and add/remove days, sooner or later you will be bitten by a time zone / daylight saving bug.

for a/b code-examples, i think utc/zulu-based Date is good-enough equivalent for CiviDate:

// a/b example for Date:
date = new Date('2013-10-20T00:00:00Z');
year = date.getUTCFullYear();   // 2013
month = date.getUTCMonth() + 1; // 10
day = date.getUTCDate();        // 20


// a/b example for Temporal CivilDate:
date = new CivilDate(2013, 10, 20);
year = date.year;   // 2013
month = date.month; // 10
day = date.day;     // 20

Your reply was 3 minutes after my comment, so I'm going to assume you didn't watch the video before trying to rebut it.

@kaizhu256 those new types are needed, and useful. For example, having a time-less date (e.g. coming from a date picker) is a common use case. If you have an appropriate data type, it signalizes the intent better. Not sure why JS (as opposed to e.g. Java) would not benefit from introduction of these new classes.

yes, @ljharb's https://github.com/tc39/proposal-temporal/issues/78#issuecomment-412254068, explained a valid use-case.

but looking at this proposal, the only real functionality for CivilDate seems to be date-only arithmetic. isn't it a bit overkill to have a class simply for that? or would it be more convenient for javascript integration-development to have a static-function that accepts JSON-friendly date-string for doing date-only arithmetic?

No, in no way is a static function more convenient than a class for something that needs to be passed around, identified, be immutable, but also be easily transformed into additional things via instance methods.

This issue should be closed.

canonical date-strings, e.g. '2018.08.25' are

  • easy to pass around
  • easily identified with regexp (/^\d\d\d\d.\d\d.\d\d$/)
  • immutable
  • sortable
  • easily transformed into additional things using simple string-methods (why complicate that with instance-methods)?

Nothing is easily identified with a regex, and anything that's primarily string-based is a huge code smell - there's no benefit to adding more stringly typed APIs to the language.

  • smell is a subjective term
  • if you were to look at this from the all-important integration-perspective (where majority of javascript-development-effort is spent), and which deals primarily with JSON-serializable data, e.g. '{"date":"2018.08.25","time":"12:59:00"}', CivilDate has no better identifiability than a canonical date-string

You continue to make this claim, but a) this is not all-important, b) JS does not deal primarily with JSON-serializable data - if anything, it deals primarily with functions, which are not JSON-serializable.

Why are you so determined to represent dates as strings? My comment on issue #82 digs into why that's not a great idea. It's also completely opposed to the way pretty much every other programming language handles dates.

In addition to "everything is a string" being a poor API, it also has potential performance impacts. Every single operation on a date string would need to:

  1. Validate that the string format is correct.
  2. Parse the date string into component parts.
  3. Convert each part into a number.
  4. Validate that all the numbers work together as a valid date.
  5. Perform the operation.
  6. Re-convert the numbers back into strings in order to return a final string.

Sequential operations on a date (e.g. adding days in a loop) would go through all those steps every time, which is a waste of processing. It's far better to parse a string into a domain-specific object _once_, perform a series of operations with the right data types, then convert back into a string _once_ at the end.

this emphasis on functions is honestly new to me ^^;;; my experience in industry is that most of the significant javascript-issues that required time to debug-and-fix were data-related ones, like mis-serialized/mis-reconstructed JSON-data during end-to-end communication between client <-> server. functions were mostly tools to achieve some means, e.g. manipulating JSON-data, before/after end-to-end communications, or am i missing something?

@gilmoreorless, i did do a performance analysis @ https://github.com/tc39/proposal-temporal/issues/53#issuecomment-345911380

tldr, javascript's Date constructor can parse around ~2million datetime-strings per second. so i don't think the performance-hit from parsing-strings for a static-function Date.datePlus is going to be that significant, compared to CivilDate.prototype.plus

Regardless of the raw benchmark numbers in one engine, it's still a conceptually less efficient way to perform a series of operations.

my experience in industry is that most of the significant javascript-issues that required time to debug-and-fix were data-related ones, like mis-serialized/mis-reconstructed JSON-data during end-to-end communication between client <-> server.

My experience in industry is that most of the significant JS issues that required time to debug and fix were flaws in logic calculations. In the case of dates, they often stemmed from not having a proper way to represent either abstract dates/times, or dates/times in a different time zone.

This constant focus on serialisation as the only thing that matters is a red herring, and is not at all what the temporal proposal is trying to fix/achieve.

closing this issue per request, and continuing further discussion on the more relevant issue https://github.com/tc39/proposal-temporal/issues/82

Was this page helpful?
0 / 5 - 0 ratings

Related issues

littledan picture littledan  Â·  4Comments

justingrant picture justingrant  Â·  4Comments

Ms2ger picture Ms2ger  Â·  6Comments

felixfbecker picture felixfbecker  Â·  6Comments

marikaner picture marikaner  Â·  3Comments