How to set locale in DatePipe in Angular 2?

僤鯓⒐⒋嵵緔 提交于 2019-11-26 01:57:49

问题


I want to display Date using European format dd/mm/yyyy but using DatePipe shortDate format it only display using US date style mm/dd/yyyy.
I\'m assuming thats the default locale is en_US. Maybe I am missing in the docs but how can I change the default locale settings in an Angular2 app? Or maybe is there some way to pass a custom format to DatePipe ?


回答1:


As of Angular2 RC6, you can set default locale in your app module, by adding a provider:

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

The Currency/Date/Number pipes should pick up the locale. LOCALE_ID is an OpaqueToken, to be imported from angular/core.

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

For a more advanced use case, you may want to pick up locale from a service. Locale will be resolved (once) when component using date pipe is created:

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

Hope it works for you.




回答2:


Solution with LOCALE_ID is great if you want to set the language for your app once. But it doesn’t work, if you want to change the language during runtime. For this case you can implement custom date pipe.

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

}

Now if you change the app display language using TranslateService (see ngx-translate)

this.translateService.use('en');

the formats within your app should automatically being updated.

Example of use:

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

or check my simple "Notes" project here.




回答3:


With angular5 the above answer no longer works!

The following code:

app.module.ts

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

Leads to following error:

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

With angular5 you have to load and register the used locale file on your own.

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




回答4:


I've had a look in date_pipe.ts and it has two bits of info which are of interest. near the top are the following two lines:

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

Near the bottom is this line:

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

This suggests to me that the date pipe is currently hard-coded to be 'en-US'.

Please enlighten me if I am wrong.




回答5:


If you use TranslateService from @ngx-translate/core, below is a version without creating a new pipe which works with switching dynamically on runtime (tested on Angular 7). Using DatePipe's locale parameter (docs):

First, declare the locales you use in your app, e.g. in 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');
}

Then, use your pipe dynamically:

myComponent.component.html

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

myComponent.component.ts

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



回答6:


On app.module.ts add the following imports. There is a list of LOCALE options here.

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

Then add the provider

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

Use pipes in html. Here is the angular documentation for this.

{{ dateObject | date: 'medium' }}



回答7:


You do something like this:

{{ dateObj | date:'shortDate' }}

or

{{ dateObj | date:'ddmmy' }}

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




回答8:


I was struggling with the same issue and didn't work for me using this

{{dateObj | date:'ydM'}}

So, I've tried a workaround, not the best solution but it worked:

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

I can always create a custom pipe.




回答9:


For those having problems with AOT, you need to do it a little differently with a useFactory:

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

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



回答10:


Copied the google pipe changed the locale and it works for my country it is posible they didnt finish it for all locales. Below is the code.

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



回答11:


Ok, I propose this solution, very simple, using 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);
  }

}



回答12:


This might be a little bit late, but in my case (angular 6), I created a simple pipe on top of DatePipe, something like this:

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

May not be the best solution, but simple and works.



来源:https://stackoverflow.com/questions/34904683/how-to-set-locale-in-datepipe-in-angular-2

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!