How to set locale in DatePipe in Angular 2? - javascript

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 ?

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.

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.

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

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

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

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.

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.

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

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

Starting from Angular 9 localization process changed. Check out official doc.
Follow the steps below:
Add localization package if it's not there yet: ng add #angular/localize
As it's said in docs:
The Angular repository includes common locales. You can change your app's source locale for the build by setting the source locale in the sourceLocale field of your app's workspace configuration file (angular.json). The build process (described in Merge translations into the app in this guide) uses your app's angular.json file to automatically set the LOCALE_ID token and load the locale data.
so set locale in angular.json like this (list of available locales can be found here):
{
"$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"
}
Basically you need to define sourceLocale in i18n section and add build configuration with specific locale like "localize": ["es"]. Optionally you can add it so serve section
Build app with specific locale using build or serve: ng serve --configuration=es

Above answers are certainly correct. Note that is is also possible to pass the locale with the pipe:
{{ now | date: undefined:undefined:'de-DE' }}
(The 2 first parameters being date format and timezone, leave them undefined if you are great with the defaults)
Not something you want to do for all your pipes, but sometimes it can be handy.

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

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

Using Pipes and No other installations.
LocalizedDatePipe.ts
import { Pipe, PipeTransform } from '#angular/core';
import { Locale } from 'src/app/contentful/interfaces/locale';
#Pipe({
name: 'localizedDate',
})
export class LocalizedDatePipe implements PipeTransform {
transform(value: any, locale: any): any {
const date = new Date(value);
const options: Intl.DateTimeFormatOptions = {
month: 'short',
day: 'numeric',
year: 'numeric',
};
return date.toLocaleDateString(locale, options);
}
}
Search-overlay.component.html
<span *ngIf="card.date" class="hero-cards-carousel__date">
{{ card.date | localizedDate: vm.locale?.code }}
</span>
Result
"20. Dez. 2012"

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.

Related

How I can create Angular custom Date Pipe

I'm working on angular 5 I want to create a custom date pipe that allows me to subtract some days from a date :
This how I display my date value :
<span>{{data.nextCertificateUpdate | date:'yyyy-MM-dd'}}</span>
for example this display a value like : 2018-08-29
I ask if it's possible to create a pipe that allow me to substract a number of days for example 28 from this date ?
Something like :
<span>{{data.nextCertificateUpdate | mypipe:28 }}</span>
and this should display value like : 2018-08-01
Thanks for any help
Adding to the nice answer given by Sachila above, you can also implement the full functionality in your custom pipe itself.
import { Pipe, PipeTransform } from '#angular/core';
import { DatePipe } from '#angular/common';
#Pipe({ name: 'mypipe' })
export class Mypipe implements PipeTransform {
// adding a default format in case you don't want to pass the format
// then 'yyyy-MM-dd' will be used
transform(date: Date | string, day: number, format: string = 'yyyy-MM-dd'): string {
date = new Date(date); // if orginal type was a string
date.setDate(date.getDate()-day);
return new DatePipe('en-US').transform(date, format);
}
}
And use your custom Pipe like:
<span>{{data.nextCertificateUpdate | mypipe: 28: 'yyyy-MM-dd'}}</span>
See a working example here: https://stackblitz.com/edit/angular-995mgb?file=src%2Fapp%2Fapp.component.html
You can create class for property like wise I have use environment class for date format DATE_FORMAT and assign by default dd-MM-yyyy format and use in date pipe.
By this approach only change the value of DATE_FORMAT and we can easily change the format of date else where.
import { Pipe, PipeTransform } from '#angular/core';
import { environment } from "../../../../environments/environment";
import { DatePipe } from "#angular/common";
#Pipe({
name: 'dateFormat'
})
export class DateFormatPipe extends DatePipe implements PipeTransform {
transform(value: any, args?: any): any {
if(Object.keys(environment).indexOf("DATE_FORMAT") >= 0){
return super.transform(value, environment.DATE_FORMAT);
}
return super.transform(value, 'dd-MM-yyyy');
}
html
<span>{{ data.date | dateFormat }}</span>
Create a custom pipe call mypipe
import { Pipe, PipeTransform } from '#angular/core';
#Pipe({ name: 'mypipe' })
export class Mypipe implements PipeTransform {
transform(date: Date, day: number): string {
date.setDate(d.getDate()-day);
return date;
}
}
call it like this
<span>{{data.nextCertificateUpdate | mypipe:28 | date:'yyyy-MM-dd'}}</span>

How to get date and time in mm-dd-yyy hh-mm-ss in typescript?

Currently, I am getting date time in the following format 'mm/dd/yyyy, hh:mm:ss'.
How to get it in the following format 'mm-dd-yyyy hh-mm-ss'.
How to achieve this without using any library, and preferably by passing some args to the function itself?
Below is the code that am currently using (in Angular 5)
console.log(new Date().toLocaleString(undefined, { hour12: false }));
make use of DatePipe , that is provided by angular framework
{{ strDate | date :'MM-dd-yyyy hh-mm-ss' }
or in code you can do like this
import { DatePipe } from '#angular/common';
#Component({
selector: 'test-component',
templateUrl: './test-component.component.html'
})
class TestComponent {
constructor(private datePipe: DatePipe) {}
formatDate(date= new Date()) {
return this.datePipe.transform(date,'MM-dd-yyyy hh-mm-ss' );
}
}
check here : DatePipe

