JoakimE
JoakimE

Reputation: 1864

NSDate to string displays 1 hour more than it should

So I'm making a small app. I'm able to get the time from two UiDatePickers and get the time difference between them. I have a NSDate which have the right number and is correct. But when I'm using stringFromDate the time get's added with 1 hour.

Here's my code:

         //recieves 2 time values from UiDatePickers and returns a NSTimeInterval
        let time = timeEndValue!.timeIntervalSinceDate(timeStartValue!)

        let dateFormatter = NSDateFormatter()
        dateFormatter.dateFormat = "HH:mm"
        //Format NSTimeInterval to NSDate. date stores the correct value
        let date = NSDate(timeIntervalSinceReferenceDate: time)
        //The trouble starts here. Here the time get's one hour more than it should. 
        let dateString = dateFormatter.stringFromDate(date)

So...date which is an NSDate have the correct value. I checked it using an online tool, converting seconds to hours and minutes. But when I convert the date with stringFromdate(date) the output shows 1 hour extra than it should. And it does this every single time I have tested. My guess is that it has something to do with timezones that date is UTC 0 and my timezone is UTC+1 so when it converts using dateformatter.stringFromDate it adds 1 hour or something.

Any ideas guys?

Edit:

Rob suggested using NSDateComponentsFormatter and he was absolutely right. Here's the result:

let formatter = NSDateComponentsFormatter()
            formatter.allowedUnits = [.NSHourCalendarUnit, .NSMinuteCalendarUnit]
            formatter.unitsStyle = .Positional
            formatter.zeroFormattingBehavior = .Default
            stringV = formatter.stringFromDate(timeStartValue!, toDate: timeEndValue!)!

Upvotes: 3

Views: 886

Answers (2)

Gladwin
Gladwin

Reputation: 73

I had this problem as well but I simply solved it by setting the timezone on NSDateFormatter to 'UTC':

let time = time
let timeFormatter = NSDateFormatter()
timeFormatter.timeZone = NSTimeZone(name: "UTC")
timeFormatter.timeStyle = .ShortStyle

Upvotes: 1

Rob
Rob

Reputation: 437422

This is because stringFromDate thinks this is a time (not an elapsed time) and is showing it to you in your time zone. You could force the timezone to be UTC/GMT/Zulu or, better, use NSDateComponentsFormatter to show the amount of time between two dates. For example:

let formatter = NSDateComponentsFormatter()
formatter.allowedUnits = [.Hour, .Minute]
formatter.unitsStyle = .Positional

let string = formatter.stringFromDate(date1, toDate: date2)

The nice thing about NSDateComponentsFormatter is that it offers a plethora of other nice formatting features, such as other unitsStyle (e.g. .Full will produce a localized string), maximumUnitCount (if you have really long periods and would rather only show the most significant units), etc.

If you really need 00:00 zero-padded format, you could also manually extract the components and format it as desired:

let components = NSCalendar.currentCalendar().components([.Hour, .Minute], fromDate: date1, toDate: date2, options: [])
let string = String(format: "%02d:%02d", components.hour, components.minute)

Upvotes: 2

Related Questions