Consider date formatting

kai zhu kaizhu256 at gmail.com
Thu Sep 21 20:23:38 UTC 2017


going to rant about why existing date builtins are more than adequate, and that over-engineering is the cause of most date-issues (and justify with working vanilla js code).

moment.js is over-engineering and unnecessary.  date manipulation is not that hard using vanilla javascript, if you follow the best-practice of representing it internally throughout your application as a standard utc-iso-string (e.g. "2017-09-21T16:57:06.781Z”).  keeping the date represented as a string-by-default saves you the hassle of doing needless custom-serializations when writing it to json or as a dom-element attribute (not to mention making debugging easier by having human-readable values). it is also sort / comparison-operator friendly as well.

in fact, if you enforce keeping the date represented internally as a string, there are only 3 common-cases that you need to worry about dealing with date serialization/deserialization:
1. date-arithmetic (trivial to do with 3-lines of vanilla javascript code)
2. writing date to the ui and persistent-storage
3. reading date from ui and persistent-storage



```javascript

/*jslint node: true, regexp: true */
'use strict';

function nop() {
/*
 * this function will do nothing
 */
    return;
}

// 1. date-arithmetic
function dateArithmeticAdd(dateIsoString, milliseconds) {
/*
 * this function will return a new dateIsoString with the given (positive or negative) milliseconds added to it
 */
    console.error('dateArithmeticAdd(' + JSON.stringify(dateIsoString) + ',' +
        JSON.stringify(milliseconds) + ')');
    // return serialized dateIsoString
    return new Date(
        // de-serialize dateIsoString and add milliseconds to it
        new Date(dateIsoString).getTime() + milliseconds
    ).toISOString();
}

// 2. writing date to the ui and persistent-storage
function dateWriteToUi(dateIsoString, options) {
/*
 * this function will return the date in a string-format suitable for ui-presentation
 * you can edit this function to suit your application needs
 */
    console.error('dateWriteToUi(' + JSON.stringify(dateIsoString) + ',' +
        JSON.stringify(options) + ')');
    var dateObject;
    // de-serialize dateIsoString
    dateObject = new Date(dateIsoString);
    // present date in local-time instead of utc-time
    if (!options.isUtc) {
        dateObject = new Date(dateObject.getTime() -
            dateObject.getTimezoneOffset() * 60 * 1000);
    }
    dateObject.toISOString().replace((/(\d\d\d\d)-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)/), function (
        match0,
        YYYY,
        MM,
        DD,
        hh,
        mm,
        ss
    ) {
        // jslint-hack
        nop(match0);
        dateObject.YYYY = YYYY;
        dateObject.MM = MM;
        dateObject.DD = DD;
        dateObject.hh = hh;
        dateObject.mm = mm;
        dateObject.ss = ss;
    });
    switch (options.type) {
    case 'china':
        return dateObject.YYYY + '-' +
            dateObject.MM + '-' +
            dateObject.DD + ' ' +
            dateObject.hh + ':' +
            dateObject.mm + ':' +
            dateObject.ss;
    case 'germany':
        return dateObject.DD + '.' +
            dateObject.MM + '.' +
            dateObject.YYYY + ' ' +
            dateObject.hh + ':' +
            dateObject.mm + ':' +
            dateObject.ss;
    case 'usa':
        return dateObject.MM + '/' +
            dateObject.DD + '/' +
            dateObject.YYYY + ' ' +
            dateObject.hh + ':' +
            dateObject.mm + ':' +
            dateObject.ss;
    // case 'foo':
    // ...
    // represent in default locale setting
    default:
        return dateObject.toString();
    }
}

// 3. reading date from ui and persistent-storage
function dateReadFromUi(inputText, options) {
/*
 * this function will parse inputText and return an appropriate dateIsoString
 * you can edit this function to suit your application needs
 */
    console.error('dateReadFromUi(' + JSON.stringify(inputText) + ',' +
        JSON.stringify(options) + ')');
    var dateObject;
    // use default Date parser
    dateObject = new Date(inputText);
    switch (options.type) {
    case 'china':
        inputText.replace((/(\d\d\d\d).(\d\d).(\d\d).(\d\d):(\d\d):(\d\d)/), function (
            match0,
            YYYY,
            MM,
            DD,
            hh,
            mm,
            ss
        ) {
            // jslint-hack
            nop(match0);
            dateObject = new Date(YYYY + '-' + MM + '-' + DD + 'T' + hh + ':' + mm + ':' + ss);
        });
        break;
    case 'germany':
        inputText.replace((/(\d\d).(\d\d).(\d\d\d\d).(\d\d):(\d\d):(\d\d)/), function (
            match0,
            DD,
            MM,
            YYYY,
            hh,
            mm,
            ss
        ) {
            // jslint-hack
            nop(match0);
            dateObject = new Date(YYYY + '-' + MM + '-' + DD + 'T' + hh + ':' + mm + ':' + ss);
        });
        break;
    case 'usa':
        inputText.replace((/(\d\d).(\d\d).(\d\d\d\d).(\d\d):(\d\d):(\d\d)/), function (
            match0,
            MM,
            DD,
            YYYY,
            hh,
            mm,
            ss
        ) {
            // jslint-hack
            nop(match0);
            dateObject = new Date(YYYY + '-' + MM + '-' + DD + 'T' + hh + ':' + mm + ':' + ss);
        });
        break;
    // case 'foo':
    // ...
    }
    // inputText was in utc-time
    if (options.isUtc) {
        dateObject = new Date(dateObject.getTime() -
            dateObject.getTimezoneOffset() * 60 * 1000);
    }
    return dateObject.toISOString();
}

// 1. date-arithmetic
console.log('\n1. date-arithmetic');
console.log(dateArithmeticAdd('2000-01-30T00:00:00Z', 24 * 60 * 60 * 1000));
console.log(dateArithmeticAdd('2000-01-30T00:00:00Z', -24 * 60 * 60 * 1000));

// 2. writing date to the ui and persistent-storage
console.log('\n2. writing date to the ui and persistent-storage');
console.log(dateWriteToUi('2000-01-30T00:00:00Z', { type: 'china' }));
console.log(dateWriteToUi('2000-01-30T00:00:00Z', { type: 'china', isUtc: true }));
console.log(dateWriteToUi('2000-01-30T00:00:00Z', { type: 'germany' }));
console.log(dateWriteToUi('2000-01-30T00:00:00Z', { type: 'germany', isUtc: true }));
console.log(dateWriteToUi('2000-01-30T00:00:00Z', { type: 'usa' }));
console.log(dateWriteToUi('2000-01-30T00:00:00Z', { type: 'usa', isUtc: true }));

// 3. reading date from ui and persistent-storage
console.log('\n3. reading date from ui and persistent-storage');
console.log(dateReadFromUi('2000-01-30 00:00:00', { type: 'china' }));
console.log(dateReadFromUi('2000-01-30 00:00:00', { type: 'china', isUtc: true }));
console.log(dateReadFromUi('30.01.2000 00:00:00', { type: 'germany' }));
console.log(dateReadFromUi('30.01.2000 00:00:00', { type: 'germany', isUtc: true }));
console.log(dateReadFromUi('01/30/2000 00:00:00', { type: 'usa' }));
console.log(dateReadFromUi('01/30/2000 00:00:00', { type: 'usa', isUtc: true }));

```



> On Sep 21, 2017, at 9:04 PM, Maggie Pint <maggiepint at gmail.com> wrote:
> 
> Substantial work is being put into a date standard library and formatting currently. There is a stage 1 proposal to rework the date library here: https://github.com/tc39/proposal-temporal <https://github.com/tc39/proposal-temporal>. I have a shim for that proposal started here: https://github.com/maggiepint/temporal-shim <https://github.com/maggiepint/temporal-shim>. I will probably seek stage two for this proposal in November of January. It is quite large, and the shim and spec text take a long time to write, so it can't be moved quickly.
> 
> My plan for formatting is to continue to rely on ECMA 402 as we do today. That team has done a wonderful job in the space, and I'm not entirely sure how i could one-up them at this point.
> 
> As far as why that proposal isn't just the Moment.js library - quite a few reasons. I maintain the Moment.js library with a couple other people, and the moment team actually created the new temporal proposal based on the knowledge of where the library falls down, and where other libraries have succeeded. Some points of difference from moment:
> Proposal has all immutable data structures
> Proposal provides a way to represent a date only, time only, and date time without associated time zone
> APIs in several corners have 'safety' features that Moment doesn't have to prevent developer error - for instance the user must specify a time zone on a zoned object
> 
> Even after this proposal goes though, I assume there will still be libraries, simply because everyone has different preferences. That said, one should no longer HAVE to bring in a date library for anything as they do today.
> 
> On Thu, Sep 21, 2017 at 6:41 AM, Matthew Robb <matthewwrobb at gmail.com <mailto:matthewwrobb at gmail.com>> wrote:
> I just mean to say that it makes more sense as a userland lib outside of the context of browsers.
> 
> 
> - Matthew Robb
> 
> On Thu, Sep 21, 2017 at 9:35 AM, Michael Kriegel <michael.kriegel at actifsource.com <mailto:michael.kriegel at actifsource.com>> wrote:
> Actually I used it in node.js today - where using/deploying another lib is less "painful" - agreed. Still I don't think it is browser scope only...
> 
> On 21.09.2017 14:59, Matthew Robb wrote:
>> +1 this sentiment
>> 
>> Raise your hand if you are using Moment.js in projects today?
>> Raise your hand if you ship the library wholesale?
>> Raise your hand if you use webpack tok strip out the locale files which add sig. heft to your bundle?
>> 
>> Moment.js should be standardized...
>> 
>> HOWEVER: The language spec is likely the wrong place. This should probably be a browser spec as the biggest motivation is going to be localization which I find obnoxious to include in an often shipped defacto lib.
>> 
>> 
>> - Matthew Robb
>> 
>> On Thu, Sep 21, 2017 at 3:17 AM, Michael Kriegel <michael.kriegel at actifsource.com <mailto:michael.kriegel at actifsource.com>> wrote:
>> Quoting my initial posting:
>> 
>> > I know there are libraries for that, but I think it is fundamental enough to put it into the standard instead.
>> 
>> Isn't it legitimate to ask for a defacto-standard to become a real standard...
>> 
>> On 21.09.2017 09:13, Bob Myers wrote:
>>> There are third-party libraries which are so widely-used as to be defacto standards.
>>> Bob
>>> 
>>> On Thu, Sep 21, 2017 at 12:11 PM, Michael Kriegel <michael.kriegel at actifsource.com <mailto:michael.kriegel at actifsource.com>> wrote:
>>> I would like to suggest to take up date formatting into the standard. Either as optional format parameter on Date.prototype.toDateString() or as a separate method Date.prototype.toFormattedDateString(format).
>>> 
>>> format should be a string in the form as specified in https://tc39.github.io/ecma262/#sec-date-time-string-format <https://tc39.github.io/ecma262/#sec-date-time-string-format>
>>> 
>>> I know there are libraries for that, but I think it is fundamental enough to put it into the standard instead.
>>> 
>>> I hope this was not already discussed before and I just did not find the thread.
>>> 
>>> -- 
>>> Michael Kriegel • Head of R&D • Actifsource AG • Haldenstrasse 1 • CH-6340 Baar • www.actifsource.com <http://www.actifsource.com/> • +41 56 250 40 02 <tel:+41%2056%20250%2040%2002>
>>> 
>>> 
>>> _______________________________________________
>>> es-discuss mailing list
>>> es-discuss at mozilla.org <mailto:es-discuss at mozilla.org>
>>> https://mail.mozilla.org/listinfo/es-discuss <https://mail.mozilla.org/listinfo/es-discuss>
>>> 
>> 
>> -- 
>> Michael Kriegel • Head of R&D • Actifsource AG • Haldenstrasse 1 • CH-6340 Baar • www.actifsource.com <http://www.actifsource.com/> • +41 56 250 40 02 <tel:+41%2056%20250%2040%2002>
>> _______________________________________________
>> es-discuss mailing list
>> es-discuss at mozilla.org <mailto:es-discuss at mozilla.org>
>> https://mail.mozilla.org/listinfo/es-discuss <https://mail.mozilla.org/listinfo/es-discuss>
>> 
>> 
> 
> -- 
> Michael Kriegel • Head of R&D • Actifsource AG • Haldenstrasse 1 • CH-6340 Baar • www.actifsource.com <http://www.actifsource.com/> • +41 56 250 40 02 <tel:+41%2056%20250%2040%2002>
> 
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org <mailto:es-discuss at mozilla.org>
> https://mail.mozilla.org/listinfo/es-discuss <https://mail.mozilla.org/listinfo/es-discuss>
> 
> 
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20170922/2b944861/attachment-0001.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: PastedGraphic-8.png
Type: image/png
Size: 761788 bytes
Desc: not available
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20170922/2b944861/attachment-0001.png>


More information about the es-discuss mailing list