Angular2 date pipe does not work in IE 11 and edge 13/14

30,442

Solution 1

UPDATE - The Angular issue that causes this issue is resolved in Angular 5. If you can, I would recommend using that to avoid this problem.

If you are still using Angular 4 or older - as a workaround, I created a pipe to use the moment formatter instead of the Angular built-in one:

import { Pipe, PipeTransform } from '@angular/core';
import * as moment from 'moment';

@Pipe({
    name: 'datex'
})

export class DatexPipe implements PipeTransform {
    transform(value: any, format: string = ""): string {
        // Try and parse the passed value.
        var momentDate = moment(value);

        // If moment didn't understand the value, return it unformatted.
        if (!momentDate.isValid()) return value;

        // Otherwise, return the date formatted as requested.
        return momentDate.format(format);
    }
}

Which can then be used:

{{exampleDate | datex:'DD/MM/YYYY HH:mm:ss'}}

The date you pass in should be something which moment can parse (see the relevant moment documentation) and the format string is a moment, not angular, date formatting string, as documented here.

I've tested this in IE11, Chrome and Firefox and it behaves consistently.

You'll need to ensure moment is added to your package.json as a dependency, e.g.:

{
  "name": "demo",
  "version": "0.0.1",
  // snip
  "dependencies": {
    // snip
    "moment": "^2.15.1",
    // snip
  },
  "devDependencies": {
    //snip
  }
}

... and ensure your systemjs.config.js is updated so it can locate moment:

map: { 
  'moment': 'npm:moment' 
} 
packages: { 
  moment: { main: './moment.js', defaultExtension: 'js' } 
}

Solution 2

From Angular2 DatePipe API Documentation.

"this pipe uses the Internationalization API. Therefore it is only reliable in Chrome and Opera browsers.

Solution 3

If you are okay with showing AM/PM instead of 24 hour time, another valid workaround is to break the formatting into two, and use shortTime or mediumTime for displaying the time portion:

{{dto.LastExecution | date:'yyyy-MM-dd'}} {{dto.LastExecution | date:'shortTime'}}

This should work in all major browsers, including IE and Edge.

Solution 4

Regarding the answer from @mark-hughes above, from the moment API documentation:

date_expression | date[:format]

expression is a date object or a number (milliseconds since UTC epoch) or an ISO string

Reference

So the value should be any type, and you can use moment().isValid() to check the value type

@Pipe({name: 'datex'})
export class DatexPipe implements PipeTransform {
    transform(value: any, format: string = ""): string {
       return moment(value).isValid()? moment(value).format(format) : value; 
    }
}

Solution 5

The below solution works fine in for IE11 and chrome. No need to create custom pipes.

 {{dto.createdTimeLocal | date:'dd MMM yyyy'}} {{dto.createdTimeLocal | date:'shortTime'}}
Share:
30,442
Anthony Brenelière
Author by

Anthony Brenelière

C# C++ Angular Typescript Python Azure

Updated on July 09, 2022

