'Angular 4 date pipe displays wrong date because of time zones - how to fix this?
I have a date value in each of my objects that I can Print like this:
<td> {{competition.compStart }}</td>
And here is how it looks:
1931-05-31T00:00:00.000+0000
In order to change the format to make it more readable I'm using the Angular date pipe:
<td> {{competition.compStart | date : "dd/MM/yyyy"}}</td>
With this result:
30/05/1931
As you can see, It is displaying the previous day (May 30 instead of May 31).
As far as I understand, the problem is related to the timezone, since I'm in Argentina and we have GMT-3 then 00:00 of the 31st minus 3 hours would be May 30 at 9 PM.
So how can I make it take the time literally and not process it based on the timezone, but still apply the format in the pipe?
Solution 1:[1]
Behind the scenes, DatePipe
uses locale to display date in user's timezone. Try with client's timezone data:
1931-05-31T00:00:00.000-0300
instead of 1931-05-31T00:00:00.000+0000
.
You can get client's offset in minutes using (new Date()).getTimezoneOffset()
This is actually the known issue/limitation of DatePipe
. Community is aware of it. It the future, you will be able to specify timezone as one of parameters ({{ value | date:format:zone }}
).
Here is the issue on github: https://github.com/angular/angular/issues/9324
For more advanced date manipulations, I recommend moment.js
(less headaches, better consistency, less testing, simpler maintaining).
EDIT: It has been added:
date_expression | date[:format[:timezone[:locale]]]
Code: https://github.com/angular/angular/blob/5.0.4/packages/common/src/pipes/date_pipe.ts#L137 Docs: https://angular.io/api/common/DatePipe
Solution 2:[2]
for angular 5 and up , you can try to add timezone in pipe,
By default it takes the local timezone of user machine
and you can specify it in minutes for example for GMT-2, timezone: '-120'
{{ competition.compStart | date: 'short' : '-120'}}
Solution 3:[3]
In html file, the below:
{{ value | date:'yyyy-MM-dd hh:mm:ss a':'UTC'+ offset}}
In ts file add the following,
offset:number;
this.offset = (new Date().getTimezoneOffset());
can be useful for converting UTC time to system time (local)
Solution 4:[4]
I also faced the same problem. before saving data convert the date format to the one used in service.For example in my case in Java it was 'YYYY-MM-DD'.So in angular just before saving all the data: where birthdate is binded to your template field or is simply displayed.
this.birthdate= this.datePipe.transform(birthDate, 'yyyy-MM-dd'); where birthdate is not a date object but a string date.
Now, when you need to show the date on the UI use:
let dd = (new Date(data.birthDate)).getUTCDate().toString();
let mm = ((new Date(data.birthDate)).getMonth()).toString();
let yy = (new Date(data.birthDate)).getFullYear().toString();
this.birthDate = new Date(Number(yy), Number(mm), Number(dd));
Solution 5:[5]
I used Date pipe
with offset
in my project as below.
I shared for whom concern.
In component
this.offset = new Date().getTimezoneOffset();
In HTML file
<div>{{deviceInfo?.updatedAt | date: 'dd/MM/yyyy hh:mm:ss' : 'offset'}}</div>
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | |
Solution 3 | |
Solution 4 | Anurag Soni |
Solution 5 | Hien Nguyen |