diff --git a/SwiftDate/SwiftDate.swift b/SwiftDate/SwiftDate.swift index 0c7d2f4a..952ec505 100644 --- a/SwiftDate/SwiftDate.swift +++ b/SwiftDate/SwiftDate.swift @@ -253,41 +253,54 @@ public extension NSDate { return dateFormatter } - /** - Create a new NSDate instance based on refDate (if nil uses current date) and set components - - :param: refDate reference date instance (nil to use NSDate()) - :param: year year component (nil to leave it untouched) - :param: month month component (nil to leave it untouched) - :param: day day component (nil to leave it untouched) - :param: tz time zone component (it's the abbreviation of NSTimeZone, like 'UTC' or 'GMT+2', nil to use current time zone) - - :returns: a new NSDate with components changed according to passed params - */ - class func date(refDate refDate: NSDate?, year: Int?, month: Int?, day: Int?, tz: String?) -> NSDate { - let referenceDate = refDate ?? NSDate() - return referenceDate.set(year: year, month: month, day: day, hour: 0, minute: 0, second: 0, tz: tz) - } - - /** - Create a new NSDate instance based on refDate (if nil uses current date) and set components - - :param: refDate reference date instance (nil to use NSDate()) - :param: year year component (nil to leave it untouched) - :param: month month component (nil to leave it untouched) - :param: day day component (nil to leave it untouched) - :param: hour hour component (nil to leave it untouched) - :param: minute minute component (nil to leave it untouched) - :param: second second component (nil to leave it untouched) - :param: tz time zone component (it's the abbreviation of NSTimeZone, like 'UTC' or 'GMT+2', nil to use current time zone) - - :returns: a new NSDate with components changed according to passed params - */ - class func date(refDate refDate: NSDate?, year: Int?, month: Int?, day: Int?, hour: Int?, minute: Int?, second: Int?, tz: String?) -> NSDate { - let referenceDate = refDate ?? NSDate() - return referenceDate.set(year: year, month: month, day: day, hour: hour, minute: minute, second: second, tz: tz) - } - + /** + Create a new NSDate instance based on refDate (if nil uses current date) and set components + + :param: refDate reference date instance (nil to use NSDate()) + :param: year year component (nil to leave it untouched) + :param: month month component (nil to leave it untouched) + :param: day day component (nil to leave it untouched) + :param: hour hour component (nil to leave it untouched) + :param: minute minute component (nil to leave it untouched) + :param: second second component (nil to leave it untouched) + :param: tz time zone component (it's the abbreviation of NSTimeZone, like 'UTC' or 'GMT+2', nil to use current time zone) + + :returns: a new NSDate with components changed according to passed params + */ + class func date(refDate refDate: NSDate? = nil, year: Int? = nil, month: Int? = nil, day: Int? = nil, hour: Int? = nil, minute: Int? = nil, second: Int? = nil, tz: String? = nil) -> NSDate { + let referenceDate = refDate ?? NSDate() + return referenceDate.set(year: year, month: month, day: day, hour: hour, minute: minute, second: second, tz: tz) + } + + + /** + Create a new NSDate instance based on refDate (if nil uses current date) and set components + + :param: refDate reference date instance (nil to use NSDate()) + :param: year year component (nil to leave it untouched) + :param: month month component (nil to leave it untouched) + :param: day day component (nil to leave it untouched) + :param: hour hour component (nil to leave it untouched) + :param: minute minute component (nil to leave it untouched) + :param: second second component (nil to leave it untouched) + :param: tz time zone component (it's the abbreviation of NSTimeZone, like 'UTC' or 'GMT+2', nil to use current time zone) + + :returns: a new NSDate with components changed according to passed params + */ + convenience init(var refDate: NSDate? = nil, year: Int, month: Int, day: Int, hour: Int? = nil, minute: Int? = nil, second: Int? = nil, let tz: String? = nil) { + + if (refDate == nil) { + + // If refDate == nil, we want a reference date of 2001-01-01 00:00:00.000 in the tz time zone + refDate = NSDate().set(year: 2001, month: 1, day: 1, hour: 0, minute: 0, second: 0, tz: tz) + } + + let newDate = refDate!.set(year: year, month: month, day: day, hour: hour, minute: minute, second: second, tz: tz) + self.init(timeIntervalSinceReferenceDate: newDate.timeIntervalSinceReferenceDate) + } + + + /** Return a new NSDate instance with the current date and time set to 00:00:00 @@ -336,17 +349,28 @@ public extension NSDate { :returns: a new NSDate instance with changed values */ func set(year year: Int?=nil, month: Int?=nil, day: Int?=nil, hour: Int?=nil, minute: Int?=nil, second: Int?=nil, tz: String?=nil) -> NSDate! { - let components = self.components - components.year = year ?? self.year - components.month = month ?? self.month - components.day = day ?? self.day - components.hour = hour ?? self.hour - components.minute = minute ?? self.minute - components.second = second ?? self.second - components.timeZone = (tz != nil ? NSTimeZone(abbreviation: tz!) : NSTimeZone.defaultTimeZone()) - return NSCalendar.currentCalendar().dateFromComponents(components) - } - + let components = self.components + if year != nil { components.year = year! } + if month != nil { components.month = month! } + if day != nil { components.day = day! } + if hour != nil { components.hour = hour! } + if minute != nil { components.minute = minute! } + if second != nil { components.second = second! } + components.timeZone = (tz != nil ? NSTimeZone(abbreviation: tz!) : NSTimeZone.defaultTimeZone()) + + // Set weekday stuff to undefined to prevent dateFromComponents to get confused + components.yearForWeekOfYear = NSDateComponentUndefined + components.weekOfYear = NSDateComponentUndefined + components.weekday = NSDateComponentUndefined + components.weekdayOrdinal = NSDateComponentUndefined + + // Set calendar time zone to desired time zone + let calendar = NSCalendar.currentCalendar() + calendar.timeZone = components.timeZone! + + return calendar.dateFromComponents(components) + } + /** Allows you to set individual date components by passing an array of components name and associated values diff --git a/SwiftDateTests/SwiftDateTests.swift b/SwiftDateTests/SwiftDateTests.swift index 492e24de..f53f937e 100644 --- a/SwiftDateTests/SwiftDateTests.swift +++ b/SwiftDateTests/SwiftDateTests.swift @@ -26,6 +26,29 @@ class SwiftDateTests: XCTestCase { super.tearDown() } + func test_init() { + let testDate = NSDate(year: 2015, month: 10, day: 23) + XCTAssertEqual(testDate.year, 2015) + XCTAssertEqual(testDate.month, 10) + XCTAssertEqual(testDate.day, 23) + XCTAssertEqual(testDate.hour, 0) + XCTAssertEqual(testDate.minute, 0) + XCTAssertEqual(testDate.second, 0) + } + + + func test_initRefdate() { + let refDate = NSDate() + let testDate = NSDate(refDate: refDate, year: 2015, month: 10, day: 23) + XCTAssertEqual(testDate.year, 2015) + XCTAssertEqual(testDate.month, 10) + XCTAssertEqual(testDate.day, 23) + XCTAssertEqual(testDate.hour, refDate.hour) + XCTAssertEqual(testDate.minute, refDate.minute) + XCTAssertEqual(testDate.second, refDate.second) + } + + func test_less_than() { XCTAssertTrue(before < now) XCTAssertTrue(now < after)