3

I'm confused by this behaviour:

let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss zzz"
let result = dateFormatter.date(from: "2017-04-12 12:12:12 GMT+1")!

2017-04-12 11:12:12 UTC

Why is the result automatically converted to UTC? How can I get the same timezone?

Leo Dabus
  • 229,809
  • 59
  • 489
  • 571
Houman
  • 64,245
  • 87
  • 278
  • 460
  • Dealing with one standardized system (such az the Unix time stamp, or UTC time) makes dealing with this data MUUUUUUCH easier. What would you expect to happen when you compare two `Date` instances which express the same point in time, but in different time zones? – Alexander Apr 21 '17 at 22:08
  • Yes, it makes sense. But how do I achieve that above? – Houman Apr 21 '17 at 22:21
  • 1
    Think of it like this: `Date` is a datatype that represents a moment in time. It doesn't know anything about time zones, days, months, years, etc. Whether you wish to express a moment in time with the Gregorian calendar in GMT+1, or in the Chinese calendar, the `Date` representing them both is the same. It's the job of other `DateFormatter` and other structs like it (e.g. `Calendar`, `DateComponents`) to take your `Date` and convert it to a human representation, in accordance to some set of rules (specified by the calendar system). – Alexander Apr 21 '17 at 22:33
  • This is exactly like how `Int` stores a magnitude: a point on the number line. It has no concept of binary, octal, decimal, hexadecimal, or any other number system you can think of. It's the job of the `String.init(_:radix:)` initializer to take an `Int` value, and generate a string representation for it for the given `radix`. – Alexander Apr 21 '17 at 22:34
  • 1
    Exactly, a *date* has no timezone. It's the *string representation* of a date that has a time zone. When printing, the date is converted to a string using a date formatter and that date formatter is set to UTC. – Sulthan Apr 21 '17 at 22:38
  • Related http://stackoverflow.com/questions/5214947/does-nsdate-date-return-the-local-date-and-time and many many others. – Sulthan Apr 21 '17 at 22:40
  • The title of this question is wrong. `DateFormatter.date` does not return UTC. It's the printing of a `Date` (obtained through any means) that shows UTC. – rmaddy Apr 22 '17 at 00:24

1 Answers1

2

Date objects encapsulate a single point in time, independent of any particular calendrical system or time zone. Date objects are immutable, representing an invariant time interval relative to an absolute reference date.

It's a kind of international standard to have it UTC formatted on default output. Most of the systems/languages in all the other environments also handle the time by this default data type.

You can change the format on input/ouput for your purpose.

let dateString = "Thu, 22 Apr 2017 00:28:17 +0000"
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "EEE, dd MMM yyyy hh:mm:ss +zzzz"
dateFormatter.locale = Locale.init(identifier: "en_GB")
let dateObj = dateFormatter.date(from: dateString)
dateFormatter.dateFormat = "dd-MM-yyyy"
print("Dateobj: \(dateFormatter.string(from: dateObj!))")
Felix Haeberle
  • 1,530
  • 12
  • 19
  • Thanks. This isn't swift3 code, but even after converting it, it won't work. `TimeZone.current.identifier` is already `Europe/London` – Houman Apr 21 '17 at 22:20
  • 1
    This answer isn't really correct. `Date` is simply a representation of a point in time. That's it. It is not UTC. The UTC doesn't come into play until the `Date` is converted to a `String`. By default, the `description` or `debugDescription` of `Date` is simply the conversion of the `Date` to a String and the string happens to be shown with the UTC timezone. – rmaddy Apr 22 '17 at 00:26