Date and
Time is always hard, especially when it spans across time zones. Once your
application becomes global, the time zone related issues become inevitable.
This becomes harder with Single Page Application Technology, now we need to
sync date between the javascript running on browser and with that of server.
Have you
faced issue where you are losing a day or getting a day more than what user
entered in your Angular application? Chances are that your server is in one
time zone and your user is in a different time zone. Your user enters the date
or picks the date using a calendar control (example Expiration Date). Due to
time zone difference, the date may change when it reaches server. For example,
user in India picked date at 27-09-2018 at 9:00 AM, the server in California
receives this date as 26-09-2018 8:30 PM. If you are considering only date part
then your date will be one day less (26th instead of 27th)
due to this time zone conversion.
Below are
the two solutions for this problem:
- Ignore time zone globally when sending data between browser and server
- A more elegant solution is to ignore time zone only for specific date controls or properties
In this
blog, I will cover the first solution and in my next blog I will go over the
second solution.
Ignore time zone globally
In most
applications, we do not need to consider time. In these applications, ignoring
time zone is the best approach. As you know, Angular and ASP.NET by default
convert the date from one time zone to another time zone. This is true even if
you are sending just date.
The best
way for this problem, is to remove time zones while exchanging data between
ASP.NET and Angular. Unfortunately, there is no out of box solution to remove
time zones. However, the solution is very easy. When the data is exchanged
between ASP.NET and Angular, the data is serialized to JSON and is transferred.
We can tap into this serialization process and can force date conversion to
ignore time zone.
ASP.NET
Core by default uses Json.NET to serialize the data. In Json serialization
configuration, we can specify the date serialization to remove time zone. For
this, we need to pass the Date format as shown below:
.AddJsonOptions(options =>
{
options.SerializerSettings.DateTimeZoneHandling
= DateTimeZoneHandling.Local;
options.SerializerSettings.DateFormatHandling =
DateFormatHandling.IsoDateFormat;
options.SerializerSettings.DateFormatString = "yyyy-MM-ddTHH:mm:ss";
});
In Angular
we also need to override the Json serialization. Angular internally uses
Json.stringy to serialize the object. Under hood, this json serializer uses
toISOString. We can override this and provide the same format we used in the
ASP.NET.
Date.prototype.toISOString = function() {
return this.getFullYear()
+ "-" + this.getMonth().toString().padStart(2, "0")
+ "-" + this.getDate().toString().padStart(2,
"0") + "T"
+ this.getHours().toString().padStart(2, "0") + ":"
+ this.getMinutes().toString().padStart(2, 0) + ":"
+ this.getSeconds().toString().padStart(2, 0);
};
By
providing DateFormats without time zone on both ASP.NET and Angular we can
ignore time zone. With this approach our application does not lose a day while
sending data to and fro.