Code dates and time like a Pro

code dates and times like a pro

Learning how to code dates and time like a pro means saving time and avoiding costly mistakes.

As a developer, one thing I found commonly tricky to handle is dealing with dates, and I’m not talking about the fruit of the palm nor courtship, but the best way to handle the interchange of dates between systems.

We can talk about a mobile application saving events locally to be later synchronized with the back-end, or the back-end serving a list of events and their expiration to a website. There is always a way to mess things up if you don’t take the necessary precautions to handle dates in a proper manner.

Any developer should know that 99% of the time someone else already had the same problem you are having, and there is no point in trying to reinvent the wheel if you are having any issue of compatibility between systems the answer is almost always the same: there is a standard you should be following.

ISO 8601

ISO 8601, as Wikipedia reads, “is an international standard covering the exchange of date and time-related data.” It sounds like an answer to my prayers! But wait, not so fast…

There is another important concept that is really useful to be familiarized with in order to handle dates like a pro: Timezones. Every single place on earth has its own timezone and living in a time where you can be developing from Mexico, for a client in Norway using servers in Ireland, can get tricky…

How do you handle dates and time in a way that timezone doesn’t matter, and you don’t make calculations in every single place? How can I avoid having to change the code if I move the server to a different timezone? Again, standards.

UTC

UTC (Coordinated Universal Time) is the standard for date and time, the difference between UTC and GMT (Greenwich Mean Time) is that UTC is the standard universal time and GMT is actually a timezone that happens to match UTC. None of them is affected by DST (Daylight Saving Time).

The Solution: Code dates & time like a pro
So, knowing these 2 things, the best way to handle dates is the following:

No matter where the event happens, you save it using the time in UTC.
If you need to interchange that value between different systems, no matter how many times you send or receive a date, you use the standard ISO 8601 format for the representation of the same UTC date (2019-12-31T23:59:59Z).
Only when displaying that date to a user, you transform that date to the user’s local Timezone.
Sounds easy, right? It is. This way, you don’t need to do calculations if your database is in a different timezone, or if the user might get the date from a different timezone, you only “transform” the date once to save and another time whenever you display to a user. Now let’s see how this looks in code.

MySQL

To Insert into a DATETIME field, use the function STR_TO_DATE using the format string:

'%Y-%m-%dT%H:%i:%sZ'

To read from a DATETIME field, use the function DATE_FORMAT using the same format string.

If you are using any database abstraction layer or language driver to communicate to the database (ODBC, PDO, custom interface, etc…), this code will change depending on it, but there should always be an equivalent to these functions in your language of choice.

MongoDB

Since the MongoDB console is actually a JavaScript interface, I will skip this and explain it on the JavaScript / node.js code section.

IOS

I won’t try to explain this code since iOS is out of my expertise, these code snippets are courtesy of Guillermo Garcia, Inmediatum’s Top Tier iOS Developer, if you have any question about this code, you can leave a comment and I will see that he gets it.

extension ISO8601DateFormatter {
convenience init(_ formatOptions: Options, timeZone: TimeZone = TimeZone(secondsFromGMT: 0)!) {
self.init()
self.formatOptions = formatOptions
self.timeZone = timeZone
}
}
extension Formatter {
static let iso8601 = ISO8601DateFormatter([.withInternetDateTime, .withFractionalSeconds])
}
extension Date {
var iso8601: String {
return Formatter.iso8601.string(from: self)
}
}
extension String {
var iso8601: Date? {
return Formatter.iso8601.date(from: self)
}
}
static func parseStringToFormatString(_ val :String) -> String? {
if let date = Formatter.iso8601.date(from: val) {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = “yyyy-MM-dd h:mm a”
dateFormatter.timeZone = TimeZone.current
let strDate2 = dateFormatter.string(from: date)
if let date = dateFormatter.date(from: strDate2) {
let myString = dateFormatter.string(from: date)
return myString
}
}
return nil
}
Android

As said before, there is no need to reinvent the wheel, for any and all your date-time Android needs there is Joda Time, and this simple snippet will take the value of iso8601_formatted, convert it to the device timezone and print using the template “MM/dd/yyyy hh:mma”.

DateTimeFormat
.forPattern("MM/dd/yyyy hh:mma")
.print(new LocalDateTime(
new DateTime(iso8601_formatted)
));
Node.js / Javascript

Another great library and a must for almost any JavaScript developer is moment.js. Moment allows you to do any date time calculation with ease, I strongly recommend checking the documentation for it.

moment().toISOString()

Returns the ISO8601 formatted string for the current time.

moment(iso8601_formatted).format("MM/dd/yyyy hh:mma")

Parses iso8601_formatted string and returns a formatted using the template “MM/dd/yyyy hh:mma”.

moment().toDate()

Returns the JavaScript Date object for the current date. Used when saving to MongoDB.

I hope you find some of the ideas here useful and please leave a comment if you think there is a better way, let’s start a conversation.

Write a comment