Get currency symbol angular 2

I'm building an application using angular 2 and currency pipe, but I can't find a way to get the currency symbol according to the ISO value without any number. What I mean is that I just want the symbol without setting a number to be formatted.
Normal situation $3.00
I want only the $symbol, not the number
Angular provides an inbuilt method getCurrencySymbol which gives you currency symbol. You can write a pipe as a wrapper over that method as
import { Pipe, PipeTransform } from '#angular/core';
import { getCurrencySymbol } from '#angular/common';
#Pipe({
name: 'currencySymbol'
})
export class CurrencySymbolPipe implements PipeTransform {
transform(
code: string,
format: 'wide' | 'narrow' = 'narrow',
locale?: string
): any {
return getCurrencySymbol(code, format, locale);
}
}
and then use as:
{{'USD'| currencySymbol}} ===> $
{{'INR'| currencySymbol}} ===> ₹
Live Stackblitz Demo:
App Url: https://angular-currency-symbol-pipe.stackblitz.io
Editor Url: https://stackblitz.com/edit/angular-currency-symbol-pipe
Answered in 2017:
As I ONLY wanted the symbol for the currency, I ended up extending currency pipe with a constant number and return only the symbol. It feels sort of a "hack" to have a constant number, but as i don't want to create new currency maps and I'm not able to provide a number, i think is the easiest way.
Here is what I did:
import { Pipe, PipeTransform } from '#angular/core';
import {CurrencyPipe} from "#angular/common";
#Pipe({name: 'currencySymbol'})
export class CurrencySymbolPipe extends CurrencyPipe implements
PipeTransform {
transform(value: string): any {
let currencyValue = super.transform(0, value,true, "1.0-2");
return currencyValue.replace(/[0-9]/g, '');
}
}
Now I can use it as:
{{ 'EUR' | currencySymbol }} and get '€'
Thanks for your help and ideas!
Update:
Changed accepted answer to Varun's one as in 2020 I would use getCurrencySymbol() to accomplish that task
I know this question is quite old but just if someone happens upon it as I have, Angular has a method to do this without having to do weird and wonderful Regex and string manipulation.
I made the following pipe using the getCurrencySymbol method in #angular/common
import { Pipe, PipeTransform } from '#angular/core';
import { getCurrencySymbol } from '#angular/common';
#Pipe({
name: 'currencySymbol'
})
export class CurrencySymbolPipe implements PipeTransform {
transform(currencyCode: string, format: 'wide' | 'narrow' = 'narrow', locale?: string): any {
return getCurrencySymbol(currencyCode, format, locale);
}
}
You can use the following code in the template which avoids having to define a new pipe:
{{ ( 0 | currency : currencyCode : 'symbol-narrow' ) | slice:0:1 }}
Where this.currencyCode is set to the three digit currency symbol expected to be shown.
for example
import { Pipe, PipeTransform } from '#angular/core';
#Pipe({name: 'removeAFromString'})
export class RemoveAFromString implements PipeTransform {
transform(value: number){
return value.substring(1);
}
}
Now concat the pipes:
{{ portfolio.currentValue | currency : 'AUD' : true : '4.0' | removeAFromString}}

Change language of Datepicker of Material Angular 4

