จะตั้งค่าภาษาใน DatePipe ใน Angular 2 ได้อย่างไร?


144

ฉันต้องการแสดงวันที่โดยใช้รูปแบบยุโรปdd/MM/yyyyแต่ใช้รูปแบบDatePipe shortDateจะแสดงโดยใช้รูปแบบวันที่ของสหรัฐอเมริกาMM/dd/yyyyเท่านั้น
ฉันสมมติว่าโลแคลเริ่มต้นคือ en_US บางทีฉันอาจจะหายไปในเอกสาร แต่ฉันจะเปลี่ยนการตั้งค่าภาษาเริ่มต้นในแอป Angular2 ได้อย่างไร หรืออาจมีวิธีส่งรูปแบบที่กำหนดเองไปยัง DatePipe หรือไม่?


1
ฉันก็อยากรู้เหมือนกัน ฉันพบเอกสารไปป์วันที่ซึ่งอธิบายลำดับของ y ของ m 'และ d ในสตริงรูปแบบจะถูกละเว้นเนื่องจากลำดับถูกกำหนดโดยสถานที่ แต่ไม่มีการระบุวิธีการตั้งค่า (หรือแม้แต่รับ) ภาษา
Mark Farmiloe

คำตอบ:


284

ใน Angular2 RC6 คุณสามารถตั้งค่าภาษาเริ่มต้นในโมดูลแอปของคุณได้โดยเพิ่มผู้ให้บริการ:

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

ไปป์ Currency / Date / Number ควรเลือกโลแคล LOCALE_ID เป็นOpaqueTokenที่จะนำเข้าจากเชิงมุม / แกน

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

สำหรับกรณีการใช้งานขั้นสูงคุณอาจต้องการเลือกภาษาจากบริการ สถานที่จะได้รับการแก้ไข (ครั้งเดียว) เมื่อมีการสร้างส่วนประกอบโดยใช้วันที่:

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

หวังว่ามันจะเหมาะกับคุณ


50
ฉันประหลาดใจมากที่ดูเหมือนว่ายังไม่มีการบันทึกไว้ที่ใด ไม่อยู่ในหน้า Date Pipe ( 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');ไฟล์. หวังว่านี่จะเป็นประโยชน์สำหรับบางสิ่งบางอย่างเนื่องจากสิ่งนี้ปรากฏเป็นผลลัพธ์แรกเมื่อ Googling ปัญหาของฉัน
Ash Blue

1
@corolla คุณช่วยให้ความกระจ่างเกี่ยวกับบริการนั้นได้หรือไม่? ฉันต้องการเปลี่ยนภาษาเมื่อแอปทำงานเป็นไปได้หรือไม่กับบริการนั้น และฉันจะใช้บริการดังกล่าวได้อย่างไร?
Martijn van den Bergh

1
@MartijnvandenBergh บริการเพียงส่งคืนสตริงภาษา - ไม่มีอะไรน่าสนใจ เรามีผลลัพธ์ที่หลากหลายในการพยายามเปลี่ยนภาษาในขณะที่แอปทำงาน สิ้นสุดการโหลดหน้าใหม่เพื่อจัดการทุกกรณี YMMV.
corolla

1
ฉันยังต่อสู้กับเรื่องนี้มากและฉันหวังว่าบทความที่ฉันเขียนเกี่ยวกับเรื่องนี้จะช่วยคนบางคนได้: medium.com/dailyjs/dynamic-locales-in-angular-dd9a527ebe1f
Michael Karén

74

การแก้ปัญหาด้วย 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

คุณประกาศ LocalizedDatePipe อย่างถูกต้องหรือไม่? ดู pipe.module.ts ในของฉันโครงการตัวอย่าง
Milan Hlinák

ใช่ฉันได้แก้ไขไปแล้วก่อนหน้านี้ @Milan Hlinak ฉันควรจะตอบในความคิดเห็นของฉันในเวลานั้นเท่านั้น แต่ยังไงก็ตามขอขอบคุณสำหรับการตอบกลับที่รวดเร็วของคุณ คุณทำได้ดีมาก
Prasad Shinde

เห็นได้ชัดว่านี่คือสิ่งที่ฉันกำลังมองหา น่าเสียดายที่ต้องใช้ท่อที่กำหนดเองเพื่อเปลี่ยน Locale ที่รันไทม์แม้ว่า ..
dendimiiii

3
ใช้งานได้ แต่ต้องใส่ใจว่าการใช้ท่อ "ไม่บริสุทธิ์" จะช้ากว่า "บริสุทธิ์" ดังที่คู่มือเชิงมุมกล่าวว่า: เชิงมุมจะดำเนินการท่อที่ไม่บริสุทธิ์ในทุกรอบการตรวจจับการเปลี่ยนแปลงส่วนประกอบ ท่อที่ไม่บริสุทธิ์มักถูกเรียกว่าบ่อยพอ ๆ กับการกดแป้นพิมพ์หรือการเลื่อนเมาส์ทุกครั้ง ด้วยความกังวลดังกล่าวให้ใช้ท่อที่ไม่บริสุทธิ์ด้วยความระมัดระวัง ท่อราคาแพงและใช้งานได้นานอาจทำลายประสบการณ์ของผู้ใช้
Luca Ritossa

66

ด้วย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
ตกลงที่ทำให้ผมปวดหัวอีก .. Thx! เอกสารมีความซับซ้อนเล็กน้อยเนื่องจากแม้ว่าฉันจะregisterLocaleDataเพียงพอแต่ก็ไม่เป็นเช่นนั้น
อันตราย 89

1
คำตอบที่ดีที่สุดสำหรับ Ionic 4!
parrycima

28

หากคุณใช้TranslateServiceจาก@ngx-translate/coreด้านล่างนี้เป็นเวอร์ชันที่ไม่มีการสร้างไพพ์ใหม่ซึ่งทำงานร่วมกับการสลับแบบไดนามิกบนรันไทม์ (ทดสอบบน Angular 7) การใช้localeพารามิเตอร์ของ DatePipe ( เอกสาร ):

ขั้นแรกประกาศสถานที่ที่คุณใช้ในแอปของคุณเช่นใน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' (พารามิเตอร์ที่ 1 สำหรับไปป์วันที่ที่ตรงกับ 'รูปแบบ') : '' (พารามิเตอร์ที่ 2 => โซนเวลา, "เมื่อไม่ได้ให้มาให้ใช้เขตเวลาของระบบภายในของผู้ใช้ปลายทาง") : trasnlateService.currentLang (พารามิเตอร์ที่ 3 => ท้องถิ่น), เจี๊ยบDatePipe
Diego Osornio

จะเกิดอะไรขึ้นถ้าคุณกำหนดรูปแบบเอง จะเป็นภาษาท้องถิ่นด้วยหรือไม่?
Wildhammer

ข้อเสียเปรียบประการหนึ่งคือคุณต้องทำให้ translateService เป็นสาธารณะเพื่อให้เข้าถึงได้โดยเทมเพลต ...
plgod

ทำไมคุณถึงคิดว่านี่เป็นข้อเสียเปรียบ? ฉันสนใจและต้องการทราบ;)
knnhcn

