Angular2日期管道在IE 11和edge 13/14中不起作用

时间:2016-09-27 15:22:36

标签: datetime angular format pipe internet-explorer-11

我正在使用Angular 2.0 final,当我在格式字符串中添加小时和分钟时,我的日期格式不正确:

在组件的模板中,我有:

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

IE 11中的输出日期为:

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

使用     {{dto.LastExecution |日期: 'YYYY-MM-DD'}}

IE 11中的输出日期是正确的:

2016-09-27

以下是我在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": {}
}

8 个答案:

答案 0 :(得分:62)

更新 - 在Angular 5中解析Angular issue that causes this issue。如果可以,我建议使用它来避免此问题。

如果您仍在使用Angular 4或更早版本 - 作为一种解决方法,我创建了一个管道来使用矩形格式化程序而不是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);
    }
}

然后可以使用:

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

您传递的日期应该是片刻可以解析的内容(请参阅the relevant moment documentation),格式字符串是片刻,而非角度,日期格式字符串,documented here

我在IE11,Chrome和Firefox中对此进行了测试,并且表现一致。

您需要确保将时刻作为依赖项添加到package.json中,例如:

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

...并确保您的systemjs.config.js已更新,以便找到时刻:

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

答案 1 :(得分:15)

来自Angular2 DatePipe API文档。

&#34;此管道使用Internationalization API。因此,它仅在Chrome和Opera浏览器中可靠。

答案 2 :(得分:10)

如果你可以显示上午/下午而不是24小时,另一个有效的解决方法是将格式化为两个,并使用shortTimemediumTime来显示时间部分:

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

这适用于所有主流浏览器,包括IE和Edge。

答案 3 :(得分:5)

关于上面@ mark-hughes的答案,从API文档的那一刻开始:

  

date_expression |日期[:格式]

     

表达式是日期对象或数字(自UTC纪元以来的毫秒数)   或ISO字符串

Reference

因此值应为任何类型,您可以使用moment().isValid()检查值类型

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

答案 4 :(得分:2)

在Angular 5.x中工作

在Angular的5.x版本中,此问题在Edge(v.38.14393.1066.0)和IE(v.11.1198.14393.0)中正常运行,请在您的版本中进行测试!

实例:Plunker Angular 5.x

  

解决问题的相关问题(如果我发现某些内容不一致):https://github.com/angular/angular/issues/9524

  

Answer that involves the entire operation of the Angular DatePipe.

答案 5 :(得分:2)

以下解决方案适用于IE11和Chrome。无需创建自定义管道。

 {{dto.createdTimeLocal | date:'dd MMM yyyy'}} {{dto.createdTimeLocal | date:'shortTime'}}

答案 6 :(得分:0)

用于Angular的moment.js管道

标记答案很棒,这是我使用的,直到我找到了这个简单明了的解决方案。

moment.js pipes for Angular

此模块适用于Angular 2.0及更高版本。

答案 7 :(得分:0)

无需编写此类格式{{date:dd/MM/yyyy hh:mm:ss a}} IE11或EDGE仅以此格式出现问题。

以下是一些替代方案:

例1:新的日期和时间:

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

var datetime = date + " " + time;

例2:您已经有datetime并且想要转换。见下文:

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

我们可以分割日期和时间。

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

var splitdatetime = date + " " + time;

这是Angular4。它适用于所有浏览器。