web-dev-qa-db-fra.com

Angular2 date pipe ne fonctionne pas dans IE 11 et Edge 13/14

J'utilise Angular 2.0 final et le format des dates est incorrect lorsque j'ajoute des heures et des minutes dans la chaîne de formatage:

Dans le modèle du composant, j'ai:

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

La date de sortie dans IE 11 est:

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

Avec {{dto.LastExecution | date: 'aaaa-MM-jj'}}

La date de sortie dans IE 11 est correcte:

2016-09-27

Voici la version des composants que j'utilise dans le 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": {}
}
42
Anthony Brenelière

UPDATE - Le problème Angular à l'origine de ce problème est résolu dans Angular 5. Si vous le pouvez, je vous recommanderais de l'utiliser pour éviter ce problème.

Si vous utilisez toujours Angular 4 ou une version antérieure, comme solution de contournement, j'ai créé un tuyau pour utiliser le formateur de moment au lieu de celui intégré dans Angular:

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);
    }
}

Ce qui peut alors être utilisé:

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

La date que vous transmettez doit correspondre à quelque chose que le moment peut analyser (voir la documentation pertinente du moment ) et la chaîne de formatage est une chaîne de formatage de la date, pas angulaire, comme documentée ici .

J'ai testé cela dans IE11, Chrome et Firefox et il se comporte toujours.

Vous devez vous assurer que moment est ajouté à votre package.json en tant que dépendance, par exemple:

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

... et assurez-vous que votre fichier systemjs.config.js est mis à jour pour pouvoir localiser le moment:

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

De Angular2 DatePipe API Documentation.

"Ce tube utilise l’API d’internationalisation. Par conséquent, il n’est fiable que dans les navigateurs Chrome et Opera.

15
Omri L

Si vous êtes d'accord pour afficher l'heure matin/heure au lieu de 24 heures, une autre solution de contournement valide consiste à diviser le formatage en deux et à utiliser shortTime ou mediumTime pour afficher la partie heure:

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

Cela devrait fonctionner dans tous les principaux navigateurs, y compris IE et Edge.

9
Andrew Mairose

En ce qui concerne la réponse de @ mark-hughes ci-dessus, à partir de la documentation de l’API:

expression_date | format de date]

expression est un objet de date ou un nombre (millisecondes depuis l'époque UTC) ou une chaîne ISO 

Référence

Donc, la valeur doit être n’importe quel type, et vous pouvez utiliser moment().isValid() pour vérifier le type de valeur

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

La solution ci-dessous fonctionne bien pour IE11 et chrome. Pas besoin de créer des tuyaux personnalisés.

 {{dto.createdTimeLocal | date: 'jj MMM aaaa'}} {{dto.createdTimeLocal | date: 'shortTime'}} 
2
Muni Chittem

Pas besoin d'écrire un format comme celui-ci {{date:dd/MM/yyyy hh:mm:ss a}}.
IE11 ou Edge rencontre un problème avec ce format uniquement.

Voici quelques alternatives:

Ex 1: nouvelle date et heure:

var date = new Date().toLocaleDateString();
var time = new Date().toLocaleTimeString();

var datetime = date + " " + time;

Ex 2: Vous avez déjà une datetime et vous voulez convertir. voir ci-dessous:

datetime = "3/23/2018 11:43:51 AM"

Nous pouvons diviser la date et l'heure.

var date = new Date(datetime).toLocaleDateString();
var time = new Date(datetime).toLocaleTimeString();

var splitdatetime = date + " " + time;

C'est Angular4. cela fonctionne bien pour tous les navigateurs.

0
Harish Gilaka

moment.js pipes pour Angular

La réponse de Marks est excellente et c’est ce que j’utilisais jusqu’à ce que je trouve cette solution simple et bien documentée.

tuyaux moment.js pour Angular

Ce module fonctionne avec Angular 2.0 et supérieur.

0
JCPhlux