How to Change language of Datepicker of Material Angular?
I can't find in documentation for Angular material 2.
Here is a plunkr https://plnkr.co/edit/unzlijtsHf3CPW4oL7bl?p=preview
<md-input-container>
<input mdInput [mdDatepicker]="picker" placeholder="Choose a date">
<button mdSuffix [mdDatepickerToggle]="picker"></button>
</md-input-container>
<md-datepicker #picker></md-datepicker>
import {MAT_DATE_LOCALE} from '#angular/material';
&
providers: [{ provide: MAT_DATE_LOCALE, useValue: 'es-ES' }]
Do this in tpv.modules.ts
md-datepicker provides setLocale method which can be used to set any language (list of locale).
Here's an example of setting locale to 'fr':
export class DatepickerOverviewExample {
constructor(private dateAdapter: DateAdapter<Date>) {
this.dateAdapter.setLocale('fr');
}
}
One thing to keep in mind, md-datepicker's default date parsing format is mm/dd/yyyy, so if a locale has a different date format (for 'fr' its dd/mm/yyyy), we will need to define a class that extends NativeDateAdapter to parse the new date format. Without setting the proper date format, there will be an issue like this question.
import { NativeDateAdapter, DateAdapter, MD_DATE_FORMATS } from "#angular/material/core";
export class FrenchDateAdapter extends NativeDateAdapter {
parse(value: any): Date | null {
if ((typeof value === 'string') && (value.indexOf('/') > -1)) {
const str = value.split('/');
if (str.length < 2 || isNaN(+str[0]) || isNaN(+str[1]) || isNaN(+str[2])) {
return null;
}
return new Date(Number(str[2]), Number(str[1]) - 1, Number(str[0]), 12);
}
const timestamp = typeof value === 'number' ? value : Date.parse(value);
return isNaN(timestamp) ? null : new Date(timestamp);
}
}
#Component({
...
providers: [{provide: DateAdapter, useClass: FrenchDateAdapter}],
})
Plunker demo
Locale setting can be provided via MAT_DATE_LOCALE constant, but to change language dynamically you need to use DateAdapter as it is shown in https://material.angular.io/components/datepicker/overview#internationalization
#Component({
selector: 'app-root',
templateUrl: './app.component.html'
})
export class AppComponent {
constructor(private dateAdapter: DateAdapter<any>) {}
setFrench() {
// Set language of Datepicker
this.dateAdapter.setLocale('fr');
}
}
Here is another example when you need to configure locale from external script:
<script>
window.appConfig = {
language: 'fr',
// Other config options
// ...
};
<script>
<app-root></app-root>
In this case you should also use DateAdapter:
import {Injectable} from '#angular/core';
import {DateAdapter} from '#angular/material';
declare let window: any;
#Injectable()
export class AppConfigService {
appConfig = window.appConfig;
constructor(private dateAdapter: DateAdapter<any>) {
// Set language of Datepicker
this.dateAdapter.setLocale(this.appConfig.language);
}
}
For anyone who has a bug when editing input field (eg: putting DD/MM/YYYY will change it to MM/DD/YYYY or simply not working) create an adapter:
import { NativeDateAdapter } from '#angular/material';
export class FrenchDateProvider extends NativeDateAdapter {
parse(value: string) {
let it = value.split('/');
if (it.length == 3) {
return new Date(+it[2], +it[1] - 1, +it[0], 12);
}
}
format(date: Date, displayFormat: Object) {
return ('0' + date.getDate()).slice(-2) + '/' + ('0' + (date.getMonth() + 1)).slice(-2) + '/' + date.getFullYear();
}
}
Add it to your module as provider:
#NgModule({
providers: [
{ provide: DateAdapter, useClass: FrenchDateProvider }
]
})
export class SharedModule { }
For me the working solution is similar to vladernn's, however it should be:
import {MAT_DATE_LOCALE} from '#angular/material/core';
and
providers: [{ provide: MAT_DATE_LOCALE, useValue: 'pl' }]
in material.module.ts file.
Difference: new import address and shorter useValue code.
I tried this and worked for me
constructor(private _adapter: DateAdapter<any>, private translate:TranslateService ) {
this._adapter.setLocale(this.translate.getBrowserLang());
}

Angular2 Using Pipes in Component.js

I'm learning Angular2 and I want to format a number adding thousand comma separator. As far as I have read this can be done using Pipes, the thing is that I want to format the number programmatically in the js file not in html (doing like var | number).
First of all I've realized there is no NumberPipe standalone pipe that I can work with (correct me if I'm wrong) the most similar one is CurrencyPipe in #angular2/common. So I have something like this:
import { Component } from '#angular/core';
import { CurrencyPipe } from '#angular/common';
#Component({
templateUrl: 'test.component.html',
styleUrls: ['./test.component.scss']
})
export class TestComponent {
public myNumber = 1000;
constructor(private currencyPipe: CurrencyPipe) {
var formatted = this.currencyPipe().transform(this.myNumber, 'MXN', true); // Is this correct?
}
}
But it throws me the following error:
Unhandled Promise rejection: No provider for CurrencyPipe! ; Zone: angular ;...
What am I doing wrong?
Thanks in advance.
Regards
First thing: you need to declare your pipe - add it to the NgModule declarations section:
declarations: [CurrencyPipe]
Second thing: pipes are not injectables, so you can't take its instance by using Angular dependency injection system. You need to create new instance of this pipe manually, like:
var formatted = (new CurrencyPipe()).transform(this.myNumber, 'MXN', true);
This actually works in an #Injectable display utility service with even less fuss than the previous answer involving modules. I imported my data model (below) and the pipe, then simply added the function. So, if you can't use the pipe directly in markup, use this trick!
export interface MoneyDTO extends SerializableDTO, JsonModelObjectDTO {
value?: string;
currency?: string;
}
import { CurrencyPipe } from '#angular/common';
formatMoney(money: MoneyDTO): string {
const cp: CurrencyPipe = new CurrencyPipe('en-US');
return money && money.value ? cp.transform(money.value, money.currency || 'USD', 'symbol') : null;
}

Categories