Swift
NSDate
date calculation
iOS development
Swift programming

Swift days between two NSDates

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

Calculating day differences in Swift sounds simple until time zones, daylight saving transitions, and time-of-day differences enter the picture. The right approach depends on whether you need calendar days or exact 24-hour intervals. Most app features such as streaks and due dates should use calendar-based day calculations.

Date and NSDate Interoperability

Modern Swift uses Date, while NSDate appears in older Objective C APIs. They bridge automatically, so you can convert without manual parsing.

swift
1import Foundation
2
3let oldApiDate: NSDate = NSDate()
4let swiftDate: Date = oldApiDate as Date
5let backToObjC: NSDate = swiftDate as NSDate
6
7print(swiftDate)
8print(backToObjC)

For new code, store values as Date and only bridge when needed for legacy interfaces.

Calendar-Day Difference

To get the number of day boundaries crossed, use Calendar.dateComponents with .day after normalizing both dates to the start of day.

swift
1import Foundation
2
3func daysBetweenCalendarDays(from start: Date, to end: Date, calendar: Calendar = .current) -> Int {
4    let startDay = calendar.startOfDay(for: start)
5    let endDay = calendar.startOfDay(for: end)
6    return calendar.dateComponents([.day], from: startDay, to: endDay).day ?? 0
7}
8
9let formatter = ISO8601DateFormatter()
10let d1 = formatter.date(from: "2026-03-01T23:30:00Z")!
11let d2 = formatter.date(from: "2026-03-04T01:00:00Z")!
12
13print(daysBetweenCalendarDays(from: d1, to: d2))

This method is stable for user-facing calendar logic.

Exact Duration in 24-Hour Blocks

If you need elapsed time in full 24-hour periods, use timeIntervalSince and divide by seconds per day.

swift
1import Foundation
2
3func full24HourBlocks(from start: Date, to end: Date) -> Int {
4    let seconds = end.timeIntervalSince(start)
5    return Int(seconds / 86_400)
6}
7
8let start = Date(timeIntervalSince1970: 0)
9let end = Date(timeIntervalSince1970: 200_000)
10print(full24HourBlocks(from: start, to: end))

This is precise for duration math but may differ from calendar day counts.

Time Zone-Aware Calculations

Date results can change by locale and selected calendar. If your business rule uses a specific zone, configure calendar explicitly.

swift
1import Foundation
2
3var calendar = Calendar(identifier: .gregorian)
4calendar.timeZone = TimeZone(identifier: "America/Toronto")!
5
6let formatter = DateFormatter()
7formatter.dateFormat = "yyyy-MM-dd HH:mm"
8formatter.timeZone = calendar.timeZone
9
10let start = formatter.date(from: "2026-03-08 00:30")!
11let end = formatter.date(from: "2026-03-09 00:30")!
12
13let days = calendar.dateComponents([.day], from: calendar.startOfDay(for: start), to: calendar.startOfDay(for: end)).day!
14print(days)

Locking a time zone is critical for billing, compliance, and region-specific reporting.

Utility for NSDate Inputs

If an API still provides NSDate, wrap conversion in a helper to keep call sites clean.

swift
1import Foundation
2
3func daysBetween(_ a: NSDate, _ b: NSDate, calendar: Calendar = .current) -> Int {
4    let start = a as Date
5    let end = b as Date
6    let startDay = calendar.startOfDay(for: start)
7    let endDay = calendar.startOfDay(for: end)
8    return calendar.dateComponents([.day], from: startDay, to: endDay).day ?? 0
9}
10
11let a = NSDate(timeIntervalSinceNow: -3 * 24 * 60 * 60)
12let b = NSDate()
13print(daysBetween(a, b))

This keeps compatibility layers isolated while promoting Date for core logic.

Testing Date Logic

Date math should include tests for boundary conditions:

  • Same calendar day with different times.
  • Daylight saving start and end transitions.
  • Cross-year transitions.
  • Negative intervals where end is before start.

Deterministic tests should set a fixed Calendar, TimeZone, and parsing format so CI results are stable.

Common Pitfalls

  • Subtracting raw timestamps when the requirement is calendar days. Fix by using start-of-day normalization.
  • Using current locale defaults in business-critical calculations. Fix by configuring calendar and time zone explicitly.
  • Mixing NSDate and Date conversions across many call sites. Fix by centralizing conversion helpers.
  • Ignoring daylight saving boundaries. Fix by adding DST-focused unit tests.
  • Assuming day difference is always positive. Fix by supporting signed results when end precedes start.

Summary

  • Prefer Date for modern Swift and bridge to NSDate only when needed.
  • Use calendar-based math for user-facing day counts.
  • Use interval math for strict elapsed-time calculations.
  • Set explicit time zone and calendar where rules require consistency.
  • Cover DST and boundary cases with deterministic tests.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.