Skip to content

Operations

Oscar edited this page Sep 9, 2020 · 1 revision

Operations

The foundation library usually requires a lot of setup to work with, one the goals of Almanakka is to get rid of that setup by providing some useful extensions that make it easy to handle calendar related tasks.

Calendar Data Models

  • Day
  • Week
  • Month
  • Year

An initialized unit contains a property with its sub units. For example, Year contains an array of Month, which in turn contains an array of Week which contains an array of Day.

Behind the scenes, everything is being flat mapped into days. So a year will have 365 days (366 for leap years) properly split into 12 months.

Usage

Creating Calendar Units

Today

// Create an instance of this year
let thisYear = Year(referenceDate: .today)

10 Years from today

// Create an instance 10 years from now
let tenYearsLater = thisYear.advanced(by: 10)

January 1970

let januaryFirst1970 = Date(timeIntervalSince1970: 0)

Month Modifiers

Leading and Trailing days

When visually displaying the days in a month, it is often the case we want to show the days that would fit the month view from the previous and following month.

For example, the view of September 2020 includes the 30-31 from August, and 1-2-3 from October.

Sun Mon Tue Wed Thu Fri Sat
30 31 1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 1 2 3

The month unit can be created with or without these extra days by using the isExcludingWeeksBeforeAndAfter parameter.

Foundation Vs Almanakka

Get weekday from a date

Foundation
let formatter = DateFormatter()
let weekDay = formatter.weekdaySymbols[Calendar.current.component(.weekday, from: Date())]
Almanakka
 let weekDay = Day(referenceDate: Date()).value

Get month from a date

Foundation
let calendar = Calendar.current
let month = calendar.component(.month, from: Date())
Almanakka
 let month = Day(referenceDate: Date()).value

Get year from a date

Foundation
let calendar = Calendar.current
let year = calendar.component(.year, from: Date())
Almanakka
 let year = Day(referenceDate: Date()).value

Get day from the date

Foundation
let calendar = Calendar.current
let day = calendar.component(.day, from: Date())
Almanakka
 let day = Day(referenceDate: Date()).value

Get the previous/next day

Foundation
var nextDay = Calendar.current.date(byAdding: .day, value: 1, to: Date())
calendar.component(.day, nextDay!)
Almanakka
 let nextDay = Day(referenceDate: Date()).advance(by: 1)

Get the previous/next month

Foundation
var lastMonthDate = Calendar.current.date(byAdding: .month, value: -1, to:  Date())
calendar.component(.month, from:lastMonthDate!)
Almanakka
 let lastMonth = Month(referenceDate: Date()).advance(by: -1)

Get the previous/next year

Foundation
var nextYear = Calendar.current.date(byAdding: .year, value: 1, to:  Date())
calendar.component(.month, from:nextYear!)
Almanakka
 let nextYear = Year(referenceDate: Date()).advance(by: 1)

Check if a date occurs within this week

Foundation
let calendar = Calendar.current
let today = Date()
let sunday = calendar.date(from: calendar.dateComponents([.yearForWeekOfYear, .weekOfYear], from: today))!
let startOfWeek = calendar.date(byAdding: .day, value: 1, to: sunday)!
let endOfWeek = calendar.date(byAdding: .day, value: 7, to: sunday)!

let doesWeekContainsDay = startOfWeek.compare(today).rawValue * today.compare(endOfWeek).rawValue >= 0
Almanakka
let week = Week(referenceDate: Date())
let day = Day(referenceDate: Date())

let doesWeekContainDay = week.contains(day: day)

- If date occurs within this Month

Foundation

let startOfMonth = Calendar.current.date(from: Calendar.current.dateComponents([.year, .month], from: Date()))!
let endOfMonth = Calendar.current.date(byAdding: DateComponents(month: 1, day: -1),
                                            to: Calendar.current.date(from: Calendar.current.dateComponents([.year, .month], from: Date()))!)!

let doesMonthsContainsDay = (min(startOfMonth, endOfMonth) ... max(startOfMonth, endOfMonth)) ~= Date()

- If date occurs within this Month

ALKCore

let month = Month(referenceDate: Date())
let week = Week(referenceDate: Date())
let day = Day(referenceDate: Date())

let doesMonthContainDay = month.contains(day: day)
// We can also use contains method to find if a particular week is contained in month or not
let doesMonthContainsWeek = month.contains(week: week)

- If date occurs within this year

Foundation

let startOfYear =  Calendar.current.date(from: Calendar.current.dateComponents([.year], from: Date()))!
let endOfYear = Calendar.current.date(from: DateComponents(year: Calendar.current.component(.year, from: Date()), month: 12, day: 31))!

let doesYearContainsDay = (min(startOfYear, endOfYear) ... max(startOfYear, endOfYear)) ~= Date()

- If date occurs within this year

ALKCore

let year = Year(referenceDate: Date())
let month = Month(referenceDate: Date())
let week = Week(referenceDate: Date())
let day = Day(referenceDate: Date())

let doesYearContainsDay = year.contains(day: day)
// We can also use contains method to find if a particular week/month is contained in year or not
let doesYearContainsMonth = year.contains(month: month)
let doesYearContainsWeek = year.contains(week: week)

Public Holidays From 1970~2050

Almanakka contains a list of holidays that can be queried like this.

let day = Day(referenceDate: Date())
let isHoliday = day.isHoliday // returns true if the day is holiday
let holidayName = day.holidayTitle //return holiday name if the day is public holiday
let holidayNameEnglish = day.holidayTitleEnglish //return holiday name in english if the day is public holiday