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 ?

- 16,800
- 14
- 110
- 131

- 5,842
- 6
- 30
- 45
-
1I'd like to know this too. I've found the date pipe docs which explains the order of the y's m' and d's in the format string are ignored as the order is set by the locale. But no indication of how to set (or even get) the locale. – Mark Farmiloe Jan 26 '16 at 16:01
15 Answers
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.
-
66I'm amazed this still doesn't appear to be documented anywhere. Not on the Date Pipe page (https://angular.io/docs/ts/latest/api/common/index/DatePipe-pipe.html), not on the general pipes page (https://angular.io/docs/ts/latest/guide/pipes.html) and this question is actually the first hit on Google (https://www.google.com/search?q=angular%202%20locales&rct=j). Great find. – J.P. Oct 04 '16 at 14:24
-
Also: Setting this locale doesn't seem to affect the `currency` pipe (Angular 2.0 final). – J.P. Oct 04 '16 at 14:32
-
Does this also mean we can use an HTTP request to get the locale? Not entirely sure how that works. – Diego Ledesma Oct 07 '16 at 21:10
-
@Hyperd, yeah, check out the APP_INITIALIZER approach from the following answer - you'd have a chance to resolve locale before app initializes: http://stackoverflow.com/a/37611614/495244 – corolla Oct 22 '16 at 20:27
-
2To use a pipe in code you must now format it as `new CurrencyPipe('en-US');`. Hopefully this is useful for something as this showed up as the first result when Googling my issue. – Ash Blue Nov 24 '16 at 00:51
-
@corolla, seems like LOCALE_ID provider gets called before APP_INITIALIZER (weird!) so you can't really reach your service. – rook Mar 21 '17 at 22:08
-
I use this simple factory function without creating a SettingsService: `() => navigator.language` – Steven Liekens Mar 27 '17 at 12:58
-
1@corolla Can u shed some light on that service? I would like to change the locale when the app is running, is that possible with that service? And how would i implement such service? – Martijn van den Bergh Jun 01 '17 at 07:16
-
1@MartijnvandenBergh, the service just returns locale string - nothing fancy. We've had mixed results trying to change locale while app runs. Ended up reloading page to handle all cases. YMMV. – corolla Jun 06 '17 at 06:22
-
@J.P.tenBerge as of now, there is one reference here https://angular.io/guide/i18n – carkod Jan 04 '19 at 07:45
-
2I also struggled a lot with this subject and I hope the article I wrote about this can help some people: https://medium.com/dailyjs/dynamic-locales-in-angular-dd9a527ebe1f – Michael Karén Feb 12 '19 at 13:43
-
@MichaelKarén ugh, that website has the most obnoxious popup on the internet, I was unable to reach the article before closing the browser tab – JohnF Jul 22 '19 at 12:08
-
-
@corolla it says Parameter 'settingsService' implicitly has an 'any' type , Error – Saurabh Aug 28 '19 at 05:36
-
In my case the factory is only called once. :( `{ provide: LOCALE_ID, useFactory: (translate: TranslateService) => {return translate.currentLang; }, deps: [TranslateService] }` (ngx-translate). And the `currentLang` is undefined because set a little bit later. (init order). Why is the factory only called once? How to set LOCALE_ID dynamically? – Domske Oct 31 '19 at 14:05
-
@Dominik check [this answer](https://stackoverflow.com/a/54803065/6640527) to change language on runtime – Diego Osornio May 20 '20 at 19:20
-
Before spend some hours in this...finally get it and its thanks to you @corolla. GGWP!! – AdamWist Feb 04 '22 at 09:10
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.

- 4,260
- 1
- 30
- 41
-
I am getting template parse error; can't compile filter 'localizedDate' I used with the same way as suggested. – Prasad Shinde Sep 26 '17 at 14:06
-
Have you declared LocalizedDatePipe correctly? See pipe.module.ts in my [example project](https://github.com/milanhlinak/notes/blob/master/notes-ui/src/app/shared/pipes/pipes.module.ts). – Milan Hlinák Sep 27 '17 at 11:34
-
Yes, I have solved it earlier, @Milan Hlinak I should have answered on my comment at that time only. But anyways thanks for your prompt response. You're doing great. – Prasad Shinde Sep 28 '17 at 08:45
-
This is apparently what i was looking for. Its a shame that a custom pipe is required to just change Locale at runtime though.. – dendimiiii Oct 23 '17 at 08:12
-
3It works but pay attention that use an "impure" pipes is slower than the "pure". As [Angular guide](https://angular.io/guide/pipes) says: Angular executes an impure pipe during every component change detection cycle. An impure pipe is called often, as often as every keystroke or mouse-move. With that concern in mind, implement an impure pipe with great care. An expensive, long-running pipe could destroy the user experience. – Luca Ritossa Nov 28 '17 at 10:33
-
Hi @LucaRitossa, thanks for comment. I have not found another way to do it. If you have some tip, please post it. :) +1 btw – Milan Hlinák Feb 05 '18 at 20:59
-
Check my answer for changing language on runtime without creating custom pipe. – knnhcn Feb 21 '19 at 09:05
-
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...
]
})

- 6,651
- 5
- 38
- 62

- 3,793
- 9
- 34
- 39
-
Indeed if you need to use some other locale except en-US, you should register it. Thanks for answer, @zgue – MikkaRin Jan 25 '18 at 13:30
-
3OK that prevented me another headache.. Thx! The doc is a bit complicated, since I though that `registerLocaleData` was enough, well its not. – Melroy van den Berg Nov 02 '19 at 00:27
-
1
-
That worked, but now the million dollar question is why does Angular force locale to be en-US instead of using Chrome or OS locale? – Shadoweb Sep 04 '21 at 08:50
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) { ... }

