如何在 Angular 2 的 DatePipe 中设置语言环境?

How to set locale in DatePipe in Angular 2?

我想使用欧洲格式 dd/MM/yyyy 显示日期,但使用 DatePipe shortDate 格式只能使用美国日期样式显示 MM/dd/yyyy
我假设默认语言环境是 en_US。也许我在文档中遗漏了但如何更改 Angular2 应用程序中的默认区域设置?或者有没有办法将自定义格式传递给 DatePipe?

你这样做:

{{ dateObj | date:'shortDate' }}

{{ dateObj | date:'ddmmy' }}

见: https://angular.io/docs/ts/latest/api/common/index/DatePipe-pipe.html

我已经查看了 date_pipe.ts,它有两个有趣的信息。 靠近顶部的是以下两行:

// TODO: move to a global configurable location along with other i18n components.
var defaultLocale: string = 'en-US';

底部附近是这一行:

return DateFormatter.format(value, defaultLocale, pattern);

这表明日期管道当前 hard-coded 为 'en-US'。

如有错误请赐教

我一直在为同样的问题而苦苦挣扎,但使用这个对我不起作用

{{dateObj | date:'ydM'}}

所以,我尝试了一种解决方法,虽然不是最好的解决方法,但它奏效了:

{{dateObj | date:'d'}}/{{dateObj | date:'M'}}/{{dateObj | date:'y'}}

我总能创建自定义管道。

复制了 google 管道更改了语言环境,它适用于我的国家,他们可能没有为所有语言环境完成它。下面是代码。

import {
    isDate,
    isNumber,
    isPresent,
    Date,
    DateWrapper,
    CONST,
    isBlank,
    FunctionWrapper
} from 'angular2/src/facade/lang';
import {DateFormatter} from 'angular2/src/facade/intl';
import {PipeTransform, WrappedValue, Pipe, Injectable} from 'angular2/core';
import {StringMapWrapper, ListWrapper} from 'angular2/src/facade/collection';


var defaultLocale: string = 'hr';

@CONST()
@Pipe({ name: 'mydate', pure: true })
@Injectable()
export class DatetimeTempPipe implements PipeTransform {
    /** @internal */
    static _ALIASES: { [key: string]: String } = {
        'medium': 'yMMMdjms',
        'short': 'yMdjm',
        'fullDate': 'yMMMMEEEEd',
        'longDate': 'yMMMMd',
        'mediumDate': 'yMMMd',
        'shortDate': 'yMd',
        'mediumTime': 'jms',
        'shortTime': 'jm'
    };


    transform(value: any, args: any[]): string {
        if (isBlank(value)) return null;

        if (!this.supports(value)) {
            console.log("DOES NOT SUPPORT THIS DUEYE ERROR");
        }

        var pattern: string = isPresent(args) && args.length > 0 ? args[0] : 'mediumDate';
        if (isNumber(value)) {
            value = DateWrapper.fromMillis(value);
        }
        if (StringMapWrapper.contains(DatetimeTempPipe._ALIASES, pattern)) {
            pattern = <string>StringMapWrapper.get(DatetimeTempPipe._ALIASES, pattern);
        }
        return DateFormatter.format(value, defaultLocale, pattern);
    }

    supports(obj: any): boolean { return isDate(obj) || isNumber(obj); }
}

从 Angular2 RC6 开始,您可以通过添加提供程序在您的应用模块中设置默认语言环境:

@NgModule({
  providers: [
    { provide: LOCALE_ID, useValue: "en-US" }, //replace "en-US" with your locale
    //otherProviders...
  ]
})

Currency/Date/Number 管道应该选择语言环境。 LOCALE_ID 是一个 OpaqueToken,将从 angular/core.

导入
import { LOCALE_ID } from '@angular/core';

对于更高级的用例,您可能希望从服务中获取语言环境。创建使用日期管道的组件时,将解析语言环境(一次):

{
  provide: LOCALE_ID,
  deps: [SettingsService],      //some service handling global settings
  useFactory: (settingsService) => settingsService.getLanguage()  //returns locale string
}

希望对你有用。

如果您想一次性为您的应用设置语言,LOCALE_ID 的解决方案非常有用。但如果你想在运行时更改语言,它就不起作用了。对于这种情况,您可以实现自定义日期管道。

import { DatePipe } from '@angular/common';
import { Pipe, PipeTransform } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';

@Pipe({
  name: 'localizedDate',
  pure: false
})
export class LocalizedDatePipe implements PipeTransform {

  constructor(private translateService: TranslateService) {
  }

  transform(value: any, pattern: string = 'mediumDate'): any {
    const datePipe: DatePipe = new DatePipe(this.translateService.currentLang);
    return datePipe.transform(value, pattern);
  }

}

