I have a very strange issue with the new Calendar module:
Example:
import { Component, OnInit } from '@angular/core';
@Component({
selector : 'app-test',
templateUrl : './test.component.html'
})
export class TestComponent implements OnInit {
someDate: Date;
constructor() {}
ngOnInit() {
// simulate API call
setTimeout(() => this.someDate = new Date('2018-08-16T00:00:00.000Z'), 2000);
}
}
<b>Value:</b> {{someDate}} <b>JSON stringify:</b> {{someDate|json}} <br>
<p-calendar [(ngModel)]="someDate"></p-calendar>
This is the result (_the initial value is not set, but i think this is a known issue at the moment_):
This is what happens when you select a date:
Basically the bound value is incorrect after the conversion to JSON string (it represents the day before) due to the timezone. But there is no other way to submit the value back to the API.
Is there a way for this component to work (internally) in UTC? Maybe somehow using dateObj.getTimezoneOffset()
to compensate for the time zone difference?
This is the offending code:
components/calendar/calendar.ts:417
- this.value = new Date(dateMeta.year, dateMeta.month, dateMeta.day);
Edit: added comments
I still have the same issue beta20. Is it only me that is facing this?
Yep .. I think I'm having the same thing on beta20.
I've some other issues with timezone that seems to be causing the value to be different in IE vs Chrome .. not sure if that's related yet, need to investigate it
Hi, I suffer the same problem.
Fri Nov 04 2016 00:00:00 GMT+0200 (FLE Standard Time)
2016-11-03T22:00:00+00:00
Consider choosing a date from the calendar (without time) set the date in 00:00:00 in UTC time but not 00:00:00 in local time zone. Selecting a date from browser in Germany should set 2016-11-04T00:01:00+01:00, in Bulgaria - 2016-11-04T00:02:00+02:00, etc...
So this line:
https://github.com/primefaces/primeng/blob/master/components/calendar/calendar.ts#L429
may become
this.value = new Date(Date.UTC(dateMeta.year, dateMeta.month, dateMeta.day));
Yes, it would be great if there will be a timezone property to get the UTC date where the default is local timezone. Something like:
<p-calendar [(ngModel)]="dateValue" timezone="utc"></p-calendar>
OR
<p-calendar [(ngModel)]="dateValue" utc="true"></p-calendar>
WDYT?
Default local timezone and utc boolean attribute as proposed by @mrgoos sounds great.
I'm having this same issue with 1.0.0 and it's critical as it creates a date mismatch between what the user selects and what is stored to my database (which must store the dates in UTC).
Have there been any updates or have any of the solutions proposed above been considered?
@rfboykin - as a workaround you can use this to get UTC date by sending calendar's date to this function:
getUTCDate(date: Date): Number {
return date.getTime() / 1000 - date.getTimezoneOffset() * 60;
}
I also came across this issue today and editing calendar.js file as @ilianiv proposed fixed the problem for me. Are there any plans on making these changes in the new version?
P.S.: I am using PriemNG 2.0.0-rc.1
P.P.S.: I just noticed that this fix works when I select data from the calendar, but when I copy the date and paste it, I still get yesterday as a result.
ref @ilianiv comment on 4 Nov 2016
the line does not appear to have been fixed in subsequent pull requests
if you are using primeng "1.0.0-rc.1") (and do not have the ts source) you can edit node_modules/primeng/components/calendar/calendar.js instead:
around line 207
this.value = new Date(dateMeta.year, dateMeta.month, dateMeta.day);
replace with
this.value = new Date(Date.UTC(dateMeta.year, dateMeta.month, dateMeta.day));
This issue is still not fixed in 2.0.1 - are there any plans to fix it anytime soon?
BUG REPORT:
Using version 4.0.0-rc.2.
Chrome or Firefox.
Current behaviour:
Selecting:
Apr 02 2017
Getting following Date value saved into bound model variable:
Sat Apr 01 2017 20:00:00 GMT-0400 (Eastern Daylight Time)
Calendar displaying:
Apr 01 2017
Expected behaviour:
Selecting:
Apr 02 2017
Getting following Date value saved into bound model variable:
Sat Apr 02 2017 00:00:00 GMT-0400 (Eastern Daylight Time)
Calendar displaying:
Apr 02 2017
Testable on your example site: https://www.primefaces.org/primeng/#/calendar
Date selected should not be _converted_ to UTC since it changes the actual date and time selected by the user. If you want to give date/time in UTC as a boolean flag option, then truncate the timezone instead of converting to UTC and changing the selected date/time. Example: "18:00:00 GMT-0400" becomes "18:00:00 GMT-0000".
+1 I couldn't upgrade my app because of this issue, I'm using calendar in many components. Sometimes I need the UTC time, but most of the time I need the local user time and with this change I would have to add a lot of boilerplate code to get the local time. The @mrgoos idea to add an attribute like "utc"=true sounds good.
Reverting due to regressions;
2426
Adding utc="true"
helps to solve the problem when selecting the date from the calendar, but if I write it down manually or copy and paste it after selecting from input - the problem still exists. I guess you need to also add the checking for if(this.utc)
to updateModel()
in calendar.ts
because at the moment checking for utc is implemented only in selectDate(dateMeta)
method.
I am using for past experience, where it does not need time.
is there a way to strip the time of the model? or at-least an example where I can scaffold my input model with date?
I fixed the issue by extending the Calendar class, then hid/rewrote the base class updateModel function, copy/paste its base functionality and added this line
this.fixUTCDate(this.value);
in the beginning of the function .
Here is the code of fixUTCDate:
private fixUTCDate(date): void {
if (date) {
date.setTime(new Date(new Date(date.getTime() - (date.getTimezoneOffset() * 60 *
1000)).toUTCString()));
}
}
Works with both selecting the date and typing it manually.
Most helpful comment
Yes, it would be great if there will be a timezone property to get the UTC date where the default is local timezone. Something like:
<p-calendar [(ngModel)]="dateValue" timezone="utc"></p-calendar>
OR
<p-calendar [(ngModel)]="dateValue" utc="true"></p-calendar>
WDYT?