In this post, I’ll write about Calendar to get the date you want.

You can get the specific time and dates like midnight, noon, tomorrow, the start of this week, and more!

 

WeekDay

You can get a weekday from Calendar. I’ll use it to get the startOfThisWeek and beforeStartOfBiWeek.

enum CalendarWeekDay: Int {
    case sun = 1
    case mon
    case tue
    case wed
    case thu
    case fri
    case sat
}

extension CalendarWeekDay {
    func startOfWeek(_ weekDay: CalendarWeekDay = .sun) -> Int? {
        guard weekDay == .sun || weekDay == .mon else {
            return nil
        }
        if weekDay == .sun {
            return (self.rawValue - 1) * -1
        }
        else {
            switch self {
            case .sun:
                return -6
            default:
                return (self.rawValue - 2) * -1
            }
        }
    }

    var beforeStartOfBiWeek: Int {
        startOfWeek(.sun)! - 7
    }
}

 

Date

I set the start of the day to midnight(AM 00:00:00) and the end of the day to military time(PM 23:59:59).

extension Date {
    var startOfDay: Date {
        return Calendar.current.date(
        byAdding: .day, 
        value: 0, 
        to: midNight)!
    }

    var yesterday: Date {
        return Calendar.current.date(
        byAdding: .day, 
        value: -1, 
        to: midNight)!
    }

    var tomorrow: Date {
        return Calendar.current.date(
        byAdding: .day, 
        value: 1, 
        to: midNight)!
    }

    var dayAfterTomorrow: Date {
        return Calendar.current.date(
        byAdding: .day, 
        value: 2, to: midNight)!
    }

    var midNight: Date {
        Calendar.current.date(
        bySettingHour: 00, 
        minute: 0, 
        second: 0, 
        of: self)!
    }

    var militaryTime: Date {
        Calendar.current.date(
        bySettingHour: 23, 
        minute: 59, 
        second: 59, of: self)!
    }

    var noon: Date {
        Calendar.current.date(
        bySettingHour: 12, 
        minute: 0, 
        second: 0, 
        of: self)!
    }

    var month: Int {
        Calendar.current.component(.month,  from: self)
    }

    var isLastDayOfMonth: Bool {
        tomorrow.month != month
    }

    var startOfThisWeek: Date {
        let weekDay = CalendarWeekDay(
            rawValue: Calendar.current.component(.weekday, from: self)
        )!
        return Calendar.current.date(
            byAdding: .day,
            value: weekDay.startOfWeek(.sun)!,
            to: startOfDay)!
    }

    var beforeStartOfBiWeek: Date {
        let weekDay = CalendarWeekDay(
            rawValue: Calendar.current.component(
            .weekday, 
            from: self)
        )!
        return Calendar.current.date(
        byAdding: .day, 
        value: weekDay.beforeStartOfBiWeek, 
        to: startOfDay)!
    }

    var startOfMonth: Date {
        return Calendar.current.date(
            from: Calendar.current.dateComponents(
                [.year, .month],
                from: Calendar.current.startOfDay(for: self)
            ))!
    }

    var endOfMonth: Date {
        return Calendar.current.date(
            byAdding: DateComponents(month: 1, day: -1),
            to: startOfMonth.militaryTime
        )!
    }
}

All done! Let’s make a test code.

The default timeZone is UTC. I recommend setting your timeZone before checking test results.

import XCTest
@testable import CalendarSample

fileprivate var dateformatter: DateFormatter {
    let formatter = DateFormatter()
    formatter.dateFormat = "yyyy.MM.dd ahh:mm"
    formatter.locale = Locale(identifier: "en_KR")
    formatter.calendar = Calendar.current
    return formatter
}
class CalendarTests: XCTestCase {
    func test_start_of_week_and_biweek() {
        let sunday = dateformatter.date(from: "2020.07.12 AM00:00")!
        let monday = dateformatter.date(from: "2020.07.13 AM00:00")!
        let tuesday = dateformatter.date(from: "2020.07.14 AM00:00")!
        let wednesday = dateformatter.date(from: "2020.07.15 AM00:00")!
        let thursday = dateformatter.date(from: "2020.07.16 AM00:00")!
        let friday = dateformatter.date(from: "2020.07.17 AM00:00")!
        let saturday = dateformatter.date(from: "2020.07.18 AM00:00")!

        XCTAssertEqual(sunday.startOfThisWeek.KST, "2020.07.12 AM12:00")
        XCTAssertEqual(sunday.beforeStartOfBiWeek.KST, "2020.07.05 AM12:00")

        XCTAssertEqual(monday.startOfThisWeek.KST, "2020.07.12 AM12:00")
        XCTAssertEqual(monday.beforeStartOfBiWeek.KST, "2020.07.05 AM12:00")

        XCTAssertEqual(tuesday.startOfThisWeek.KST, "2020.07.12 AM12:00")
        XCTAssertEqual(tuesday.beforeStartOfBiWeek.KST, "2020.07.05 AM12:00")

        XCTAssertEqual(wednesday.startOfThisWeek.KST, "2020.07.12 AM12:00")
        XCTAssertEqual(wednesday.beforeStartOfBiWeek.KST, "2020.07.05 AM12:00")

        XCTAssertEqual(thursday.startOfThisWeek.KST, "2020.07.12 AM12:00")
        XCTAssertEqual(thursday.beforeStartOfBiWeek.KST, "2020.07.05 AM12:00")

        XCTAssertEqual(friday.startOfThisWeek.KST, "2020.07.12 AM12:00")
        XCTAssertEqual(friday.beforeStartOfBiWeek.KST, "2020.07.05 AM12:00")

        XCTAssertEqual(saturday.startOfThisWeek.KST, "2020.07.12 AM12:00")
        XCTAssertEqual(saturday.beforeStartOfBiWeek.KST, "2020.07.05 AM12:00")
    }

    func test_get_specific_from_date() {
        let sunday = dateformatter.date(from: "2020.07.12 AM00:00")!

        XCTAssertEqual(sunday.midNight.KST, "2020.07.12 AM12:00")
        XCTAssertEqual(sunday.noon.KST, "2020.07.12 PM12:00")
        XCTAssertEqual(sunday.militaryTime.KST, "2020.07.12 PM11:59")

        XCTAssertEqual(sunday.yesterday.KST, "2020.07.11 AM12:00")
        XCTAssertEqual(sunday.tomorrow.KST, "2020.07.13 AM12:00")
        XCTAssertEqual(sunday.dayAfterTomorrow.KST, "2020.07.14 AM12:00")
    }

    func test_check_month_from_date() {
        let sunday = dateformatter.date(from: "2020.07.12 AM00:00")!
        let lastDayOnJuly = dateformatter.date(from: "2020.07.31 AM00:00")!

        XCTAssertEqual(sunday.startOfMonth.KST, "2020.07.01 AM12:00")
        XCTAssertEqual(sunday.endOfMonth.KST, "2020.07.31 PM11:59")

        XCTAssertEqual(sunday.isLastDayOfMonth, false)
        XCTAssertEqual(lastDayOnJuly.isLastDayOfMonth, true)
    }
}

fileprivate extension Date {
    //Set your timeZone
    var KST: String {
        dateformatter.timeZone = TimeZone(abbreviation: "KST")
        return dateformatter.string(from: self)
    }
}

test1.png

Done! 😎

Done! 😎

 

Thanks for reading my post. Next time I’ll write about CoreData. If you have any questions, please leave a comment here.

Quote of the week

"People ask me what I do in the winter when there's no baseball. I'll tell you what I do. I stare out the window and wait for spring."

~ Rogers Hornsby