Làm cách nào để đặt ngôn ngữ trong DatePipe trong Angular 2?


138

Tôi muốn hiển thị Ngày bằng định dạng Châu Âu dd/MM/yyyynhưng sử dụng định dạng DatePipe shortDate, nó chỉ hiển thị theo kiểu ngày của Hoa Kỳ MM/dd/yyyy.
Tôi giả sử rằng miền địa phương mặc định là en_US. Có thể tôi bị thiếu trong các tài liệu nhưng làm cách nào tôi có thể thay đổi cài đặt ngôn ngữ mặc định trong ứng dụng Angular2? Hoặc có thể có một số cách để chuyển một định dạng tùy chỉnh cho DatePipe?


1
Tôi cũng muốn biết điều này. Tôi đã tìm thấy các tài liệu ống ngày giải thích thứ tự của y 'm' và d trong chuỗi định dạng bị bỏ qua vì thứ tự được đặt bởi miền địa phương. Nhưng không có chỉ dẫn về cách đặt (hoặc thậm chí lấy) miền địa phương.
Mark Farmiloe

Câu trả lời:


275

Kể từ Angular2 RC6, bạn có thể đặt ngôn ngữ mặc định trong mô-đun ứng dụng của mình bằng cách thêm nhà cung cấp:

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

Các ống Tiền tệ / Ngày / Số sẽ chọn miền địa phương. LOCALE_ID là một OpaqueToken , được nhập từ góc / lõi.

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

Đối với trường hợp sử dụng nâng cao hơn, bạn có thể muốn nhận ngôn ngữ từ một dịch vụ. Địa điểm sẽ được giải quyết (một lần) khi thành phần sử dụng đường ống ngày được tạo:

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

Hi vọng nó sẽ giúp ích cho bạn.


43
Tôi ngạc nhiên điều này dường như vẫn chưa được ghi nhận ở bất cứ đâu. Không phải trên trang Ngày ống ( angular.io/docs/ts/latest/api/common/index/DatePipe-pipe.html ), không phải trên trang ống chung ( angular.io/docs/ts/latest/guide/pipes .html ) và câu hỏi này thực sự là lần truy cập đầu tiên trên Google ( google.com/search?q=angular%202%20locales&rct=j ). Tuyệt vời tìm thấy.
JP mười Berge

2
Để sử dụng một đường ống trong mã, bây giờ bạn phải định dạng nó là new CurrencyPipe('en-US');. Hy vọng rằng điều này hữu ích cho một cái gì đó vì điều này xuất hiện như là kết quả đầu tiên khi giải quyết vấn đề của tôi.
Ash Blue

1
@corolla Bạn có thể làm sáng tỏ dịch vụ đó không? Tôi muốn thay đổi ngôn ngữ khi ứng dụng đang chạy, điều đó có khả thi với dịch vụ đó không? Và làm thế nào tôi sẽ thực hiện dịch vụ như vậy?
Martijn van den Bergh

1
@MartijnvandenBergh, dịch vụ chỉ trả về chuỗi địa phương - không có gì lạ mắt. Chúng tôi đã có kết quả hỗn hợp khi cố gắng thay đổi ngôn ngữ trong khi ứng dụng chạy. Đã kết thúc trang tải lại để xử lý tất cả các trường hợp. YMMV.
tràng hoa

1
Tôi cũng đã đấu tranh rất nhiều với chủ đề này và tôi hy vọng bài báo mà tôi đã viết về điều này có thể giúp một số người: Medium.com/dailyjs/dynamic-locales-in-angular-dd9a527ebe1f
Michael Karén

72

Giải pháp với LOCALE_ID là tuyệt vời nếu bạn muốn đặt ngôn ngữ cho ứng dụng của mình một lần. Nhưng nó không hoạt động, nếu bạn muốn thay đổi ngôn ngữ trong thời gian chạy. Đối với trường hợp này, bạn có thể thực hiện ống ngày tùy chỉnh.

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

}

Bây giờ nếu bạn thay đổi ngôn ngữ hiển thị ứng dụng bằng TranslateService (xem ngx-dịch )

this.translateService.use('en');

các định dạng trong ứng dụng của bạn sẽ tự động được cập nhật.

Ví dụ sử dụng:

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

hoặc kiểm tra dự án "Ghi chú" đơn giản của tôi ở đây .

nhập mô tả hình ảnh ở đây


Tôi nhận được lỗi phân tích mẫu; không thể biên dịch bộ lọc 'localizedDate' Tôi đã sử dụng theo cùng một cách như được đề xuất.
Prasad Shinde

Bạn đã khai báo LocalizedDatePipe đúng chưa? Xem pipe.module.ts trong dự án ví dụ của tôi .
Milan Hlinák

Vâng, tôi đã giải quyết nó sớm hơn, @Milan Hlinak Tôi chỉ nên trả lời bình luận của tôi vào lúc đó. Nhưng dù sao cũng cảm ơn phản hồi nhanh chóng của bạn. Bạn đang làm rất tốt.
Prasad Shinde

Đây rõ ràng là những gì tôi đang tìm kiếm. Thật xấu hổ khi một đường ống tùy chỉnh được yêu cầu chỉ thay đổi Locale khi chạy ..
dendimiiii

2
Nó hoạt động nhưng chú ý rằng sử dụng đường ống "không tinh khiết" chậm hơn so với "tinh khiết". Như hướng dẫn Angular nói: Angular thực hiện một đường ống không tinh khiết trong mỗi chu kỳ phát hiện thay đổi thành phần. Một ống không tinh khiết được gọi thường xuyên, thường xuyên như mọi lần nhấn phím hoặc di chuyển chuột. Với mối quan tâm đó, thực hiện một đường ống không tinh khiết với sự cẩn thận. Một đường ống dài, đắt tiền có thể phá hủy trải nghiệm người dùng.
Luca Ritossa

