Açısal 2'de DatePipe'de yerel ayar nasıl yapılır?


138

Avrupa biçimini kullanarak Tarih görüntülemek istiyorum, dd/MM/yyyyancak DatePipe shortDate biçimini kullanarak yalnızca ABD tarih stilini kullanarak görüntüleniyor MM/dd/yyyy.
Ben varsayılan yerel ayar en_US olduğunu varsayıyorum. Belgelerimde eksik olabilirim ama bir Angular2 uygulamasındaki varsayılan yerel ayarları nasıl değiştirebilirim? Ya da DatePipe'a özel bir format geçirmenin bir yolu var mı?


1
Bunu da bilmek istiyorum. Sipariş yerel ayarı tarafından ayarlandığı gibi biçim dizesinde y 'm' ve d 'sırasını açıklayan tarih boru belgeleri buldum. Ancak, yerel ayarı nasıl ayarlayacağınıza (hatta ayarlayacağınıza) dair hiçbir gösterge yok.
Mark Farmiloe

Yanıtlar:


276

Angular2 RC6'dan itibaren, bir sağlayıcı ekleyerek uygulama modülünüzde varsayılan yerel ayarı ayarlayabilirsiniz:

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

Para Birimi / Tarih / Sayı boruları yerel ayarı almalıdır. LOCALE_ID, açısal / çekirdekten içe aktarılacak bir OpaqueToken'dir .

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

Daha gelişmiş bir kullanım durumu için, bir hizmetten yerel ayarı almak isteyebilirsiniz. Tarih borusu kullanan bileşen oluşturulduğunda yerel ayar (bir kez) çözülür:

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

Umarım sizin için çalışır.


43
Bu hala hiçbir yerde belgelenmemiş gibi görünüyor. Tarih Borusu sayfasında ( angular.io/docs/ts/latest/api/common/index/DatePipe-pipe.html ) değil, genel borular sayfasında ( angular.io/docs/ts/latest/guide/pipes) değil .html ) ve bu soru aslında Google'daki ilk isabettir ( google.com/search?q=angular%202%20locales&rct=j ). Büyük bulmak.
JP ten Berge

2
Kodda bir kanal kullanmak için şimdi olarak biçimlendirmeniz gerekir new CurrencyPipe('en-US');. Umarım bu sorunum için Googling yaparken ilk sonuç olarak ortaya çıktığı için faydalıdır.
Ash Blue

1
@corolla Bu hizmete biraz ışık tutabilir misiniz? Uygulama çalışırken yerel ayarı değiştirmek istiyorum, bu hizmet ile mümkün mü? Ve bu hizmeti nasıl uygulayabilirim?
Martijn van den Bergh

1
@MartijnvandenBergh, hizmet sadece yerel dize döndürür - fantezi bir şey. Uygulama çalışırken yerel ayarları değiştirmeye çalışan karışık sonuçlar elde ettik. Tüm durumları ele almak için yeniden yükleme sayfası sona erdi. YMMV.
corolla

1
Bu konuda da çok mücadele ettim ve umarım bunun hakkında yazdığım makale bazı insanlara yardımcı olabilir: medium.com/dailyjs/dynamic-locales-in-angular-dd9a527ebe1f
Michael Karén

72

Uygulamanız için dili bir kez ayarlamak istiyorsanız, LOCALE_ID ile mükemmel çözüm. Ancak çalışma zamanı sırasında dili değiştirmek isterseniz, çalışmaz. Bu durumda özel tarih borusu uygulayabilirsiniz.

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

}

Şimdi uygulama görüntüleme dilini TranslateService kullanarak değiştirirseniz (bkz. Ngx-translate )

this.translateService.use('en');

uygulamanızdaki biçimler otomatik olarak güncellenmelidir.

Kullanım örneği:

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

veya basit "Notlar" projemi buradan kontrol edin .

resim açıklamasını buraya girin


Şablon ayrıştırma hatası alıyorum; 'localizedDate' filtresini derleyemiyorum Önerilen şekilde kullandım.
Prasad Shinde

LocalizedDatePipe'ı doğru bir şekilde ilan ettiniz mi? Örnek projemdeki pipe.module.ts dosyasına bakın .
Milan Hlinák

Evet, daha önce çözmüştüm, @Milan Hlinak Yorumuma sadece o zaman cevap vermeliydim. Ama yine de hızlı yanıtınız için teşekkürler. Harika gidiyorsun.
Prasad Shinde

Görünüşe göre aradığım şey bu. Onun olsa özel bir boru sadece zamanında Locale değiştirmek için gerekli bir utanç ..
dendimiiii 23:17

2
Çalışır, ancak "saf olmayan" borular kullanmanın "saf" dan daha yavaş olduğuna dikkat edin. Olarak açılı kılavuz söyler: Açısal her bileşen değişimi saptama devresi sırasında saf olmayan bir boru yürütür. Saf olmayan bir boruya, her tuş vuruşu veya fare hareketiyle aynı sıklıkta denir. Bu endişeyi göz önünde bulundurarak, büyük bir dikkatle saf olmayan bir boru uygulayın. Pahalı, uzun ömürlü bir boru kullanıcı deneyimini yok edebilir.
Luca Ritossa

