Brian Coleman

  • Home
  • ABOUT
  • SERVICES
  • PORTFOLIO
  • BLOG
  • Contact

Tutorial: NSDate in Swift

NSDate objects represent a single point in time. NSDate is a class cluster; its single public superclass, NSDate, declares the programmatic interface for specific and relative time values. The objects you create using NSDate are referred to as date objects.

NSDate is an abstract class that provides behavior for creating dates, comparing dates, representing dates, computing intervals, and similar functionality. NSDate presents a programmatic interface through which suitable date objects are requested and returned. Date objects returned from NSDate are lightweight and immutable since they represent an invariant point in time.

Using NSDate

In objective-c, the following code results in the UTC date time information using the date API.

NSDate *currentUTCDate = [NSDate date]

In Swift however,

let date = NSDate()

Results in local date and time.

UTC vs Local Time

NSDate is a specific point in time without a time zone. Think of it as the number of seconds that have passed since a reference date. How many seconds have passed in one time zone vs. another since a particular reference date? The answer is the same.

Depending on how you output that date (including looking at the debugger), you may get an answer in a different time zone.

If they ran at the same moment, the values of these are the same. They’re both the number of seconds since the reference date, which may be formatted on output to UTC or local time. Within the date variable, they’re both UTC.

To explain this, we can use a NSDateFormatter in a playground:

import UIKit

let date = NSDate();
// "Apr 1, 2015, 8:53 AM" <-- local without seconds

var formatter = NSDateFormatter();
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss ZZZ";
let defaultTimeZoneStr = formatter.stringFromDate(date);
// "2015-04-01 08:52:00 -0400" <-- same date, local, but with seconds
formatter.timeZone = NSTimeZone(abbreviation: "UTC");
let utcTimeZoneStr = formatter.stringFromDate(date);
// "2015-04-01 12:52:00 +0000" <-- same date, now in UTC

Compare NSDate

If you need to compare two dates, you can use the method below. This example shows comparing the current date against an endDate. It will give you all possible results so you can handle each situation.

// Date comparision to compare current date and end date.
var dateComparisionResult:NSComparisonResult = NSDate().compare(endDate)

if dateComparisionResult == NSComparisonResult.OrderedAscending
{
    // Current date is smaller than end date.
}
else if dateComparisionResult == NSComparisonResult.OrderedDescending
{
    // Current date is greater than end date.
}
else if dateComparisionResult == NSComparisonResult.OrderedSame
{
    // Current date and end date are same.
}

There are several useful methods in NSCalendar in iOS 8.0+:

startOfDayForDate, isDateInToday, isDateInYesterday, isDateInTomorrow

And even to compare days:

func isDate(date1: NSDate!, inSameDayAsDate date2: NSDate!) -> Bool

To ignore the time element you can use this:

var toDay = NSCalendar.currentCalendar().startOfDayForDate(NSDate())

Formatting NSDate

If you have a string and want to convert it to an NSDate.

var dataString = "April 1, 2015" as String
var dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "MM-dd-yyyy"
dateFormatter.timeZone = NSTimeZone.localTimeZone()

// convert string into date
let dateValue = dateFormatter.dateFromString(dataString) as NSDate!

println(dateValue)

This might help you also formatting your dates:
Sg0tZ

Convert Unix TimeStamp to NSDate in Swift

If you have a timestamp "/Date(1427909016000-0800)" and you need to convert it to an NSDate, you can use the following extension. This will also convert it to your local time. The first part "1427909016000" is the time since the Unix epoch in milliseconds, and the second part "-0800" is a time zone specification.

extension NSDate {
    convenience init?(jsonDate: String) {
        let prefix = "/Date("
        let suffix = ")/"
        let scanner = NSScanner(string: jsonDate)
        
        // Check prefix:
        if scanner.scanString(prefix, intoString: nil) {
            
            // Read milliseconds part:
            var milliseconds : Int64 = 0
            if scanner.scanLongLong(&milliseconds) {
                // Milliseconds to seconds:
                var timeStamp = NSTimeInterval(milliseconds)/1000.0
                
                // Read optional timezone part:
                var timeZoneOffset : Int = 0
                if scanner.scanInteger(&timeZoneOffset) {
                    let hours = timeZoneOffset / 100
                    let minutes = timeZoneOffset % 100
                    // Adjust timestamp according to timezone:
                    timeStamp += NSTimeInterval(3600 * hours + 60 * minutes)
                }
                
                // Check suffix:
                if scanner.scanString(suffix, intoString: nil) {
                    // Success! Create NSDate and return.
                    self.init(timeIntervalSince1970: timeStamp)
                    return
                }
            }
        }
        
        // Wrong format, return nil. (The compiler requires us to
        // do an initialization first.)
        self.init(timeIntervalSince1970: 0)
        return nil
    }
}

Here's an example of it in use:

if let theDate = NSDate(jsonDate: "/Date(1427909016000-0800)/")
{
    println(theDate)
}
else
{
    println("wrong format")
}

Result

2015-04-01 09:23:36 +0000
Tutorial: How To Share in Facebook SDK 4.1.x for SwiftTutorial: Upgrading to Swift 1.2
Brian Coleman

Manager, Mobile Development at Rogers Communications with over 15 years of multifaceted experience including development, design, business analysis and project management working directly with clients in a consulting capacity throughout the full software life cycle.

April 1, 2015 Swift, Tutorialsios8, swift, tutorial
Follow Me
    
Categories
  • About Me
  • Frameworks
  • My Apps
  • News
  • Strategy
  • Swift
  • Tools
  • Tutorials
  • tvOS
  • Uncategorized
  • Videos
  • Watch
Archives
  • May 2016
  • January 2016
  • October 2015
  • July 2015
  • May 2015
  • April 2015
  • March 2015
  • November 2014
  • October 2014
  • September 2014
  • July 2014
  • June 2014
  • September 2013
  • August 2013
  • July 2013
  • June 2013
  • May 2013
  • April 2013
  • March 2013
  • February 2013
Recent Posts
  • Classix for iPhone, iPad & Apple TV
  • Tutorial: How to test your app for IPv6 compatibility
  • Tutorial: Testing SSL using Charles Proxy on an iOS Device
  • Tutorial: 3D Touch – Quick Actions in Swift
  • tvOS Tutorial: Top Shelf in Swift
Featured Apps
Classix
Sportsnet
TAGS
tutorialswiftios8iosobjective-cvideogamesstrategynewsframeworkappsmonitizefacebookwatchappleios7toolstvosios9apiprovisionsocialtutorialsbooksdesignbookiapIPv6iTunes Connect
Search
TAGS
tutorialswiftios8iosobjective-cvideogamesstrategynewsframeworkappsmonitizefacebookwatchappleios7toolstvosios9apiprovisionsocialtutorialsbooksdesignbookiapIPv6iTunes Connect
ABOUT
Brian is a Lead iOS/tvOS Developer from Toronto with over 18 years of multifaceted experience including development, design, business analysis and project management.

FOLLOW ME
    
Email Subscription
Sign up for my newsletter to receive the latest news and tutorials posted.

Enter your email address:

2023 © Brian Coleman