What’s wrong with my Date (Swift)

Pattaravadee Luamsomboon
Finnomena
Published in
4 min readJul 23, 2021

--

Hello world!!! Today, I will talk about Date object. Although, this object seems to be easy to use, I had faced a problem when I compared two dates which set for Bangkok time zone.

Let’s see what is the problem I faced and how to fix it.

First of all, I have a requirement to compare two dates that are exactly the same date. If it is difference, the point will be counted for 1 point. This process similar to when you play a game and it will give a point every login per day.

Guess what I did with my code.

For the first date(Today), I got a current date and converted it to date string with Bangkok time zone because I needed to set time zone to my date and converted my date string to date. I saved my first date to local memory by UserDefaults.

For the second date (Tomorrow), I still got a current date and converted it like the first date and got the first date from local memory. I used calendar for compare those.

Next, I will show you step by step in my code and mock first date and tomorrow’s date with timeIntervalSinceReferenceDate

Step 1: I created the first date with timeIntervalSinceReferenceDate

let date = Date(timeIntervalSinceReferenceDate: 0)
print(date)

the result: 2001–01–01 00:00:00 +0000

I have the first date. Then I need to set Bangkok time zone. I search the approach to set date with time zone and they show their code by convert date to date string and set time zone.

step 2: I converted my date to date string and set time zone with “Asia/Bangkok”

let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
dateFormatter.timeZone = TimeZone(identifier: "Asia/Bangkok")
let firstDateStr = dateFormatter.string(from: date)
print(firstDateStr)

the result: 2001–01–01T07:00:00.000+0700

Wow!!! everything looks good. I had a date with the correct time zone.

I had the first date(Today) and then I needed to mock tomorrow’s date with timeIntervalSinceReferenceDate. So my first date string was 2001–01–01 and time was 07.00 am. Then, I have to create tomorrow time and add 17 hours.

Step 3: I created my date and added 17 hours and converted it to date string.

let calendar = Calendar.current
let tomorrow = calendar.date(byAdding: .hour, value: 17, to: currentDate!)!
let tomorrowDateStr = dateFormatter.string(from: date)
print(tomorrowDateStr)

the result: 2001–01–02T07:00:00.000+0700

🤩🤩🤩 Now I had tomorrow’s date and I needed to compare two dates follow a requirement.

Oh wait! I cannot use date string. I need to use calendar to compare the same date with compare(_:to:toGranularity:) function and this func requires date object so I need to convert my date string to date object

Step 4: Convert first date string and tomorrow’s date string to date object

let firstDate = dateFormatter.date(from: firstDateStr)!
let tomorrowWithTimezone = dateFormatter.date(from: firstDateStr)!
let isSameDate = calendar.isDate(firstDate, equalTo: tomorrowWithTimezone, toGranularity: .day)
print(isSameDate)

the result: true

What? Wait. What happen? What’s wrong with my first date and the tomorrow’s date. Why those are the same date?

I tried to find out what’s wrong with my date and I found the answer from someone said when you convert string to date, time zone will be always to UTC.

In my head, “Stupid dog(date)! You make me look bad!”, this quote from cartoon network. 😂😂😂

And how I can fix it? Let’s see the solution.

Now, I knew If I convert my date string to date object, it will be always to UTC even time zone in date string was converted. I knew that I must use calendar to compare two dates. So I think, I used my date and set Bangkok time zone to calendar and compared them. Let’s see my final code.

let date = Date(timeIntervalSinceReferenceDate: 0)
var calendar = Calendar.current
let tomorrow = calendar.date(byAdding: .hour, value: 17, to: date)!
calendar.timeZone = TimeZone(identifier: "Asia/Bangkok") ?? .current
let isSameDate = calendar.isDate(date, equalTo: tomorrow, toGranularity: .day)
print(isSameDate)

the result: false

Keep in mind:

  • When you get date, time zone will be always UTC.
  • When you convert date from date string, time zone will be always UTC.
  • If you need to compare date with time zone. You can use calendar and set your time zone to calendar.

Let’s play with date object/calendar and time zone. 💪🏻💪🏻💪🏻

I hope this blog will give the benefit for you guys. If you have any question, feel free to comment below. 🤗

--

--