64

İle angular5yukarıdaki cevabı artık çalışmıyor!

Aşağıdaki kod:

app.module.ts

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

Aşağıdaki hataya yol açar:

Hata: "de-at" yerel ayarı için yerel ayar verileri eksik.

İle angular5yüklemek ve kendi başınıza kullanılan yerel dosya kaydetmek gerekir.

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

belgeleme


Gerçekten de, tr-tr dışında başka bir yerel ayar kullanmanız gerekiyorsa, kayıt olmalısınız. Cevabınız için teşekkürler, @zgue
MikkaRin

1
Tamam başka bir baş ağrısını engelledi .. Teşekkürler! Doktor biraz karmaşık, çünkü bu registerLocaleDatayeterliydi ama iyi değil.
danger89

1
Ionic 4 için en iyi cevap!
parrycima

22

Eğer kullanırsanız TranslateServicedan @ngx-translate/coreaşağıya çalışma zamanı üzerinde dinamik anahtarlama ile çalışan yeni bir boru oluşturmadan sürümü (açısal 7 üzerinde test) 'dir. DatePipe localeparametresini ( docs ) kullanarak :

İlk olarak, uygulamanızda kullandığınız yerel ayarları bildirin, örneğ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');
}

Ardından borunuzu dinamik olarak kullanın:

myComponent.component.html

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

myComponent.component.ts

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

2
Bu şaşırtıcı derecede güzel. Bunun için @ ngx-translate'e bile ihtiyacınız yok. Şablondaki ifadenin ne yaptığını açıklayabilir misiniz?
Lama

2
@lama, dueDate (biçimlendirmek istediğiniz herhangi bir tarih) | date: 'shortDate' ('format' a karşılık gelen tarih borusu için 1. parametre) : '' (2. parametre => timeZone, "Sağlanmadığında, son kullanıcının yerel sistem saat dilimini kullanır".) : trasnlateService.currentLang (3. parametre => yerel), bu DatePipe
Diego Osornio

özelleştirilmiş bir biçiminiz varsa ne olacak? bu da yerelleştirilebilir mi?
Wildhammer

12

Ben date_pipe.ts bir göz vardı ve ilgi iki bilgi biti vardır. üst tarafa yakın iki satır vardır:

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

Aşağıya doğru bu çizgi:

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

Bu bana tarih borusunun şu anda 'en-US' olacak şekilde kodlandığını gösteriyor.

Yanılıyorsam lütfen beni aydınlatın.



Corolla'nın cevabını aşağıdan kontrol etmek isteyebilirsiniz. Daha güncel ve harika bir çözüm sunuyor.
Mark Langer

9

App.module.ts üzerinde aşağıdaki içe aktarmaları ekleyin. Burada LOCALE seçeneklerinin bir listesi var .

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

Ardından sağlayıcıyı ekleyin

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

Html'de borular kullanın. İşte bunun için açısal belgeler .

{{ dateObject | date: 'medium' }}

Justo necesitaba esto!
alexchvrches

5

Böyle bir şey yapıyorsun:

{{ dateObj | date:'shortDate' }}

veya

{{ dateObj | date:'ddmmy' }}

Bkz. Https://angular.io/docs/ts/latest/api/common/index/DatePipe-pipe.html


Benim sorum açık değildi ama bu tam olarak ne yapıyorum ama desen 'shortDate' ile üzgünüm ve sadece ABD tarzında gösterir. Zaman tarzı gayet iyi.
nsbm

İkinci örnek, DatePipe'a aktarılan bir formatı gösterir, istediğiniz şey bu mu?
Langley

Denedim ama çalışmıyor. Tarihten bağımsız olarak yalnızca '5' sayısını gösterin.
nsbm

3

Aynı sorunla uğraşıyordum ve bunu kullanarak benim için çalışmadım

{{dateObj | date:'ydM'}}

Bu yüzden, en iyi çözümü değil bir çözümü denedim ama işe yaradı:

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

Her zaman özel bir boru oluşturabilirim.


3

AOT ile sorun yaşayanlar için, bunu bir kullanımla biraz farklı yapmanız gerekir.

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

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

4
angular5 itibarıyla, sağlayıcılar dizisinde şişman bir ok ifadesi kullanabilirsiniz
iuliust

{ provide: LOCALE_ID, useFactory: () => 'fr-CA'}benim için hile yaptı;)
JoxieMedina

0

Google borusu kopyalandı yerel değiştirdi ve benim ülke için çalışıyor onlar tüm yerel için bitirmek mümkün değildir. Kod aşağıdadır.

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

Tamam, bu çözümü çok basit, 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

Bu biraz geç olabilir, ancak benim durumumda (açısal 6), DatePipe'in üstünde basit bir boru oluşturdum, şöyle bir şey:

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

En iyi çözüm olmayabilir, ama basit ve çalışır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.