Henrik
Henrik

Reputation: 4034

Converting NSDate from UTC to local gives wrong result

I am creating an NSDate from components of hour and minute. It is in GMT and prints correctly as:

0001-01-01 07:30:00 +0000

I then want to convert this to my local timezone (CET), so I set up the NSDateFormatter like so:

formatter.timeZone = NSTimeZone.localTimeZone()

This prints (using .Longstyle):

08.13.00 GMT+0.43

This is wrong—it is supposed to be GMT+1. Printing the .localTimeZone() gives the correct offset:

Local Time Zone (Europe/Oslo (CET) offset 3600)

Edit1: By adding this extension(from an answer linked in comments) to NSDate, I can offset the timezone by hand. But then I need to set the NSDateFormatter timezone to GMT, which I don't think is right.

extension NSDate {
  func toLocalTime() -> NSDate {    
    let timeZone = NSTimeZone.localTimeZone()
    let seconds : NSTimeInterval = Double(timeZone.secondsFromGMTForDate(self))      
    let localDate = NSDate(timeInterval: seconds, sinceDate: self)
    return localDate
  }
}

Edit2: I made a test project. The expected output is for the time printed to match the offset in the timezone. Instead it adds 43 minutes.

func applicationDidFinishLaunching(aNotification: NSNotification) {
    let calendar = NSCalendar.currentCalendar()
    let realDateComponents = calendar.components([.Hour, .Minute], fromDate: NSDate())
    guard let realDate = calendar.dateFromComponents(realDateComponents)
        else{fatalError("Unable to get real date.")}
    let formatter = NSDateFormatter()
    formatter.timeStyle = .ShortStyle

    print(realDate)
    print(formatter.stringFromDate(realDate))
    print(NSTimeZone.localTimeZone())
}

// OUTPUT
0001-01-01 21:03:00 +0000
21.46
Local Time Zone (Europe/Oslo (CET) offset 3600)

Upvotes: 0

Views: 622

Answers (1)

vadian
vadian

Reputation: 285069

NSDate 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 (00:00:00 UTC on 1 January 2001).

Apparently you're creating the date from the .Hour and .Minute components, that sets the (indeterminate) year information to 01 (not 2001).

The point in time about 2000 years ago is a pretty large time interval which probably causes the weird behavior.

Upvotes: 1

Related Questions