12

ฉันได้ดู 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'

กรุณาแจ้งฉันถ้าฉันผิด



คุณอาจต้องการตรวจสอบคำตอบของโคโรลลาด้านล่าง เป็นข้อมูลล่าสุดและเป็นโซลูชันที่ยอดเยี่ยม
Mark Langer

9

บน app.module.ts เพิ่มการนำเข้าต่อไปนี้ มีรายการของตัวเลือกสถานที่เกิดเหตุเป็นที่นี่

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

ตัวอย่างที่สองแสดงรูปแบบการส่งผ่านไปยัง DatePipe นั่นคือสิ่งที่คุณไม่ต้องการ?
Langley

พยายามแล้วแต่ไม่ได้ผล แสดงเพียงตัวเลข '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
ในเชิงมุม 5 คุณสามารถใช้นิพจน์ลูกศรอ้วนในอาร์เรย์ผู้ให้บริการ
iuliust

{ provide: LOCALE_ID, useFactory: () => 'fr-CA'}ทำเคล็ดลับให้ฉัน;)
JoxieMedina

1

เริ่มตั้งแต่กระบวนการแปล Angular 9 เปลี่ยนไป ตรวจสอบเอกสารที่เป็นทางการ

ทำตามขั้นตอนด้านล่าง:

  1. เพิ่มแพ็คเกจการแปลหากยังไม่มี: ng add @angular/localize
  2. ตามที่กล่าวไว้ในเอกสาร:

ที่เก็บเชิงมุมมีโลแคลทั่วไป คุณสามารถเปลี่ยนภาษาต้นทางของแอปของคุณสำหรับบิลด์ได้โดยตั้งค่าภาษาต้นทางในช่อง sourceLocale ของไฟล์การกำหนดค่าพื้นที่ทำงานของแอปของคุณ (angular.json) ขั้นตอนการสร้าง (อธิบายไว้ในการผสานการแปลลงในแอปในคู่มือนี้) ใช้ไฟล์ angular.json ของแอปของคุณเพื่อตั้งค่าโทเค็น LOCALE_ID โดยอัตโนมัติและโหลดข้อมูลภาษา

ดังนั้นตั้งค่าภาษาในangular.jsonลักษณะนี้ (สามารถดูรายการสถานที่ที่มีอยู่ได้ที่นี่ ):

{
  "$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"
}

โดยทั่วไปคุณต้องกำหนดsourceLocaleในi18nส่วนและเพิ่มการกำหนดค่าการสร้างด้วยโลแคลเฉพาะเช่น"localize": ["es"]. คุณสามารถเพิ่มserveส่วนนี้ได้หรือไม่

  1. สร้างแอปด้วยภาษาเฉพาะโดยใช้buildหรือserve:ng serve --configuration=es

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.