64

Với angular5câu trả lời trên không còn hoạt động!

Các mã sau đây:

app.module.ts

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

Dẫn đến lỗi sau:

Lỗi: Thiếu dữ liệu miền địa phương cho ngôn ngữ "de-at".

Với angular5bạn phải tải và đăng ký tập tin bản địa được sử dụng trên của riêng bạn.

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

Tài liệu


Thật vậy, nếu bạn cần sử dụng một số ngôn ngữ khác ngoại trừ en-US, bạn nên đăng ký nó. Cảm ơn câu trả lời, @zgue
MikkaRin

1
OK mà ngăn tôi đau đầu nữa .. Thx! Tài liệu hơi phức tạp, vì tôi mặc dù thế registerLocaleDatalà đủ, nhưng nó không phải vậy.
nguy hiểm89

1
Câu trả lời hay nhất cho Ionic 4!
parrycima

22

Nếu bạn sử dụng TranslateServicetừ @ngx-translate/core, bên dưới là phiên bản mà không tạo đường ống mới hoạt động với chuyển đổi linh hoạt khi chạy (được thử nghiệm trên Angular 7). Sử dụng localetham số ( tài liệu ) của DatePipe :

Đầu tiên, khai báo các địa điểm bạn sử dụng trong ứng dụng của mình, ví dụ 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');
}

Sau đó, sử dụng đường ống của bạn một cách linh hoạt:

myComponent.component.html

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

myComponent.component.ts

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

2
Điều này là đáng ngạc nhiên tốt đẹp. Bạn thậm chí không cần @ ngx-dịch cho điều đó. Bạn có thể giải thích những gì tuyên bố trong mẫu mặc dù?
Lạt ma

2
@lama, doDate (bất kỳ ngày nào bạn muốn định dạng) | date: 'shortDate' (tham số thứ nhất cho ống ngày tương ứng với 'format') : '' (tham số thứ 2 => timeZone, "Khi không được cung cấp, sử dụng múi giờ hệ thống cục bộ của người dùng cuối".) : trasnlateService.cienLang (tham số thứ 3 => địa phương), gà này DatePipe
Diego Osornio

Nếu bạn có định dạng tùy chỉnh thì sao? điều đó cũng sẽ được địa phương hóa?
Wildhammer

12

Tôi đã xem qua date_pipe.ts và nó có hai bit thông tin đáng quan tâm. gần đầu là hai dòng sau:

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

Gần phía dưới là dòng này:

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

Điều này gợi ý cho tôi rằng đường ống ngày hiện tại được mã hóa cứng là 'en-US'.

Hãy soi sáng cho tôi nếu tôi sai.



Bạn có thể muốn kiểm tra câu trả lời của tràng hoa dưới đây. Đó là cập nhật hơn và cung cấp một giải pháp tuyệt vời.
Đánh dấu Langer

9

Trên app.module.ts thêm các mục nhập sau. Có một danh sách các tùy chọn LOCALE ở đây .

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

Sau đó thêm nhà cung cấp

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

Sử dụng đường ống trong html. Đây là tài liệu góc cho việc này.

{{ dateObject | date: 'medium' }}

Justo necesitaba esto!
alexchvrches

5

Bạn làm một cái gì đó như thế này:

{{ dateObj | date:'shortDate' }}

hoặc là

{{ dateObj | date:'ddmmy' }}

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


xin lỗi nếu nó không rõ ràng trong câu hỏi của tôi nhưng đây chính xác là những gì tôi đang làm nhưng với mẫu 'shortDate' và nó chỉ hiển thị theo kiểu Mỹ. Phong cách thời gian là tốt.
nsbm

Ví dụ thứ hai cho thấy một định dạng được chuyển đến DatePipe, đó có phải là điều bạn muốn không?
Langley

Đã thử nhưng nó không hoạt động. Chỉ hiển thị số '5' độc lập với ngày.
nsbm

3

Tôi đã đấu tranh với cùng một vấn đề và đã không làm việc cho tôi bằng cách sử dụng này

{{dateObj | date:'ydM'}}

Vì vậy, tôi đã thử một cách giải quyết, không phải là giải pháp tốt nhất nhưng nó đã hoạt động:

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

Tôi luôn có thể tạo một đường ống tùy chỉnh.


3

Đối với những người gặp vấn đề với AOT, bạn cần thực hiện một chút khác biệt với useFactory:

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

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

4
kể từ angular5, bạn có thể sử dụng biểu thức mũi tên béo trong mảng nhà cung cấp
iuliust

{ provide: LOCALE_ID, useFactory: () => 'fr-CA'}đã lừa tôi;)
JoxieMedina

0

Sao chép đường ống google đã thay đổi ngôn ngữ và nó hoạt động cho đất nước của tôi, có thể thấy rằng họ đã không hoàn thành nó cho tất cả các địa phương. Dưới đây là mã.

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

Ok, tôi đề xuất giải pháp này, rất đơn giản, sử dụng 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

Điều này có thể hơi muộn một chút, nhưng trong trường hợp của tôi (góc 6), tôi đã tạo ra một đường ống đơn giản trên đỉnh DatePipe, đại loại như thế này:

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

Có thể không phải là giải pháp tốt nhất, nhưng đơn giản và hiệu quả.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.