Search code examples
swiftnsdatenscalendar

Why does the result in Swift Playground differ from being executed in the app?


I have the following code in Playground:

import Cocoa

let date = NSDate()
let calendar = NSCalendar( calendarIdentifier:NSGregorianCalendar )
let components = calendar.components( NSCalendarUnit.YearCalendarUnit | NSCalendarUnit.MonthCalendarUnit | NSCalendarUnit.DayCalendarUnit, fromDate: date )

let dateStrippedOfTimeComponent:NSDate = calendar.dateFromComponents(components)

The result in Playgrounds is 5 Jul 2014 00:00 which is what I want

However the same code, when used in my viewController as part of a func gives the result 04 Jul 2014 23:00 and also the current NSDate() result comes up an hour earlier than it is showing my my mac. Could someone show me how to solve this problem? Much appreciated, Thanks.


Solution

  • It's merely a display issue. The two date objects are the exactly the same, but the playground and the app are using two different timezones when printing the result.

    NSDate is a pure representation of an instant in time.

    Whenever you need to display it, then you can decide the format, the locale, the timezone and other visualization-related information. As an example, you can run this in the playground:

    let date = NSDate()
    // "Jul 6, 2014, 11:43 AM" in my system timezone (Italy)
    
    let calendar = NSCalendar( calendarIdentifier:NSGregorianCalendar ) 
    let components = calendar.components( NSCalendarUnit.YearCalendarUnit | NSCalendarUnit.MonthCalendarUnit | NSCalendarUnit.DayCalendarUnit, fromDate: date )
    let dateStrippedOfTimeComponent = calendar.dateFromComponents(components)
    
    let dateFormatter = NSDateFormatter()
    dateFormatter.dateStyle = NSDateFormatterStyle.MediumStyle
    dateFormatter.timeStyle = NSDateFormatterStyle.MediumStyle
    
    dateFormatter.timeZone = NSTimeZone(abbreviation: "EST")
    let estDate = dateFormatter.stringFromDate(dateStrippedOfTimeComponent)
    // "Jul 5, 2014, 6:00:00 PM" in NYC
    
    dateFormatter.timeZone = NSTimeZone(abbreviation: "UTC")
    let utcDate = dateFormatter.stringFromDate(dateStrippedOfTimeComponent)
    // "Jul 5, 2014, 10:00:00 PM" in London