Coding Explorer Blog

Exploring how to code for iOS in Swift and Objective-C

  • Home
  • Apps
  • About
  • Contact

Date — Class Reference

Xcode 11.6 Swift 5.2.4

Last updated on August 12, 2020

An NSDate object specifies a particular point in time.  Despite “date” being in its name, it really stores time, of which the date is a component.  Under the hood, NSDates (as far as the public superclass we can see is concerned) are specified as a number of seconds past a reference date.  NSDate’s reference date is the first moment of January 1, 2001 in the GMT timezone.  These seconds are stored as a Double, which allows NSDate to range from milliseconds to years.  What we see as an NSDate is actually an abstract public superclass for a cluster of classes related to dates.  The internal classes are private, so talking about them here wouldn’t be particularly helpful, and it is probably best not to mess with them anyway.

Since Swift 3 though, most “NS” prefixes were removed from the Swift Standard Library, so now it is simply called “Date”.  If you need to save a timestamp for something in your iOS app, or maybe have a countdown timer for an app or game, you will be dealing with the Date class, so let’s take a look at it.

Creating an Date Object

The Date class itself has 6 initializers:  3 dedicated and 3  convenience ones.  One dedicated initializer deals with Coding and 4 of them deal with TimeInterval.  I personally only use one of the built in initializers to Date, and that is the one that takes no arguments.  This one creates n Date object specifying the exact moment it was called.  It is incredibly simple:

//Prototype:  init()
let now = Date()

That is all there is to it, now the “now” variable stores the exact moment this initializer was called.  I’ve used this in a few examples before to generate a simple class to test with.

I originally wrote this going through the other initializers that deal with TimeInterval, but decided to not include them.  TimeInterval is a typealias for a Double, and it specifies a certain number of seconds.  It has initializers for an TimeInterval since the reference date, since now, since the first moment of January 1, 1970 (the Unix epoch), and since any other Date object.

I don’t know about you, but I can’t really read a few million seconds and see that it is referring to this year.  Instead, if I need to specify a particular Date, I usually use DateComponents.  We will cover it a bit more in depth later, but for the moment, I will show a simple implementation of using this to create a certain Date:

let todayComponents = DateComponents(year: 2014, month: 11, day: 12)

if let todayDate = Calendar.current.date(from: todayComponents) {
    print(todayDate)
}

//Output: "2014-11-12 08:00:00 +0000"

The first part is pretty simple.  You make a DateComponents object, and then set the components you wish.

An DateComponents object lets you set the components, but it has very little meaning without the context given by a Calendar.  Different calendrical systems have different numbers of seconds for some of these components, particularly for the length of a year.  So, to create a Date, we call that dateFromComponents method of the Calendar class and pass in the todayComponents object we just made.  The actual object we are calling that from is is the return of Calendar’s currentCalendar class function.  This returns an object specifying the current calendar that the device is set to.  You can specify one if you wish, but it is usually easier (and in many situations better) to use the current one for that device.

The dateFromComponents method returns an optional Date, so we can use optional binding to make it into a standard Date.  It could return nil if it is unable to convert the components to a specific time for some reason.  If you set a component out of its normal bounds, it will usually roll over.  For instance, if you set the minutes component to 1, and the seconds component to 121 seconds, this will return something with the  will be interpreted as 2 minutes and one second, and just add to the already specified minute value, so resulting in 3 minutes and 1 second.  I am not sure when it is unable to actually generate an Date from components, but I know very little about other Calendars, so maybe it has more to do with the conversions or idiosyncrasies between how other calendars handle the components compared to the Gregorian calendar.  Nonetheless, this can return nil, so I would suggest either checking it against nil before force unwrapping, or just using Swift’s Optional Binding syntax when using this for your iOS apps.

Also, apparently this calculation uses the time zone for your computer, so that is the reason it returned 8 AM in the GMT timezone.  This computer’s time zone is the Pacific Timezone, which is -8 GMT, as such midnight here (as specified by not setting the hour, minute, second, etc components, corresponds to 8 AM GMT.  If we had also set the timezone explicitly as GMT in our DateComponents object, it would return a value with 0 hours with 0 hours offset.

Comparing Dates

Date comes with 4 instance methods to compare dates.  The first we will talk about is the most general, the compare method.  This method returns an ComparisonResult, which is an enumeration that says whether a date is before, same as, or after another date.  I’ve personally found ComparisonResult difficult to remember which way means what, but Apple provided a nice explanation, which I will paraphrase in tabular form below:

ComparisonResult  Meaning
orderedAscending Instance Date is earlier than anotherDate.
orderedSame Instance Date and anotherDate are equal.
orderedDescending Instance date is later than anotherDate.

Here is some code to test it in a Swift Playground:

let result = now.compare(hourFromNow)

if result == .orderedAscending {
    print("Earlier")
} else if result == .orderedDescending {
    print("Later")
}

//Outputs:  "Earlier"

Conclusion

The Date abstract class itself is a pretty simple interface.  It has some initializers, and basic comparisons between different Date classes, and that’s about it.

If you really want to get a lot of use out of it, you will need to work with a few different classes like DateComponents, Calendar, and DateFormatter.  I have covered DateFormatter a bit in Objective-C, but there will probably be a Swift version soon enough.  We’ll cover DateComponents a bit more in depth later, but I felt it was better to give some information about it now because it is a whole lot easier to create an Date object with DateFormatter than with an TimeInterval (at least if you have to work with more than a day’s worth of time anyway).

I hope you found this article helpful.  If you did, please don’t hesitate to share this post on Twitter or your social media of choice, every share helps.  Of course, if you have any questions, don’t hesitate to contact me on the Contact Page, or on Twitter @CodingExplorer, and I’ll see what I can do.  Thanks!

Sources

  • Date Class Reference — Apple Inc.

Filed Under: Uncategorized

Subscribe to the Coding Explorer Newsletter

* indicates required

Follow Us

Facebooktwitterrss

Recent Posts

  • Error Handling in Swift
  • Creating and Modifying a URL in your Swift App
  • Watch Connectivity in Swift — Application Context
  • watchOS Hello World App in Swift
  • API Availability Checking in Swift

Categories

  • Class Reference
  • General
  • Interface Builder
  • My Apps
  • Objective-C
  • Swift
  • Syntax
  • Tutorial
  • Uncategorized

Archives

  • May 2016
  • March 2016
  • February 2016
  • December 2015
  • July 2015
  • June 2015
  • April 2015
  • February 2015
  • January 2015
  • December 2014
  • November 2014
  • October 2014
  • September 2014
  • August 2014
  • July 2014
  • June 2014
  • May 2014
  • April 2014
  • March 2014
  • January 2014
  • November 2013
  • September 2013
  • August 2013
  • July 2013
  • Terms Of Use
  • Privacy Policy
  • Affiliate Disclaimer

Subscribe to the Coding Explorer Newsletter

* indicates required

Copyright © 2025 Wayne Media LLC · Powered by Genesis Framework · WordPress