Angular 2のDatePipeでロケールを設定するにはどうすればよいですか?


138

ヨーロッパ形式を使用して日付を表示したいのですdd/MM/yyyyが、DatePipe shortDate形式を使用すると、米国の日付スタイルのみを使用して表示されますMM/dd/yyyy
デフォルトのロケールはen_USであると想定しています。ドキュメントにないかもしれませんが、Angular2アプリのデフォルトのロケール設定を変更するにはどうすればよいですか?または、カスタム形式をDatePipeに渡す方法はありますか?


1
これも知りたいです。フォーマットストリング内のyのmとdの順序を説明する日付パイプドキュメントは、ロケールによって順序が設定されているため無視されます。しかし、ロケールを設定する(または取得する)方法の指示はありません。
Mark Farmiloe、2016年

回答:


276

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';

より高度なユースケースでは、サービスからロケールを取得することができます。日付パイプを使用するコンポーネントが作成されると、ロケールが解決されます(1回)。

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

それがあなたのために働くことを願っています。


43
これはまだどこにも文書化されていないようです。日付パイプページ(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)。素晴らしい発見。
JP ten Berge

2
コードでパイプを使用するには、パイプをとしてフォーマットする必要がありますnew CurrencyPipe('en-US');。これが私の問題をグーグルするときの最初の結果として現れたので、うまくいけばこれは何かのために便利です。
アッシュブルー

1
@corollaそのサービスに光を当てることはできますか?アプリの実行中にロケールを変更したいのですが、そのサービスでそれは可能ですか?そして、そのようなサービスをどのように実装しますか?
Martijn van den Bergh 2017年

1
@MartijnvandenBergh、サービスはロケール文字列を返すだけです-特別なことはありません。アプリの実行中にロケールを変更しようとすると、さまざまな結果が発生しました。すべてのケースを処理するためにページをリロードすることになりました。YMMV。
カローラ

1
私はこの主題についても多く苦労しました。私がこれについて書いた記事が一部の人々に役立つことを願っています:medium.com/dailyjs/dynamic-locales-in-angular-dd9a527ebe1f
MichaelKarénFeb

72

アプリの言語を一度設定する場合は、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>

または、こちらの簡単な「メモ」プロジェクトを確認してください

ここに画像の説明を入力してください


テンプレート解析エラーが発生しています。提案されたのと同じ方法で使用したフィルター 'localizedDate'をコンパイルできません。
Prasad Shinde 2017

LocalizedDatePipeを正しく宣言しましたか?私のサンプルプロジェクトの pipe.module.tsを参照してください。
MilanHlinák17年

はい、私は以前にそれを解決しました。@ Milan Hlinak私はその時だけコメントに答えるべきでした。とにかく迅速な対応に感謝します。元気です。
Prasad Shinde 2017

これは明らかに私が探していたものです。カスタムパイプが...しかし、実行時にだけ変更ロケールに必要であることをその恥
dendimiiii

2
動作しますが、「純粋でない」パイプの使用は「純粋な」パイプよりも遅いことに注意してください。アンギュラガイド言う:角度は、すべての成分変化検出サイクル中に不純なパイプを実行します。不純なパイプは、すべてのキーストロークまたはマウスの移動と同じくらい頻繁に呼び出されます。その懸念を念頭に置いて、不純なパイプを慎重に実装してください。高価で長時間実行されるパイプは、ユーザーエクスペリエンスを破壊する可能性があります。
Luca Ritossa

64

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...
  ]
})

ドキュメンテーション


実際、en-US以外のロケールを使用する必要がある場合は、それを登録する必要があります。回答をありがとう、@ zgue
MikkaRin

1
もう頭痛がしませんでした。私はそれregisterLocaleDataで十分だったので、ドキュメントは少し複雑です。
danger89

1
Ionic 4のベストアンサー!
パリシマ

22

TranslateServicefrom を使用する場合@ngx-translate/core、以下は実行時に動的に切り替えることで動作する新しいパイプを作成しないバージョンです(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) { ... }

2
これは驚くほどいいです。そのために@ ngx-translateも必要ありません。テンプレートのステートメントが何をするか説明できますか?
ラマ

2
@lama、dueDate (フォーマットしたい任意の日付) | date: 'shortDate' ( 'format'に対応する日付パイプの最初のパラメーター) : '' (2番目のパラメーター=> timeZone、「指定されていない場合、エンドユーザーのローカルシステムのタイムゾーンを使用します。」trasnlateService.currentLang (3番目のパラメーター=>ローカル)、このDatePipeを
Diego Osornio

フォーマットをカスタマイズした場合はどうなりますか?それもローカライズされますか?
ワイルドハンマー

12

date_pipe.tsを確認しましたが、興味深い2ビットの情報があります。上部に次の2行があります。

// 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」にハードコードされていることを示唆しています。

私が間違っていたら教えてください。



以下のカローラの回答を確認してください。より最新であり、優れたソリューションを提供します。
Mark Langer

9

app.module.tsに次のインポートを追加します。ここにLOCALEオプションのリストがあります

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でパイプを使用します。これの角度のドキュメントは次のとおりです。

{{ dateObject | date: 'medium' }}

Justo necesitaba esto!
alexchvrches

5

あなたはこのようなことをします:

{{ dateObj | date:'shortDate' }}

または

{{ dateObj | date:'ddmmy' }}

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


私の質問でそれが明確ではなかった場合は申し訳ありませんが、これはまさに私がやっていることですが、パターン「shortDate」を使用しており、米国スタイルでのみ表示されます 時間のスタイルは結構です。
nsbm

2番目の例は、DatePipeに渡されるフォーマットを示しています。
ラングレー

試しましたが動作しません。日付に関係なく「5」という数字だけを表示します。
nsbm

3

私は同じ問題に苦労していて、これを使用して私のために働きませんでした

{{dateObj | date:'ydM'}}

だから、私は最善の解決策ではなく回避策を試しましたが、うまくいきました:

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

いつでもカスタムパイプを作成できます。


3

AOTに問題がある場合は、useFactoryで少し異なる方法で行う必要があります。

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

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

4
angular5以降、プロバイダー配列で太い矢印式を使用できます
iuliust '12 / 12/17

{ provide: LOCALE_ID, useFactory: () => 'fr-CA'}私のためにトリックをしました;)
JoxieMedina

0

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

0

わかりました、私はこのソリューションを提案します 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);
  }

}

-1

これは少し遅れるかもしれませんが、私の場合(角度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);
}

最善の解決策ではないかもしれませんが、シンプルで機能します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.