DateKit

Swift gave to developers great opportunity to learn new stuff. It was, and I believe still is, a refreshing breeze to programmers’ life. There’s also a great reason to show off – quickly learn the newest technology and prove your skills by releasing some great project. A lot of developers did that and it’s really great. Today I would like to present my attempt to simplify operations on NSDate and its components – DateKit.

Motivation

Everyone who worked with NSDateComponents knows how verbose it can be. Changing a single component involves an instance of NSCalendar, than an instance of NSDateComponents, then changing the component and finally you can get the result NSDate. It takes at least 3 lines of code that have to be written. It’s a bit disgusting. It makes mess in your code causing it hard to read and maintain in the future.

The idea behind DateKit was to encapsulate that operations in a single line of code. One line of code to modify components like seconds, minutes and hour should not be a problem. Comparing number of seconds or checking if only days of two dates are same should be very simple. I believe I achieved quite nice result. Keep on reading!

Features

Below you can find some cheat-sheet for DateKit. Every feature is presented in playground, so you can interact with it.

Modifying date components

You can modify one component at time:

  today.year(1989).date

or use chaining and change several in one line:

  today.year(1989).month(12).day(30).date

Dates comparison

Compare dates using operators:

  today < tomorrow    // true
today <= tomorrow   // true
today > tomorrow    // false
today >= tomorrow   // false
today == tomorrow   // false

or it’s components (compares Int values, so it doesn’t check if you compare same compoments):

  today.minute == tomorrow.minute

or you can compare by chosen components like this:

  today.compare(toDate: tomorrow, byUnits: [.CalendarUnitMonth, .CalendarUnitYear])

compare(toDate:,byUnits:default) has default argument byUnit: which is [.CalendarUnitDay,.CalendarUnitMonth,.CalendarUnitYear] . This method returns NSComparisonResult , however you can determine bool value with shorthand methods like this:

  today.compare(toDate: tomorrow, byUnits: [.CalendarUnitHour, .CalendarUnitYear]).same    // false
 
today.compare(toDate: tomorrow, byUnits: [.CalendarUnitHour, .CalendarUnitYear]).ascending    // true
 
today.compare(toDate: tomorrow, byUnits: [.CalendarUnitHour, .CalendarUnitYear]).descending    // false
 
today.compare(toDate: tomorrow).notSame    // true

Create new date by adding/substracting value to only one component

Get date from current date by changing one component with operators:

  today.minutes + 13
today.seconds - 4
today.hours + 1
today.days - 1

Create new date by adding/substracting values to several components (chaining)

Here’s an example of chaining:

  today.days.add(1).months.substract(1).hour(12).minute(30).date

Functions add(Int) and substract(Int) works like +/- math operators.

Helpers

I’ve added also some helpers. These are self-explaining:

  today.midnight
today.noon
today.tomorrow
today.yesterday

Get the first and last unit in component:

  today.months.first  // returns same date but with January
today.months.last   // returns same date but with December
today.minutes.first // returns same date but with 0 minutes

Since today it’s January this code:

  today.months.add(1).days.last

will return date with last day of February – 28th. If you want to get day itself, just add day at the end of chain:

  today.months.add(1).days.last.day

It’s pretty simple, isn’t it?

Under the hood

There is no surprise under the hood – every operation is being made using NSCalendar instance and NSDateComponents . To achieve chaining I’ve introduced Operation object, which keeps date and NSCalendarUnit . If you create a chain, remember to return result date by adding date word at the end.

Summary

I hope DateKit will improve your work with dates. We are open for pull request with new features as well as bug reports. Code is available on Github. Happy operating on dates!

PS: I’m planning to add some new stuff to DateKit in the future, so contact me if you have any requests!