Sometimes, I have seen developers (myself included) use simple strings to represent dates. This could lead to unexpected behaviors if you are not careful. For instance, I recently ran into a bug where the PDF document the program generated show the incorrect date, which was a few hours off from the correct one. The date value originated from a data API and did not include a timezone. The intended time zone was local time, which is Pacific Standard Time (PST) in this case. However, because we were using storing the date in the angular application using string instead of the javascript built-in Date type, when the framework serialized the data into JSON and sent to .NET, it kept the date as is and did not add any timezone. At the backend, .NET deserialized the value back into a DateTime object, and when we attempted to convert the value to local time usingDateTime.ToLocalTime()
for displaying in the document, we got an incorrect value because .NET assumed the date was in Universal Coordinated Time (UTC).
The bug was because of inconsistencies when passing date values and not including timezone information. However, had we used the frameworks’ built-in types for representing dates instead of strings, we could have avoided the issue.
When you use Date type to represent a date in a Javascript/Angular application, you don’t have to worry about timezones as by default, the framework automatically includes it for you when it serializes the value into JSON. However, if the value is just a string, the framework does nothing, and you should ensure the value contains timezone information to avoid losing a few hours of your precious life trying to figure out why your date is off.
Consider the following simplified JSON coming from the Javascript/Angular application to the ASP.NET core application. Both the client and server are in the same timezone, Pacific Standard Time (PST) in this case.
{"date":"2018-12-04T12:02:56"}
The JSON above is the serialization of the following simple TypeScript class:
export class DateExample { date: string ="2018-12-04T12:02:56"; }
In simple format, the date is 12/04/18 12:02:56 PM. The intended timezone is PST. At the server side, .NET serializes the value into a DateTime object with the timezone (System.DateTime.TimeKind) as unspecified.
When I convert the date to local time with date.ToLocalTime()
, it becomes
12/04/18 04:02:56 AM, which is 8 hours off. That is because when the TimeKind is unspecified, the call ToLocalTime() assumes I want to convert from Coordinated Universal Time (UTC) to local time zone, and my local time is PST, which is UTC – 8 hours. However, the time I pass from the angular app is already in PST time.
Indeed, the document warns against calling ToLocalTime() on a DateTime instance that already represents local time.
ToLocalTime UTC Local Time Do not call on an DateTime instance that already represents local time
In the angular application, because I use string, the Javascript framework does not convert it into UTC for me on serialization.
Now let’s switch to using Date type.
export class DateExample { date: Date = new Date("2018-12-04T12:02:56"); }
When serializing to JSON, the Javascript framework automatically converts the value to UTC (The Z at the end indicates the time is in UTC).
{ "date" :"2018-12-04T20:02:56.000Z"; }
At the backend, I get the correct local time in PST when calling date.ToLocalTime().
In summary, the takeaway points are:
Building a fully multitenant system using Microsoft Identity Framework and SQL Row Level Security
Analyzing a rental property through automation
Web scraping in C# using HtmlAgilityPack
Building multitenant application – Part 2: Storing value into database session context from ASP.NET core web API
Build and deploy a WebJob alongside web app using azure pipelines
Authenticate against azure ad using certificate in a client credentials flow
Notes on The Clean Architecture
Three essential libraries for unit testing a .NET project