Comments

  • Anthony Brenelière
    Anthony Brenelière almost 2 years

    I'm using Angular 2.0 final, and I have an incorrect format of dates when I add hours and minutes in the format string:

    In the template of the component, I have:

    <th id="lastexecution">{{dto.LastExecution | date:'yyyy-MM-dd HH:mm:ss'}}</th>
    

    The output date in IE 11 is:

    2016-09-27 15:00:9/27/2016 3:53:46 PM:9/27/2016 3:53:46 PM
    

    With {{dto.LastExecution | date:'yyyy-MM-dd'}}

    The output date in IE 11 is correct:

    2016-09-27
    

    Here is the components version I use in the package.json:

    {
      "name": "ima_sentinel",
      "version": "1.0.0",
      "description": "QuickStart package.json from the documentation, supplemented with testing support",
      "scripts": {
        "start": "tsc && concurrently \"tsc -w\" \"lite-server\" ",
        "docker-build": "docker build -t ima_sentinel .",
        "docker": "npm run docker-build && docker run -it --rm -p 3000:3000 -p 3001:3001 ima_sentinel",
        "pree2e": "npm run webdriver:update",
        "e2e": "tsc && concurrently \"http-server -s\" \"protractor protractor.config.js\" --kill-others --success first",
        "lint": "tslint ./app/**/*.ts -t verbose",
        "lite": "lite-server",
        "postinstall": "typings install",
        "test": "tsc && concurrently \"tsc -w\" \"karma start karma.conf.js\"",
        "test-once": "tsc && karma start karma.conf.js --single-run",
        "tsc": "tsc",
        "tsc:w": "tsc -w",
        "typings": "typings",
        "webdriver:update": "webdriver-manager update"
      },
      "keywords": [],
      "author": "",
      "license": "ISC",
      "dependencies": {
        "@angular/common": "2.0.0",
        "@angular/compiler": "2.0.0",
        "@angular/core": "2.0.0",
        "@angular/forms": "2.0.0",
        "@angular/http": "2.0.0",
        "@angular/platform-browser": "2.0.0",
        "@angular/platform-browser-dynamic": "2.0.0",
        "@angular/router": "3.0.0",
        "@angular/upgrade": "2.0.0",
        "angular2-in-memory-web-api": "0.0.20",
        "bootstrap": "^3.3.6",
        "core-js": "^2.4.1",
        "linqts": "^1.6.0",
        "reflect-metadata": "^0.1.3",
        "rxjs": "5.0.0-beta.12",
        "signalr": "^2.2.1",
        "systemjs": "0.19.27",
        "typescript-collections": "^1.1.9",
        "zone.js": "^0.6.23"
      },
      "devDependencies": {
        "concurrently": "^2.2.0",
        "lite-server": "^2.2.0",
        "typescript": "^2.0.2",
        "typings": "^1.0.4",
        "canonical-path": "0.0.2",
        "http-server": "^0.9.0",
        "tslint": "^3.7.4",
        "lodash": "^4.11.1",
        "jasmine-core": "~2.4.1",
        "karma": "^1.2.0",
        "karma-chrome-launcher": "^0.2.3",
        "karma-cli": "^0.1.2",
        "karma-htmlfile-reporter": "^0.2.2",
        "karma-jasmine": "^0.3.8",
        "protractor": "^3.3.0",
        "rimraf": "^2.5.2"
      },
      "repository": {}
    }
    
  • Anthony Brenelière
    Anthony Brenelière over 7 years
    It results with the following error when executing the project: XHR error (404 Not Found) loading localhost:3000/moment. I have no idea why it is looking for the the library at this place whereas it is located in node_modules/moment. I have no error at compile time.
  • Anthony Brenelière
    Anthony Brenelière over 7 years
    Ok system.config.js was not updated by the package install. I had to add: map: { 'moment': 'npm:moment' } packages: { moment: { main: './moment.js', defaultExtension: 'js' } } It works pretty well thank you!!!
  • Léon Pelletier
    Léon Pelletier over 7 years
    It just gives another form of garbage as a result. 01/th/y for MM/dd/y.
  • Mark Hughes
    Mark Hughes over 7 years
    @léon-pelletier I'm not sure that is a valid momentjs format string for what you're trying to achieve (e.g. dd in moment formats as a two-letter day of week abbreviation); check the momentjs documentation linked in the answer for valid moment format strings.
  • Léon Pelletier
    Léon Pelletier over 7 years
    What I've done is to rewrite my formats to work with this pipe and momentjs. Working very well now. +1!
  • Ant0ha
    Ant0ha about 7 years
    Are they crazy?.
  • Mark Hughes
    Mark Hughes about 7 years
    I think this answer is more of a comment on my answer - it's a good point though!
  • Mark Hughes
    Mark Hughes about 7 years
    Updated following on from the comment-answer from @seven
  • Seven
    Seven about 7 years
    yeah,Thank you for giving me the inspiration
  • Sam
    Sam almost 7 years
    *Tip: If anyone wants to add moment in app.module.ts, it's like this: import { Moment } from 'moment';
  • Josh
    Josh over 6 years
    Thanks, this was very helpful.
  • cheesydoritosandkale
    cheesydoritosandkale over 6 years
    This was awesome! Thanks! Do you know how to grab the timezone? Like CST or EST? (Z) doesn't seem to work
  • cheesydoritosandkale
    cheesydoritosandkale over 6 years
    Do you know how to grab the timezone? Like CST or EST? (Z) doesn't seem to work on IE.
  • Andrew Mairose
    Andrew Mairose over 6 years
    @cheesydoritosandkale angular.io/api/common/DatePipe#description - see the table at this link that shows the different formatting options. Upper case Z is the zone offset, e.g. -0800. I think lower case z is what you're looking for.
  • cheesydoritosandkale
    cheesydoritosandkale over 6 years
    @AndrewMairose The problem is, It just doesn't work on IE =(
  • Andrew Mairose
    Andrew Mairose over 6 years
    @cheesydoritosandkale try using date:'longTime' - that includes the zone and should work in IE
  • KTCO
    KTCO over 6 years
    It now looks like the Internationalization API is supported on all major browsers: caniuse.com/#search=internationalization%20api
  • Ondrej Peterka
    Ondrej Peterka over 6 years
    You should not use this anymore if you use Angular 5, where the problem with native date pipe is solved. Note, that adding moment.js adds more than 300Kb in parsed size to the production build (in Angular 5 and CLI 1.6.8).
  • Mark Hughes
    Mark Hughes over 6 years
    Great point @OndraPeterka - I've updated the answer to make it clear that using Angular 5 is the best way to fix this issue :)
  • Muni Chittem
    Muni Chittem about 6 years
    use moment.js, will filter the time zones
  • apoellitsi
    apoellitsi almost 6 years
    Hello i tried the link you gave for Plunker and is not working on IE 11. Is this related to the DatePipe issue?