Date/Date/Date.swift
//
// Date.swift
// Date
//
// Created by Mark Meretzky on 10/17/18.
// Copyright © 2018 New York University School of Professional Studies. All rights reserved.
//
import Foundation;
class Date: CustomStringConvertible {
//year, month, and day are stored properties.
var year: Int;
var month: Int {
willSet(newMonth) { //a property observer
if newMonth < 1 || newMonth > 12 {
print("bad month \(newMonth)");
}
}
}
var day: Int {
willSet(newDay) {
if newDay < 1 || newDay > monthLength() {
print("bad day \(newDay) for month \(month)");
}
}
}
//description is a read-only computed property.
var description: String {
return "\(month)/\(day)/\(year)";
}
init(month: Int, day: Int, year: Int) {
self.year = year; //self.year is the property, year is the argument
self.month = month;
self.day = day;
}
//Put today's year, month, and day into the newborn Date object.
init() {
let calendar: Calendar = Calendar.current;
let today: Foundation.Date = Foundation.Date(); //Apple's class Date, not ours.
let dateComponents: DateComponents = calendar.dateComponents([.year, .month, .day], from: today);
year = dateComponents.year!;
month = dateComponents.month!;
day = dateComponents.day!;
}
/*
Return the number of days in the month described by the year and month properties. For example,
If year = 2018 and month = 2, then this method returns 28.
if year = 2020 and month = 2, then this method returns 29.
*/
func monthLength() -> Int {
let calendar: Calendar = Calendar.current;
let dateComponents: DateComponents = DateComponents(year: year, month: month, day: day);
let date: Foundation.Date = calendar.date(from: dateComponents)!;
let range: Range = calendar.range(of: .day, in: .month, for: date)!;
return range.count;
}
//Advance this Date one day into the future.
//This method accepts no arguments.
func next() -> Void {
if day < monthLength() {
day += 1; //means day = day + 1;
return;
}
day = 1;
if month < Date.yearLength() {
month += 1;
return;
}
month = 1;
year += 1;
}
/*
Advance this Date many days into the future.
This method accepts one argument.
It does the bulk of its work by calling the above method over and over.
*/
func next(_ distance: Int) {
if distance < 0 {
print("argument \(distance) of next must be non-negative");
return;
}
for _ in 1 ... distance { //Loops distance times. No need to name the counting variable.
next();
}
}
// Return the number of months in a year. A type method is marked with the keyword "class".
class func yearLength() -> Int {
return 12;
}
}