【问题标题】:How to set locale in DatePipe in Angular 2?如何在 Angular 2 中的 DatePipe 中设置语言环境?
【发布时间】:2016-04-26 13:44:51
【问题描述】:

我想使用欧洲格式 dd/MM/yyyy 显示日期,但使用 DatePipe shortDate 格式它仅使用美国日期样式 MM/dd/yyyy 显示。
我假设默认语言环境是 en_US。也许我在文档中丢失了,但是如何更改 Angular2 应用程序中的默认语言环境设置?或者也许有一些方法可以将自定义格式传递给 DatePipe ?

【问题讨论】:

  • 我也想知道这个。我发现日期管道文档解释了格式字符串中 y's m' 和 d's 的顺序被忽略,因为顺序是由语言环境设置的。但没有说明如何设置(甚至获取)语言环境。

标签: javascript angular date-pipe


【解决方案1】:

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

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

货币/日期/数字管道应该选择语言环境。 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
}

希望它对你有用。

【讨论】:

  • 我很惊讶这似乎仍然没有记录在任何地方。不在日期管道页面 (angular.io/docs/ts/latest/api/common/index/DatePipe-pipe.html) 上,不在一般管道页面 (angular.io/docs/ts/latest/guide/pipes.html) 上,这个问题实际上是 Google 上的第一个问题 (google.com/search?q=angular%202%20locales&rct=j)。很棒的发现。
  • 要在代码中使用管道,您现在必须将其格式化为new CurrencyPipe('en-US');。希望这对某些事情有用,因为这在谷歌搜索我的问题时显示为第一个结果。
  • @corolla 你能解释一下这项服务吗?我想在应用程序运行时更改语言环境,该服务可以吗?我将如何实施这样的服务?
  • @MartijnvandenBergh,该服务只返回语言环境字符串 - 没什么特别的。我们在应用运行时尝试更改语言环境的结果好坏参半。结束重新加载页面以处理所有情况。 YMMV。
  • 我在这个问题上也很挣扎,希望我写的关于这个的文章可以帮助一些人:medium.com/dailyjs/dynamic-locales-in-angular-dd9a527ebe1f
【解决方案2】:

如果您想为您的应用设置一次语言,使用 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

【讨论】:

  • 我收到模板解析错误;无法按照建议的方式编译我使用的过滤器“localizedDate”。
  • 您是否正确声明了LocalizedDatePipe?请参阅我的 example project 中的 pipe.module.ts。
  • 是的,我之前已经解决了,@Milan Hlinak 我应该只在那个时候回答我的评论。但无论如何感谢您的及时回复。你做得很好。
  • 这显然是我想要的。可惜需要一个自定义管道来在运行时更改语言环境..
  • 它有效,但请注意使用“不纯”管道比“纯”管道慢。正如Angular guide 所说:Angular 在每个组件更改检测周期中都会执行一个不纯的管道。不纯管道经常被调用,就像每次击键或鼠标移动一样频繁。考虑到这一点,请非常小心地使用不纯的管道。昂贵且长期运行的管道可能会破坏用户体验。
【解决方案3】:

angular5 上面的答案不再有效!

以下代码:

app.module.ts

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

导致以下错误:

错误:缺少区域设置“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

【讨论】:

  • 确实,如果您需要使用除 en-US 以外的其他语言环境,您应该注册它。谢谢你的回答,@zgue
  • 好的,这让我又头疼了。谢谢!文档有点复杂,因为我认为 registerLocaleData 已经足够了,但它不是。
  • Ionic 4 的最佳答案!
  • 这行得通,但现在百万美元的问题是为什么 Angular 强制语言环境为 en-US 而不是使用 Chrome 或操作系统语言环境?
【解决方案4】:

如果你使用@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) { ... }

【讨论】:

  • 这出奇的好。你甚至不需要@ngx-translate。你能解释一下模板中的语句是做什么的吗?
  • @lama, dueDate (你想格式化的任何日期) | date: 'shortDate' (对应于'format'的日期​​管道的第一个参数) : '' (第二个参数=> timeZone, "当不提供时,使用结束-用户的本地系统时区”。) : trasnlateService.currentLang (第三个参数 => 本地),这个DatePipe
  • 如果您有自定义格式怎么办?那也会被本地化吗?
  • 您究竟为什么认为这是一个缺点?我有兴趣并想知道;)
  • 在我看来最好的解决方案,但在我的情况下,如果没有 @ngx-translate 和 TranslateService 也可以完美运行。
【解决方案5】:

在 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 中使用管道。这是角度documentation

{{ dateObject | date: 'medium' }}

【讨论】:

【解决方案6】:

我查看了 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);

这表明日期管道当前被硬编码为“en-US”。

如果我错了,请赐教。

【讨论】:

【解决方案7】:

你做这样的事情:

{{ dateObj | date:'shortDate' }}

{{ dateObj | date:'ddmmy' }}

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

【讨论】:

  • 很抱歉,如果我的问题不清楚,但这正是我正在做的,但使用模式“shortDate”,它仅以美国风格显示。时间风格很好。
  • 第二个例子显示了一种格式被传递给 DatePipe,这就是你想要的不?
  • 试过了,还是不行。仅显示数字“5”,与日期无关。
【解决方案8】:

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

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

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

【讨论】:

  • 从 angular5 开始,您可以在 providers 数组中使用粗箭头表达式
  • { provide: LOCALE_ID, useFactory: () =&gt; 'fr-CA'} 帮了我大忙 ;)
【解决方案9】:

从 Angular 9 开始,本地化过程发生了变化。查看official doc

按照以下步骤操作:

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

Angular 存储库包含常见的语言环境。您可以通过在应用的工作区配置文件 (angular.json) 的 sourceLocale 字段中设置源语言环境来更改应用的源语言环境。构建过程(在本指南中将翻译合并到应用程序中进行了描述)使用应用程序的 angular.json 文件来自动设置 LOCALE_ID 令牌并加载语言环境数据。

像这样在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

【讨论】:

  • 与往常一样,您在 StackOverflow 中得到的解释比 Angular 官方文档更简洁明了。
【解决方案10】:

我在同样的问题上苦苦挣扎,使用它对我不起作用

{{dateObj | date:'ydM'}}

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

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

我总是可以创建一个自定义管道。

【讨论】:

    【解决方案11】:

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

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

    【讨论】:

      【解决方案12】:

      好的,我提出这个解决方案,很简单,使用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);
        }
      
      }
      

      【讨论】:

        【解决方案13】:

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

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

        (前两个参数是日期格式和时区,如果您对默认设置很好,请不要定义它们)

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

        【讨论】:

          【解决方案14】:

          这可能有点晚了,但就我而言(角度 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);
          }
          

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

          【讨论】:

            猜你喜欢
            • 2017-11-01
            • 1970-01-01
            • 2016-10-07
            • 1970-01-01
            • 2021-11-12
            • 2014-05-29
            • 2014-01-01
            • 2011-01-24
            • 1970-01-01
            相关资源
            最近更新 更多