Javascript – Resolving Moment.js Deprecation Warning in Angular App

angulardatejavascriptmomentjs

I am getting an warning for the following code, using moment.js, in my Angular app:

moment(value).add(6, 'hours').format("MM/DD/YYYY");

The warning/error printing to the console is:

moment.js:293 Deprecation warning: value provided is not in a
recognized RFC2822 or ISO format. moment construction falls back to js
Date(), which is not reliable across all browsers and versions. Non
RFC2822/ISO date formats are discouraged and will be removed in an
upcoming major release. Please refer to
http://momentjs.com/guides/#/warnings/js-date/ for more info.
Arguments: [0] _isAMomentObject: true, _isUTC: false, _useUTC: false,
_l: undefined, _i: Apr 10, 2007, 10:00:00 PM, _f: undefined, _strict: undefined, _locale: [object Object]

I have looked at the documentation page linked in the warning, but it's still unclear to me what I need to change to get rid of the deprecation warning. I tried, for instance, adding an empty array as a second argument:

moment(value, []).add(6, 'hours').format("MM/DD/YYYY");

…but while that gets rids of the error, I get "invalid date" printed in my view, instead of the actual date. How do I need to adjust the syntax here to get rid of the warning?

UPDATE: The value being provided is a UTC value that has been transformed using the Angular date pipe. So I am passing through two pipes: first the Angular date pipe, and then this custom pipe using moment. the full pipe code looks like this:

import { Pipe, PipeTransform } from '@angular/core';
const moment = require('moment');

@Pipe({name: 'timeZoneSync'})
export class TimeZoneSyncPipe implements PipeTransform {

    constructor() { }

    transform(value) {
        if (value) {
            return moment(value).add(6, 'hours').format("MM/DD/YYYY");
        }
    }
}

And in my view I am using the two pipes like this:

  <input class="app-input" [ngModel]="client.dob | timeZoneSync | date:'medium'"
                                (ngModelChange)="client.dob=$event" name="inputField" type="text" /> 

Best Answer

You have a link in your error message. It indirectly leads you to this: https://github.com/moment/moment/issues/1407

Quote:

moment construction using a non-iso string is deprecated. What this means is you can safely do

moment("2014-04-25T01:32:21.196Z"); // iso string, utc timezone

moment("2014-04-25T01:32:21.196+0600"); // iso string with timezone

moment("2014 04 25", "YYYY MM DD"); // string with format

but you can't do reliably (therefore its being deprecated)

moment("2014/04/25");

moment("Thu Apr 24 2014 12:32:21 GMT-0700 (PDT)");

moment("some random string that looks like date");

Basically, whatever provides the value to your TimeZoneSyncPipe is not doing a good job making sure that the date is in the ISO or RFC2822 format.

More specifically

'mediumDate' argument is equivalent to 'MMM d, y' (e.g. Jun 15, 2015) which is not even close to ISO.

FIX

Try using something like "client.dob | date:'yyyy-MM-ddTHH:mm:ss.sssZ' | timeZoneSync"

Forest behind the trees

@jonrsharpe is very right! My answer explains the "why" you see the error. But Jon asks a better question. Why keep translating date -> string -> date!?

Example

const parsedDate = moment("1981-09-24T05:00:00.000Z");
console.log(parsedDate.format("YYYY/MM/DD"));

Plunkr

enter image description here

Related Topic