-1

I'm trying to find the first day of the month. There have been different solutions posted here on SO (e.g. this)

When analyzing them it seems like the day component is being ignored.
Instead of returning the first day of the month

Calendar.current.date(from: Calendar.current.dateComponents([.year, .month], from: Calendar.current.startOfDay(for: self)))!

it returns the current day but changes the month:

(lldb) po Calendar.current.date(from: Calendar.current.dateComponents([.year, .month], from: Calendar.current.startOfDay(for: self)))!
▿ 2019-02-28 23:00:00 +0000
  - timeIntervalSinceReferenceDate : 573087600.0

(lldb) po self
▿ 2019-03-28 01:09:17 +0000
  - timeIntervalSinceReferenceDate : 575428157.663583

I've also looked into setting the components by hand:

var components = Calendar.current.dateComponents([.year, .month, .day], from: self)
components.setValue(1, for: .day)
let value = Calendar.current.date(from: components)!

which results in the same:

(lldb) po value
▿ 2019-02-28 23:00:00 +0000
  - timeIntervalSinceReferenceDate : 573087600.0

Am I doing something wrong? Or is this a bug in Calendar?

Apple Swift version 5.0.1 (swiftlang-1001.0.82.4 clang-1001.0.46.5)
Target: x86_64-apple-darwin18.6.0

Oh in case this is interesting I'm developing for macOS but as far as I can see, this API is not influenced by Catalina.

Jan
  • 1,827
  • 2
  • 16
  • 29

1 Answers1

1

Your code is fine. You have a date that is in March 2019. You create a new date that is March 1, 2019 at midnight local time. All good so far.

The only issue is your misunderstanding of the output of printing that date. The date is printed in the debugger in UTC time. That's what the +0000 means - UTC time. You must live in the UTC+1 timezone.

So March 1, 2019 at midnight your local time is the same as February 28, 2019 at 23:00 UTC. It's the same moment in time, just displayed in a different timezone.

In short, your code is fine.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
  • 1
    Thanks for the reply. it does make sense. What made me stumble upon it was calculating the last day of the month April. The code above resulted in 2019-03-31 22:00:00, which makes sense after your explaination. The last day calculated by code in the link provided above results in: 2019-04-28 00:30:35 +0000. Which I cannot derive from the timezone as it's no where near the 30th. Is this also an error in my understanding? – Jan Jul 28 '19 at 00:36
  • 1
    Same thing. You start with a day in April. You calculate April 1 at midnight local time. That's the same as March 31 at 22:00 UTC time. It's now 2 hours different due to daylight saving time. – rmaddy Jul 28 '19 at 00:41
  • 1
    I agree March 31rst makes totally sense. Just the last day as 28th is odd. – Jan Jul 28 '19 at 00:44