现在,如果您使用 TranslateService 更改应用显示语言(参见 ngx-translate

this.translateService.use('en');

您应用中的格式应该会自动更新。

使用示例:

<p>{{ 'note.created-at' | translate:{date: note.createdAt | localizedDate} }}</p>
<p>{{ 'note.updated-at' | translate:{date: note.updatedAt | localizedDate:'fullDate'} }}</p>

或查看我的简单 "Notes" 项目 here

对于那些使用 AOT 有问题的人,您需要使用 useFactory 做一些不同的事情:

export function getCulture() {
    return 'fr-CA';
}

@NgModule({
  providers: [
    { provide: LOCALE_ID, useFactory: getCulture },
    //otherProviders...
  ]
})

好的,我提出这个解决方案,很简单,使用ngx-translate

import { DatePipe } from '@angular/common';
import { Pipe, PipeTransform } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';

@Pipe({
  name: 'localizedDate',
  pure: false
})
export class LocalizedDatePipe implements PipeTransform {

  constructor(private translateService: TranslateService) {
}

  transform(value: any): any {
    const date = new Date(value);

    const options = { weekday: 'long',
                  year: 'numeric',
                  month: 'long',
                  day: 'numeric',
                  hour: '2-digit',
                  minute: '2-digit',
                  second: '2-digit'
                    };

    return date.toLocaleString(this.translateService.currentLang, options);
  }

}

使用 angular5 以上答案不再有效!

以下代码:

app.module.ts

@NgModule({
  providers: [
    { provide: LOCALE_ID, useValue: "de-at" }, //replace "de-at" with your locale
    //otherProviders...
  ]
})

导致以下错误:

Error: Missing locale data for the locale "de-at".

使用 angular5 您必须自行加载和注册使用的语言环境文件。

app.module.ts

import { NgModule, LOCALE_ID } from '@angular/core';
import { registerLocaleData } from '@angular/common';
import localeDeAt from '@angular/common/locales/de-at';

registerLocaleData(localeDeAt);

@NgModule({
  providers: [
    { provide: LOCALE_ID, useValue: "de-at" }, //replace "de-at" with your locale
    //otherProviders...
  ]
})

Documentation

这可能有点晚,但就我而言 (angular 6),我在 DatePipe 之上创建了一个简单的管道,如下所示:

private _regionSub: Subscription;
private _localeId: string;

constructor(private _datePipe: DatePipe, private _store: Store<any>) {
  this._localeId = 'en-AU';
  this._regionSub = this._store.pipe(select(selectLocaleId))
    .subscribe((localeId: string) => {
      this._localeId = localeId || 'en-AU';
    });
}

ngOnDestroy() { // Unsubscribe }

transform(value: string | number, format?: string): string {
  const dateFormat = format || getLocaleDateFormat(this._localeId, FormatWidth.Short);
  return this._datePipe.transform(value, dateFormat, undefined, this._localeId);
}

可能不是最好的解决方案,但简单有效。

在 app.module.ts 添加以下导入。有一个 LOCALE 选项列表 here.

import es from '@angular/common/locales/es';
import { registerLocaleData } from '@angular/common';
registerLocaleData(es);

然后添加提供商

@NgModule({
  providers: [
    { provide: LOCALE_ID, useValue: "es-ES" }, //your locale
  ]
})

在 html 中使用管道。这是 angular documentation

{{ dateObject | date: 'medium' }}

如果您使用 @ngx-translate/core 中的 TranslateService,下面是一个没有创建新管道的版本,它可以在运行时动态切换(在 Angular 7 上测试)。使用 DatePipe 的 locale 参数 (docs):

首先,声明您在应用中使用的语言环境,例如在 app.component.ts:

import localeIt from '@angular/common/locales/it';
import localeEnGb from '@angular/common/locales/en-GB';
.
.
.
ngOnInit() {
    registerLocaleData(localeIt, 'it-IT');
    registerLocaleData(localeEnGb, 'en-GB');
}

然后,动态使用你的管道:

myComponent.component.html

<span>{{ dueDate | date: 'shortDate' : '' : translateService.currentLang }}</span>

myComponent.component.ts

 constructor(public translateService: TranslateService) { ... }

从Angular 9 本地化过程开始改变。查看 official doc

按照以下步骤操作:

  1. 如果还没有本地化包,请添加:ng add @angular/localize
  2. 正如文档中所说:

The Angular repository includes common locales. You can change your app's source locale for the build by setting the source locale in the sourceLocale field of your app's workspace configuration file (angular.json). The build process (described in Merge translations into the app in this guide) uses your app's angular.json file to automatically set the LOCALE_ID token and load the locale data.

所以在 angular.json 中像这样设置语言环境(可以找到可用语言环境列表 here):

{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "version": 1,
  "newProjectRoot": "projects",
  "projects": {
    "test-app": {
      "root": "",
      "sourceRoot": "src",
      "projectType": "application",
      "prefix": "app",
      "i18n": {
        "sourceLocale": "es"
      },
      ....
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:browser",
          ...
          "configurations": {
            "production": {
             ...
            },
            "ru": {
              "localize": ["ru"]
            },
            "es": {
              "localize": ["es"]
            }
          }
        },
        "serve": {
          "builder": "@angular-devkit/build-angular:dev-server",
          "options": {
            "browserTarget": "test-app:build"
          },
          "configurations": {
            "production": {
              "browserTarget": "test-app:build:production"
            },
            "ru":{
              "browserTarget": "test-app:build:ru"
            },
            "es": {
              "browserTarget": "test-app:build:es"
            }
          }
        },
        ...
      }
    },
    ...
  "defaultProject": "test-app"
}

基本上您需要在 i18n 部分定义 sourceLocale 并添加具有特定语言环境的构建配置,例如 "localize": ["es"]。您可以选择添加它 serve 部分

  1. 使用 buildserve 构建具有特定语言环境的应用程序:ng serve --configuration=es

以上答案肯定是正确的。请注意,可以通过管道传递语言环境:

  {{ now | date: undefined:undefined:'de-DE' }}

(前 2 个参数是日期格式和时区,如果您对默认值很好,请将它们保留为未定义)

您不想为所有管道做的事情,但有时它会很方便。