When I select date and transform it to JSON with Angular | json pipe or JSON.stringify I get wrong date (1 day before selected).
Calendar returns Date with timezone, but JSON then converts it to UTC which decrease date for 1 day. I think Calendar should return Date in UTC or at least provide some property to accomplish that.
_Selected date is 24, but JSON version is 23._

@MaklaCof, the DatePicker component (applicable to Calendar and DateInput) works with JavaScript Date instances. The Date object always has a local timezone applied. This is something that we cannot control, hence we always will return a date with the local timezone.
If you would like to avoid this local TZ to UTC conversion, then I would suggest you built an Angular pipe that just formats the value into ISO8601 string without touching the timezone offset. The same approach could be applied for custom json pipe too.
Closing the issue due to inactivity.
If someone wants to comment, please feel free to do so.
Yes I want to comment.
I don't think your proposed solution will work for me. It surprised me, that nobody has this problem.
Working with Javascript Date is definitely the only available option. But I think my problem is big for me and you should help me/us achieve what I/we want.
I have tons of DatePickers, Calendars, DateInputs component. I use it in Template-driven forms, Reactive forms, and eventually I always post object (via JSON) with entire model to the server.
I am using DatePicker in inline grid editing and then post entire row to server, again with JSON.
For example:
export class JobUpdateDeadline
{
constructor(public id: number, public deadline?: Date) { }
}
//.....
this.jobService.updateDeadline(new JobUpdateDeadline(this.id, date)).subscribe();
//.....
updateDeadline(e: JobUpdateDeadline)
{
return this.authService.put<boolean>(this.baseURL + "UpdateDeadline/", JSON.stringify(e));
}
and in ASP.NET Core
[HttpPut("UpdateDeadline")]
public async Task<IActionResult> UpdateDeadline([FromBody]JobUpdateDeadlineModel job)
{
if (!this.ModelState.IsValid)
return this.ReturnInvalidModel;
//....
May I propose some global setting (don't know how to do it in Angular) or at least a boolean property, which will tell date inputs that they should return Javascript Date object with Date and time set in TZ.
For example:
now it returns 2017-04-02 00:00:00
but with boolean property (addLocalTimeToHours) it would return 2017-04-02 02:00:00 (in GMT +2).
I have no other idea how to solve it without recursively checking all object properties if contains Date and add TZ hours. Or add it on server which is even worst idea. And be carefully when Date is DateTime in Javascript and there should happen conversion to UTC. But that would mean everywhere where I use DatePicker/Calendar/DateInput, every change event, every form and every template-driven model. It would be great if I don't need to wory about this things and only to set my suggested boolean property.
Please consider it.
Hi @MaklaCof, thanks for the input.
I am afraid that the DatePicker, nor the Calendar or DateInput, should return a modified Date instance (adjusted with current TZ offset). Although, this is a plausible solution, it makes the component value completely invalid.
I do believe, however, that you can handle this case gracefully using a wrapping (high-order) component , e.g. OffsetDatePicker component. The high-order component will proxy the DatePicker inputs/outputs, but most importantly will handle the Date instance conversion back and forward. Thus, the offset logic will be encapsulated in your custom component, will be testable and easier to reason to. The custom component will be used throughout your application instead of the Kendo DatePicker.
Basically, what I am suggesting is to implement the required additional logic into a high-order component, which enables you to tweak and adjust it much easier.
If additional assistance is needed, please contact our Professional Services:
https://www.progress.com/services
They are fully capable to assist you with this effort.
Hello @ggkrustev,
Thank you for the detailed responses!
Out team is experiencing the same issue with a DatePicker component.
I understand that the existing behaviour stems from using a native Date object. However, it does not suit some very common scenarios.
Fundamentally, there are 2 types of dates:
It seems that a _DatePicker_ covers scenarios that need _absolute date_ but requires additional coding to support _calendar_ date.
Unfortunately, since a _DatePicker_ works only with dates (not time), scenarios with a _calendar_ date are more likely.
Currently, a _DatePicker_ will show different dates for a date of birth across different time zones since it considers a _calendar_ date as an _absolute_ date.
It seems that there is a solution for this issue in other libraries: https://www.igniteui.com/help/api/2017.1/ui.igdateeditor#options:enableUTCDates.
Please, could you consider to extend a _DatePicker_ to handle _calendar_ dates too?
Thank you!
Hello @alexeikostevich,
Thank you for the post and for the detailed explanation of the issue.
I completely agree that handling Dates persisted on the server in one TZ and displayed in other on the client is not a trivial task. The main difficulty comes from the built-in JavaScript Date behavior. In short, I do believe that this issue should be handled outside the DatePicker component, as it works only with JS Date instances. Below I will try to be objective and discuss the possible implementations.
[TL;DR]
I can see clearly why most people think that DatePicker (Date components as a whole) should handle this scenario and I hope that I can explain why I refrain from doing UTC built-in support in the component. For instance, to enable UTC conversion we can choose from several approaches. Let's discuss the possible implementations and their implications:
enableUTC-like option that will modify the Date objectIn this case, the datepicker should accept ISO8601 strings in UTC TZ or Date objects (considering local TZ) and should always return strings in UTC TZ. This is the only way to mitigate the JS Date nature to use only local TZ. Also this solution enforces the date instances persistance only into string values. Their subsequent modification will be very hard and the one should use only using the datepicker, as it will handle the string->date->string conversion. This could be plausable solution, but definitely becomes somewhat messy.
As a negative implication, I can think of:
timezone optionThis will offset the Date instance, just like we do in Kendo Scheduler for jQuery (#link), but this will produce invalid result as I mentioned in my previous reply.
The negative implication here is that the result will be completely offset (read wrong), because the developer will see one and will receive something completely different as Date value. This is required, because JSON.stringify will remove the local TZ for you. Hence Date instances should be already offset to ensure correct UTC TZ value after JSON serialization. As a side note, this is what we do in SchedulerDataSource, but as you can recall the DataSource handles the serialization for you. In Angular, we don't have control over that.
I hope at this point, you can see that the main issue is actually JSON serialization/deserialization and not how the DatePicker manipulates the JavaScript Date instances. They are always in local TZ and we need to accept that.
IMHO, this issue should be mitigated with a dedicated middleware layer that handles the serialization/deserialization of the Date objects. In most cases, your client app will consume JSON, convert it into JavaScript objects and then work with it. Here is the place where Dates should be adjusted. The very same approach is demonstrated in our documentation:
https://www.telerik.com/kendo-angular-ui/components/dateinputs/datepicker/#toc-integration-with-json
If we put the suggested approach in action, we could build a simple Directive class that will handle the string -> Date -> string conversion and will communicate with the DatePicker component for you:
http://plnkr.co/edit/CFmI6qN4qcn6a6CcMnyF?p=preview
With custom directive, you can easily handle string -> Date -> conversion and there is no need to introduce the functionality as a built-in feature. The minus here is that you cannot work with ngModel and formControl and still bind with strings.
Another approach is to use HOC (as mentioned in my previous reply). Here is smth more tengible:
http://plnkr.co/edit/GDu5fLZiu49MdKVt23Gk?p=preview
This one will work with ngModel as it implements ControlValueAccessor. I would vote to use this approach as it separates the UTC behavior into a separate component, which could be easily tweaked if necessary.
After this long long post I still strongly believe that this string -> Date -> string conversion should be handled with Angular Service that performs the actual JSON serialization/deserialization. The service in question will encapsulate the TZ logic internally and will reduce the complexity throughout the app when the one needs to work with dates.
P.S. Sorry for making this post so long, but I wanted to elaborate throughly the UTC support topic and share our thoughts why supporting UTC conversion inside the component is not feasible solution in the Angular component context.
Please let me know if I am missing something or the given solutions don't work for you. Let me know if smth of the written is confusion or incomplete.
Hello @ggkrustev,
Thank you so much for sharing these options and providing your thoughtful opinion on this! I appreciate it so much and very excited to read your response.
Unfortunately, I am not able to pay much attention to this issue at this moment. However, your research on this topic, certainly, deserves it, and I would be delighted to dig into it deeply! Please, give me some time to look at this in more detail, play around with your suggestions and apply them to our codebase.
I will share my results with you as soon as I have them.
Most helpful comment
Hello @ggkrustev,
Thank you for the detailed responses!
Out team is experiencing the same issue with a DatePicker component.
I understand that the existing behaviour stems from using a native Date object. However, it does not suit some very common scenarios.
Fundamentally, there are 2 types of dates:
It seems that a _DatePicker_ covers scenarios that need _absolute date_ but requires additional coding to support _calendar_ date.
Unfortunately, since a _DatePicker_ works only with dates (not time), scenarios with a _calendar_ date are more likely.
Currently, a _DatePicker_ will show different dates for a date of birth across different time zones since it considers a _calendar_ date as an _absolute_ date.
It seems that there is a solution for this issue in other libraries: https://www.igniteui.com/help/api/2017.1/ui.igdateeditor#options:enableUTCDates.
Please, could you consider to extend a _DatePicker_ to handle _calendar_ dates too?
Thank you!