- 1,071
- 1
- 11
- 22
-
3This is surprisingly nice. You don't even need @ngx-translate for that. Can you explain what the statement in the template does though? – lama May 17 '20 at 18:06
-
3@lama, **dueDate** *(any date you want to format)* **| date: 'shortDate'** *(1st parameter for date pipe corresponding to 'format')* : '' *(2nd parameter => timeZone, "When not supplied, uses the end-user's local system timezone".)* : **trasnlateService.currentLang** *(3rd parameter => local), chick this [DatePipe](https://angular.io/api/common/DatePipe#parameters)* – Diego Osornio May 20 '20 at 18:53
-
-
One drawback is that you need to make the translateService public so it's accessible by the template... – plgod Aug 27 '20 at 14:16
-
1Why exactly do you think that this is a drawback? I am interested and would like to know ;) – knnhcn Sep 01 '20 at 14:02
-
2Best solution in my opinion, but works perfecly fine without @ngx-translate and TranslateService in my case. – Boommeister Jul 19 '21 at 11:09
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' }}

- 3,966
- 3
- 33
- 31
-
-
I couldn't find the list under your link, but here is another good list: http://iteration.info/Sharing/AllAngular5Locales.rtf (taken from here: https://stackoverflow.com/questions/47285742/locales-in-angular-5) – Boommeister Jul 19 '21 at 11:04
-
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.

- 396
- 3
- 8
-
https://github.com/angular/angular/blob/master/modules/@angular/common/src/pipes/date_pipe.ts – julio Jul 08 '16 at 14:18
-
You might want to check out corolla's answer below. It's more up to date and provides a great solution. – Mark Langer Sep 18 '16 at 07:03
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
orserve
:ng serve --configuration=es

- 725
- 7
- 17
-
1As always, you get a much more concise and clear explanation in StackOverflow than Angular official documentation. – Deniz Aug 18 '21 at 18:14
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

- 1,445
- 1
- 20
- 36

- 5,326
- 2
- 26
- 42
-
sorry if it wasnt clear in my question but this is exactly what im doing but with pattern 'shortDate' and it shows only in US style. The time style is fine. – nsbm Jan 20 '16 at 16:01
-
The second example shows a format getting passed to the DatePipe, that's what you wanted no? – Langley Jan 20 '16 at 16:03
-
Tried but it doesnt work. Show just the number '5' independently of the date. – nsbm Jan 20 '16 at 16:06
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.

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

- 4,365
- 1
- 32
- 40
-
4as of angular5, you can use a fat arrow expression in the providers array – iuliust Nov 12 '17 at 20:32
-
1`{ provide: LOCALE_ID, useFactory: () => 'fr-CA'}` did the trick for me ;) – JoxieMedina Dec 29 '17 at 05:43
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.

- 2,988
- 3
- 31
- 43
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"

- 3,393
- 1
- 24
- 25
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); }
}

- 1,723
- 3
- 25
- 47
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);
}
}

- 11
- 3
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.

- 493
- 6
- 15