2

I want to get a today date without a time, so I can use it to compare with other Date objects that I am getting from API.

Here is my code:

var today = Date()
let gregorian = Calendar(identifier: .gregorian)
var components = gregorian.dateComponents([.timeZone, .year, .month, .day, .hour, .minute,.second], from: today)

components.hour = 0
components.minute = 0
components.second = 0

today = gregorian.date(from: components)!

But I have a strange problem with timezones. Today is for example 16/09/17, but at the end today would be equal to

2017-09-15 23:00:00 UTC

The only way to fix it is actually to specify my time zone as GMT.

components.timeZone = NSTimeZone(name: "GMT")! as TimeZone

Then the result would be correct one.

2017-09-16 00:00:00 UTC

Why you need to specify the timezone, as it is already should be set up by dateComponents or what I am doing wrong.
Before setting my own timezone it is equal to NSTimeZone "Europe/London"

andrii
  • 727
  • 3
  • 9
  • 21
  • You don't specify the `TimeZone` in `components`, so the setting of the calendar is used as default. Also, `NSTimeZone(name: "GMT")! as TimeZone` makes no sense, just use `TimeZone(abbreviation: "GMT")` – Dávid Pásztor Sep 16 '17 at 15:45
  • David, thank you. But timeZone is already specified by dateComponents function. It is actually not nil. It is equial to NSTimeZone "Europe/London". So I am still not clear what is the problem... – andrii Sep 16 '17 at 15:49
  • 1
    Your original code works just fine. Your only confusion is interpreting the output of logging a `Date` object. BTW - you are not creating a date with no time. You are creating a date set to midnight, local time (in your first set of code). Or midnight GMT time when you set the timezone to GMT. – rmaddy Sep 16 '17 at 15:59
  • @rmaddy are you sure this is the same as that question? I think the confusion here is coming from the fact that the UK is currently using British Summer Time, which is actually GMT+1 and not GMT. – Dávid Pásztor Sep 16 '17 at 16:03
  • @DávidPásztor I believe you meant to reply to MartinR, not me. And no, the only confusion here is the misunderstanding of how dates work and print. – rmaddy Sep 16 '17 at 16:05
  • @DávidPásztor: I agree with rmaddy's comments and am fairly sure that this is the same problem (which comes up regularly). If that should turn out to be wrong then I'll reopen the question. – Martin R Sep 16 '17 at 16:10
  • Helpful func TimeZone.knownTimeZoneIdentifiers - return all timezones. – WINSergey Sep 20 '21 at 14:29

1 Answers1

5

The time zone "Europe/London" corresponds to "BST" at the moment, which is British Summer Time, which is GMT+1, hence the issue you are seeing.

You can see this when using a DateFormatter with its timeStyle set to .full.

let df = DateFormatter()
df.timeZone = TimeZone(identifier: "Europe/London")
df.dateStyle = .medium
df.timeStyle = .full
print(df.string(from: Date())) // "Sep 16, 2017, 4:56:55 PM British Summer Time"
df.timeZone = TimeZone.current //I am actually in London, so this will be the same as explicitly setting it to Europe/London
print(df.string(from: Date())) // "Sep 16, 2017, 4:56:55 PM British Summer Time"
df.timeZone = TimeZone(abbreviation: "UTC")
print(df.string(from: Date())) // "Sep 16, 2017, 3:56:55 PM GMT"
Dávid Pásztor
  • 51,403
  • 9
  • 85
  • 116