diff --git a/.swift-version b/.swift-version index 9f55b2cc..819e07a2 100644 --- a/.swift-version +++ b/.swift-version @@ -1 +1 @@ -3.0 +5.0 diff --git a/DateTools.podspec b/DateTools.podspec index 5f2dfe1b..59280884 100644 --- a/DateTools.podspec +++ b/DateTools.podspec @@ -1,10 +1,10 @@ Pod::Spec.new do |s| s.name = 'DateTools' s.version = '2.0.0' - s.summary = 'Dates and time made easy in Objective-c' + s.summary = 'Dates and time made easy in Objective-C' s.homepage = 'https://github.com/MatthewYork/DateTools' - s.description = 'DateTools was written to streamline date and time handling in Swift.' + s.description = 'DateTools was written to streamline date and time handling in Objective-C.' s.license = { :type => 'MIT', :file => 'LICENSE' } s.author = { "Matthew York" => "my3681@gmail.com" } @@ -12,8 +12,8 @@ Pod::Spec.new do |s| s.source = { :git => "https://github.com/MatthewYork/DateTools.git", :tag => "v#{s.version.to_s}" } - s.ios.deployment_target = '8.0' - s.osx.deployment_target = '10.9' + s.platforms = { :ios => '7.0', :osx => '10.7' } + s.requires_arc = true s.source_files = 'DateTools/DateTools' diff --git a/DateTools/DateTools/DateTools.bundle/es.lproj/DateTools.strings b/DateTools/DateTools/DateTools.bundle/es.lproj/DateTools.strings index 4d7113f3..2aeffc05 100644 --- a/DateTools/DateTools/DateTools.bundle/es.lproj/DateTools.strings +++ b/DateTools/DateTools/DateTools.bundle/es.lproj/DateTools.strings @@ -52,6 +52,9 @@ /* No comment provided by engineer. */ "1 day ago" = "Hace un día"; +/* No comment provided by engineer. */ +"1 hour ago" = "Hace 1 hora"; + /* No comment provided by engineer. */ "This morning" = "Esta mañana"; diff --git a/DateTools/DateTools/NSDate+DateTools.h b/DateTools/DateTools/NSDate+DateTools.h index 94231a75..07b91844 100644 --- a/DateTools/DateTools/NSDate+DateTools.h +++ b/DateTools/DateTools/NSDate+DateTools.h @@ -21,10 +21,17 @@ // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifndef DateToolsLocalizedStrings + +#ifdef SPM +#define DateToolsLocalizedStrings(key) \ +NSLocalizedStringFromTableInBundle(key, @"DateTools", [NSBundle bundleWithPath:[[SWIFTPM_MODULE_BUNDLE resourcePath] stringByAppendingPathComponent:@"DateTools.bundle"]], nil) +#else #define DateToolsLocalizedStrings(key) \ NSLocalizedStringFromTableInBundle(key, @"DateTools", [NSBundle bundleWithPath:[[[NSBundle bundleForClass:[DTError class]] resourcePath] stringByAppendingPathComponent:@"DateTools.bundle"]], nil) #endif +#endif + #import #import "DTConstants.h" diff --git a/DateTools/Examples/DateToolsExample/DateToolsExample.xcodeproj/xcshareddata/xcschemes/DateTools.xcscheme b/DateTools/Examples/DateToolsExample/DateToolsExample.xcodeproj/xcshareddata/xcschemes/DateTools.xcscheme index e97962ab..9846c2f7 100644 --- a/DateTools/Examples/DateToolsExample/DateToolsExample.xcodeproj/xcshareddata/xcschemes/DateTools.xcscheme +++ b/DateTools/Examples/DateToolsExample/DateToolsExample.xcodeproj/xcshareddata/xcschemes/DateTools.xcscheme @@ -15,7 +15,11 @@ >>>>>> swift:DateTools/Examples/DateToolsExample/DateToolsExample.xcodeproj/xcshareddata/xcschemes/DateTools.xcscheme BlueprintName = "DateTools iOS" ReferencedContainer = "container:DateToolsExample.xcodeproj"> @@ -57,7 +61,11 @@ >>>>>> swift:DateTools/Examples/DateToolsExample/DateToolsExample.xcodeproj/xcshareddata/xcschemes/DateTools.xcscheme BlueprintName = "DateTools iOS" ReferencedContainer = "container:DateToolsExample.xcodeproj"> @@ -79,7 +87,11 @@ >>>>>> swift:DateTools/Examples/DateToolsExample/DateToolsExample.xcodeproj/xcshareddata/xcschemes/DateTools.xcscheme BlueprintName = "DateTools iOS" ReferencedContainer = "container:DateToolsExample.xcodeproj"> @@ -97,7 +109,11 @@ >>>>>> swift:DateTools/Examples/DateToolsExample/DateToolsExample.xcodeproj/xcshareddata/xcschemes/DateTools.xcscheme BlueprintName = "DateTools iOS" ReferencedContainer = "container:DateToolsExample.xcodeproj"> diff --git a/DateToolsSwift.podspec b/DateToolsSwift.podspec index 30c79ed9..6990c708 100644 --- a/DateToolsSwift.podspec +++ b/DateToolsSwift.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'DateToolsSwift' - s.version = '2.0.0' + s.version = '5.0.0' s.summary = 'Dates and time made easy in Swift' s.homepage = 'https://github.com/MatthewYork/DateTools' @@ -10,10 +10,12 @@ Pod::Spec.new do |s| s.author = { "Matthew York" => "my3681@gmail.com" } s.source = { :git => "https://github.com/MatthewYork/DateTools.git", - :tag => "v#{s.version.to_s}" } + :tag => "#{s.version.to_s}" } s.ios.deployment_target = '8.0' s.osx.deployment_target = '10.9' + s.tvos.deployment_target = '9.0' + s.watchos.deployment_target = '2.0' s.requires_arc = true s.source_files = 'DateToolsSwift/DateTools' diff --git a/DateToolsSwift/DateTools/Date+Bundle.swift b/DateToolsSwift/DateTools/Date+Bundle.swift index 735848cb..6fe0845a 100644 --- a/DateToolsSwift/DateTools/Date+Bundle.swift +++ b/DateToolsSwift/DateTools/Date+Bundle.swift @@ -9,10 +9,17 @@ import Foundation public extension Bundle { - - class func dateToolsBundle() -> Bundle { - let assetPath = Bundle(for: Constants.self).resourcePath! - return Bundle(path: (assetPath as NSString).appendingPathComponent("DateTools.bundle"))! - } + + class func dateToolsBundle() -> Bundle? { + let assetPath: String? +#if SPM + assetPath = Bundle.module.resourcePath +#else + assetPath = Bundle(for: Constants.self).resourcePath +#endif + guard let assetPath = assetPath else { return nil } + return Bundle(path: NSString(string: assetPath).appendingPathComponent("DateTools.bundle")) + } + } diff --git a/DateToolsSwift/DateTools/Date+Comparators.swift b/DateToolsSwift/DateTools/Date+Comparators.swift index 30f800bf..4349804b 100644 --- a/DateToolsSwift/DateTools/Date+Comparators.swift +++ b/DateToolsSwift/DateTools/Date+Comparators.swift @@ -43,8 +43,8 @@ public extension Date { * * - returns: A TimeChunk representing the time between the dates, in natural form */ - public func chunkBetween(date: Date) -> TimeChunk { - var compenentsBetween = Calendar.autoupdatingCurrent.dateComponents([.year, .month, .day, .hour, .minute, .second], from: self, to: date) + func chunkBetween(date: Date) -> TimeChunk { + let compenentsBetween = Calendar.autoupdatingCurrent.dateComponents([.year, .month, .day, .hour, .minute, .second], from: self, to: date) return TimeChunk(seconds: compenentsBetween.second!, minutes: compenentsBetween.minute!, hours: compenentsBetween.hour!, days: compenentsBetween.day!, weeks: 0, months: compenentsBetween.month!, years: compenentsBetween.year!) // TimeChunk(seconds: secondDelta, minutes: minuteDelta, hours: hourDelta, days: dayDelta, weeks: 0, months: monthDelta, years: yearDelta) } @@ -56,7 +56,7 @@ public extension Date { * * - returns: Bool representing comparison result */ - public func equals(_ date: Date) -> Bool { + func equals(_ date: Date) -> Bool { return self.compare(date) == .orderedSame } @@ -68,7 +68,7 @@ public extension Date { * * - returns: Bool representing comparison result */ - public func isLater(than date: Date) -> Bool { + func isLater(than date: Date) -> Bool { return self.compare(date) == .orderedDescending } @@ -80,7 +80,7 @@ public extension Date { * * - returns: Bool representing comparison result */ - public func isLaterThanOrEqual(to date: Date) -> Bool { + func isLaterThanOrEqual(to date: Date) -> Bool { return self.compare(date) == .orderedDescending || self.compare(date) == .orderedSame } @@ -92,7 +92,7 @@ public extension Date { * * - returns: Bool representing comparison result */ - public func isEarlier(than date: Date) -> Bool { + func isEarlier(than date: Date) -> Bool { return self.compare(date) == .orderedAscending } @@ -104,7 +104,7 @@ public extension Date { * * - returns: Bool representing comparison result */ - public func isEarlierThanOrEqual(to date: Date) -> Bool { + func isEarlierThanOrEqual(to date: Date) -> Bool { return self.compare(date) == .orderedAscending || self.compare(date) == .orderedSame } @@ -115,7 +115,7 @@ public extension Date { * * - returns: True if both paramter dates fall on the same day, false otherwise */ - public func isSameDay(date : Date ) -> Bool { + func isSameDay(date : Date ) -> Bool { return Date.isSameDay(date: self, as: date) } @@ -127,7 +127,7 @@ public extension Date { * * - returns: True if both paramter dates fall on the same day, false otherwise */ - public static func isSameDay(date: Date, as compareDate: Date) -> Bool { + static func isSameDay(date: Date, as compareDate: Date) -> Bool { let calendar = Calendar.autoupdatingCurrent var components = calendar.dateComponents([.era, .year, .month, .day], from: date) let dateOne = calendar.date(from: components) @@ -154,7 +154,7 @@ public extension Date { * * - returns: The years between receiver and provided date */ - public func years(from date: Date) -> Int { + func years(from date: Date) -> Int { return years(from: date, calendar:nil) } @@ -169,7 +169,7 @@ public extension Date { * * - returns: The years between receiver and provided date */ - public func months(from date: Date) -> Int { + func months(from date: Date) -> Int { return months(from: date, calendar:nil) } @@ -184,7 +184,7 @@ public extension Date { * * - returns: The weeks between receiver and provided date */ - public func weeks(from date: Date) -> Int { + func weeks(from date: Date) -> Int { return weeks(from: date, calendar:nil) } @@ -199,7 +199,7 @@ public extension Date { * * - returns: The days between receiver and provided date */ - public func days(from date: Date) -> Int { + func days(from date: Date) -> Int { return days(from: date, calendar:nil) } @@ -213,7 +213,7 @@ public extension Date { * * - returns: The hours between receiver and provided date */ - public func hours(from date: Date) -> Int { + func hours(from date: Date) -> Int { return Int(self.timeIntervalSince(date)/Constants.SecondsInHour); } @@ -227,7 +227,7 @@ public extension Date { * * - returns: The minutes between receiver and provided date */ - public func minutes(from date: Date) -> Int { + func minutes(from date: Date) -> Int { return Int(self.timeIntervalSince(date)/Constants.SecondsInMinute) } @@ -241,7 +241,7 @@ public extension Date { * * - returns: The seconds between receiver and provided date */ - public func seconds(from date: Date) -> Int { + func seconds(from date: Date) -> Int { return Int(timeIntervalSince(date)) } @@ -259,7 +259,7 @@ public extension Date { * * - returns: The years between receiver and provided date */ - public func years(from date: Date, calendar: Calendar?) -> Int { + func years(from date: Date, calendar: Calendar?) -> Int { var calendarCopy = calendar if (calendar == nil) { calendarCopy = Calendar.autoupdatingCurrent @@ -283,7 +283,7 @@ public extension Date { * * - returns: The months between receiver and provided date */ - public func months(from date: Date, calendar: Calendar?) -> Int{ + func months(from date: Date, calendar: Calendar?) -> Int { var calendarCopy = calendar if (calendar == nil) { calendarCopy = Calendar.autoupdatingCurrent @@ -307,7 +307,7 @@ public extension Date { * * - returns: The weeks between receiver and provided date */ - public func weeks(from date: Date, calendar: Calendar?) -> Int{ + func weeks(from date: Date, calendar: Calendar?) -> Int { var calendarCopy = calendar if (calendar == nil) { calendarCopy = Calendar.autoupdatingCurrent @@ -331,7 +331,7 @@ public extension Date { * * - returns: The days between receiver and provided date */ - public func days(from date: Date, calendar: Calendar?) -> Int { + func days(from date: Date, calendar: Calendar?) -> Int { var calendarCopy = calendar if (calendar == nil) { calendarCopy = Calendar.autoupdatingCurrent @@ -351,7 +351,7 @@ public extension Date { * The number of years until the receiver's date (0 if the receiver is the same or * earlier than now). */ - public var yearsUntil: Int { + var yearsUntil: Int { return yearsLater(than: Date()) } @@ -359,7 +359,7 @@ public extension Date { * The number of months until the receiver's date (0 if the receiver is the same or * earlier than now). */ - public var monthsUntil: Int { + var monthsUntil: Int { return monthsLater(than: Date()) } @@ -367,7 +367,7 @@ public extension Date { * The number of weeks until the receiver's date (0 if the receiver is the same or * earlier than now). */ - public var weeksUntil: Int { + var weeksUntil: Int { return weeksLater(than: Date()) } @@ -375,7 +375,7 @@ public extension Date { * The number of days until the receiver's date (0 if the receiver is the same or * earlier than now). */ - public var daysUntil: Int { + var daysUntil: Int { return daysLater(than: Date()) } @@ -383,7 +383,7 @@ public extension Date { * The number of hours until the receiver's date (0 if the receiver is the same or * earlier than now). */ - public var hoursUntil: Int{ + var hoursUntil: Int{ return hoursLater(than: Date()) } @@ -391,7 +391,7 @@ public extension Date { * The number of minutes until the receiver's date (0 if the receiver is the same or * earlier than now). */ - public var minutesUntil: Int{ + var minutesUntil: Int{ return minutesLater(than: Date()) } @@ -399,7 +399,7 @@ public extension Date { * The number of seconds until the receiver's date (0 if the receiver is the same or * earlier than now). */ - public var secondsUntil: Int{ + var secondsUntil: Int{ return secondsLater(than: Date()) } @@ -410,7 +410,7 @@ public extension Date { * The number of years the receiver's date is earlier than now (0 if the receiver is * the same or earlier than now). */ - public var yearsAgo: Int { + var yearsAgo: Int { return yearsEarlier(than: Date()) } @@ -418,7 +418,7 @@ public extension Date { * The number of months the receiver's date is earlier than now (0 if the receiver is * the same or earlier than now). */ - public var monthsAgo: Int { + var monthsAgo: Int { return monthsEarlier(than: Date()) } @@ -426,7 +426,7 @@ public extension Date { * The number of weeks the receiver's date is earlier than now (0 if the receiver is * the same or earlier than now). */ - public var weeksAgo: Int { + var weeksAgo: Int { return weeksEarlier(than: Date()) } @@ -434,7 +434,7 @@ public extension Date { * The number of days the receiver's date is earlier than now (0 if the receiver is * the same or earlier than now). */ - public var daysAgo: Int { + var daysAgo: Int { return daysEarlier(than: Date()) } @@ -442,7 +442,7 @@ public extension Date { * The number of hours the receiver's date is earlier than now (0 if the receiver is * the same or earlier than now). */ - public var hoursAgo: Int { + var hoursAgo: Int { return hoursEarlier(than: Date()) } @@ -450,7 +450,7 @@ public extension Date { * The number of minutes the receiver's date is earlier than now (0 if the receiver is * the same or earlier than now). */ - public var minutesAgo: Int { + var minutesAgo: Int { return minutesEarlier(than: Date()) } @@ -458,7 +458,7 @@ public extension Date { * The number of seconds the receiver's date is earlier than now (0 if the receiver is * the same or earlier than now). */ - public var secondsAgo: Int{ + var secondsAgo: Int{ return secondsEarlier(than: Date()) } @@ -473,7 +473,7 @@ public extension Date { * * - returns: The number of years */ - public func yearsEarlier(than date: Date) -> Int { + func yearsEarlier(than date: Date) -> Int { return abs(min(years(from: date), 0)) } @@ -485,7 +485,7 @@ public extension Date { * * - returns: The number of months */ - public func monthsEarlier(than date: Date) -> Int { + func monthsEarlier(than date: Date) -> Int { return abs(min(months(from: date), 0)); } @@ -497,7 +497,7 @@ public extension Date { * * - returns: The number of weeks */ - public func weeksEarlier(than date: Date) -> Int { + func weeksEarlier(than date: Date) -> Int { return abs(min(weeks(from: date), 0)) } @@ -509,7 +509,7 @@ public extension Date { * * - returns: The number of days */ - public func daysEarlier(than date: Date) -> Int { + func daysEarlier(than date: Date) -> Int { return abs(min(days(from: date), 0)) } @@ -521,7 +521,7 @@ public extension Date { * * - returns: The number of hours */ - public func hoursEarlier(than date: Date) -> Int { + func hoursEarlier(than date: Date) -> Int { return abs(min(hours(from: date), 0)) } @@ -533,7 +533,7 @@ public extension Date { * * - returns: The number of minutes */ - public func minutesEarlier(than date: Date) -> Int { + func minutesEarlier(than date: Date) -> Int { return abs(min(minutes(from: date), 0)) } @@ -545,7 +545,7 @@ public extension Date { * * - returns: The number of seconds */ - public func secondsEarlier(than date: Date) -> Int { + func secondsEarlier(than date: Date) -> Int { return abs(min(seconds(from: date), 0)) } @@ -561,7 +561,7 @@ public extension Date { * * - returns: The number of years */ - public func yearsLater(than date: Date) -> Int { + func yearsLater(than date: Date) -> Int { return max(years(from: date), 0) } @@ -574,7 +574,7 @@ public extension Date { * * - returns: The number of months */ - public func monthsLater(than date: Date) -> Int { + func monthsLater(than date: Date) -> Int { return max(months(from: date), 0) } @@ -587,7 +587,7 @@ public extension Date { * * - returns: The number of weeks */ - public func weeksLater(than date: Date) -> Int { + func weeksLater(than date: Date) -> Int { return max(weeks(from: date), 0) } @@ -600,7 +600,7 @@ public extension Date { * * - returns: The number of days */ - public func daysLater(than date: Date) -> Int { + func daysLater(than date: Date) -> Int { return max(days(from: date), 0) } @@ -613,7 +613,7 @@ public extension Date { * * - returns: The number of hours */ - public func hoursLater(than date: Date) -> Int { + func hoursLater(than date: Date) -> Int { return max(hours(from: date), 0) } @@ -626,7 +626,7 @@ public extension Date { * * - returns: The number of minutes */ - public func minutesLater(than date: Date) -> Int { + func minutesLater(than date: Date) -> Int { return max(minutes(from: date), 0) } @@ -639,7 +639,7 @@ public extension Date { * * - returns: The number of seconds */ - public func secondsLater(than date: Date) -> Int { + func secondsLater(than date: Date) -> Int { return max(seconds(from: date), 0) } } diff --git a/DateToolsSwift/DateTools/Date+Components.swift b/DateToolsSwift/DateTools/Date+Components.swift index 6545908e..fe67cdae 100644 --- a/DateToolsSwift/DateTools/Date+Components.swift +++ b/DateToolsSwift/DateTools/Date+Components.swift @@ -23,7 +23,7 @@ public extension Date { * - returns: The value of the component * */ - public func component(_ component: Calendar.Component) -> Int { + func component(_ component: Calendar.Component) -> Int { let calendar = Calendar.autoupdatingCurrent return calendar.component(component, from: self) } @@ -37,7 +37,7 @@ public extension Date { * - returns: The ordinal number of a smaller calendar component within a specified larger calendar component * */ - public func ordinality(of smaller: Calendar.Component, in larger: Calendar.Component) -> Int? { + func ordinality(of smaller: Calendar.Component, in larger: Calendar.Component) -> Int? { let calendar = Calendar.autoupdatingCurrent return calendar.ordinality(of: smaller, in: larger, for: self) } @@ -54,7 +54,8 @@ public extension Date { * - returns: The number of smaller units required to equal in 1 larger unit, given the date called on * */ - public func unit(of smaller: Calendar.Component, in larger: Calendar.Component) -> Int? { + @available(*, deprecated, message: "Calendar component hashes no longer yield relevant values and will always return nil. The function is deprecated and will be removed soon.") + func unit(of smaller: Calendar.Component, in larger: Calendar.Component) -> Int? { let calendar = Calendar.autoupdatingCurrent var units = 1 var unitRange: Range? @@ -125,105 +126,105 @@ public extension Date { /** * Convenience getter for the date's `era` component */ - public var era: Int { + var era: Int { return component(.era) } /** * Convenience getter for the date's `year` component */ - public var year: Int { + var year: Int { return component(.year) } /** * Convenience getter for the date's `month` component */ - public var month: Int { + var month: Int { return component(.month) } /** * Convenience getter for the date's `week` component */ - public var week: Int { + var week: Int { return component(.weekday) } /** * Convenience getter for the date's `day` component */ - public var day: Int { + var day: Int { return component(.day) } /** * Convenience getter for the date's `hour` component */ - public var hour: Int { + var hour: Int { return component(.hour) } /** * Convenience getter for the date's `minute` component */ - public var minute: Int { + var minute: Int { return component(.minute) } /** * Convenience getter for the date's `second` component */ - public var second: Int { + var second: Int { return component(.second) } /** * Convenience getter for the date's `weekday` component */ - public var weekday: Int { + var weekday: Int { return component(.weekday) } /** * Convenience getter for the date's `weekdayOrdinal` component */ - public var weekdayOrdinal: Int { + var weekdayOrdinal: Int { return component(.weekdayOrdinal) } /** * Convenience getter for the date's `quarter` component */ - public var quarter: Int { + var quarter: Int { return component(.quarter) } /** * Convenience getter for the date's `weekOfYear` component */ - public var weekOfMonth: Int { + var weekOfMonth: Int { return component(.weekOfMonth) } /** * Convenience getter for the date's `weekOfYear` component */ - public var weekOfYear: Int { + var weekOfYear: Int { return component(.weekOfYear) } /** * Convenience getter for the date's `yearForWeekOfYear` component */ - public var yearForWeekOfYear: Int { + var yearForWeekOfYear: Int { return component(.yearForWeekOfYear) } /** * Convenience getter for the date's `daysInMonth` component */ - public var daysInMonth: Int { + var daysInMonth: Int { let calendar = Calendar.autoupdatingCurrent let days = calendar.range(of: .day, in: .month, for: self) return days!.count @@ -234,42 +235,42 @@ public extension Date { /** * Convenience setter for the date's `year` component */ - public mutating func year(_ year: Int) { + mutating func year(_ year: Int) { self = Date.init(year: year, month: self.month, day: self.day, hour: self.hour, minute: self.minute, second: self.second) } /** * Convenience setter for the date's `month` component */ - public mutating func month(_ month: Int) { + mutating func month(_ month: Int) { self = Date.init(year: self.year, month: month, day: self.day, hour: self.hour, minute: self.minute, second: self.second) } /** * Convenience setter for the date's `day` component */ - public mutating func day(_ day: Int) { + mutating func day(_ day: Int) { self = Date.init(year: self.year, month: self.month, day: day, hour: self.hour, minute: self.minute, second: self.second) } /** * Convenience setter for the date's `hour` component */ - public mutating func hour(_ hour: Int) { + mutating func hour(_ hour: Int) { self = Date.init(year: self.year, month: self.month, day: self.day, hour: hour, minute: self.minute, second: self.second) } /** * Convenience setter for the date's `minute` component */ - public mutating func minute(_ minute: Int) { + mutating func minute(_ minute: Int) { self = Date.init(year: self.year, month: self.month, day: self.day, hour: self.hour, minute: minute, second: self.second) } /** * Convenience setter for the date's `second` component */ - public mutating func second(_ second: Int) { + mutating func second(_ second: Int) { self = Date.init(year: self.year, month: self.month, day: self.day, hour: self.hour, minute: self.minute, second: second) } @@ -279,7 +280,7 @@ public extension Date { /** * Determine if date is in a leap year */ - public var isInLeapYear: Bool { + var isInLeapYear: Bool { let yearComponent = component(.year) if yearComponent % 400 == 0 { @@ -297,7 +298,7 @@ public extension Date { /** * Determine if date is within the current day */ - public var isToday: Bool { + var isToday: Bool { let calendar = Calendar.autoupdatingCurrent return calendar.isDateInToday(self) } @@ -305,7 +306,7 @@ public extension Date { /** * Determine if date is within the day tomorrow */ - public var isTomorrow: Bool { + var isTomorrow: Bool { let calendar = Calendar.autoupdatingCurrent return calendar.isDateInTomorrow(self) } @@ -313,7 +314,7 @@ public extension Date { /** * Determine if date is within yesterday */ - public var isYesterday: Bool { + var isYesterday: Bool { let calendar = Calendar.autoupdatingCurrent return calendar.isDateInYesterday(self) } @@ -321,7 +322,7 @@ public extension Date { /** * Determine if date is in a weekend */ - public var isWeekend: Bool { + var isWeekend: Bool { if weekday == 7 || weekday == 1 { return true } diff --git a/DateToolsSwift/DateTools/Date+Format.swift b/DateToolsSwift/DateTools/Date+Format.swift index 94feb4c7..405c2533 100644 --- a/DateToolsSwift/DateTools/Date+Format.swift +++ b/DateToolsSwift/DateTools/Date+Format.swift @@ -24,7 +24,7 @@ public extension Date { * * - returns: Represenation of the date (self) in the specified format */ - public func format(with dateStyle: DateFormatter.Style, timeZone: TimeZone, locale: Locale) -> String? { + func format(with dateStyle: DateFormatter.Style, timeZone: TimeZone, locale: Locale) -> String { let dateFormatter = DateFormatter() dateFormatter.dateStyle = dateStyle dateFormatter.timeZone = timeZone @@ -41,7 +41,7 @@ public extension Date { * * - returns String? - Represenation of the date (self) in the specified format */ - public func format(with dateStyle: DateFormatter.Style, timeZone: TimeZone) -> String? { + func format(with dateStyle: DateFormatter.Style, timeZone: TimeZone) -> String { #if os(Linux) return format(with: dateStyle, timeZone: timeZone, locale: Locale.current) #else @@ -58,7 +58,7 @@ public extension Date { * * - returns: Represenation of the date (self) in the specified format */ - public func format(with dateStyle: DateFormatter.Style, locale: Locale) -> String? { + func format(with dateStyle: DateFormatter.Style, locale: Locale) -> String { return format(with: dateStyle, timeZone: TimeZone.autoupdatingCurrent, locale: locale) } @@ -70,7 +70,7 @@ public extension Date { * * - returns: Represenation of the date (self) in the specified format */ - public func format(with dateStyle: DateFormatter.Style) -> String? { + func format(with dateStyle: DateFormatter.Style) -> String { #if os(Linux) return format(with: dateStyle, timeZone: TimeZone.autoupdatingCurrent, locale: Locale.current) #else @@ -90,7 +90,7 @@ public extension Date { * * - returns: Represenation of the date (self) in the specified format */ - public func format(with dateFormat: String, timeZone: TimeZone, locale: Locale) -> String? { + func format(with dateFormat: String, timeZone: TimeZone, locale: Locale) -> String { let dateFormatter = DateFormatter() dateFormatter.dateFormat = dateFormat dateFormatter.timeZone = timeZone @@ -108,7 +108,7 @@ public extension Date { * * - returns: Representation of the date (self) in the specified format */ - public func format(with dateFormat: String, timeZone: TimeZone) -> String? { + func format(with dateFormat: String, timeZone: TimeZone) -> String { #if os(Linux) return format(with: dateFormat, timeZone: timeZone, locale: Locale.current) #else @@ -125,7 +125,7 @@ public extension Date { * * - returns: Represenation of the date (self) in the specified format */ - public func format(with dateFormat: String, locale: Locale) -> String? { + func format(with dateFormat: String, locale: Locale) -> String { return format(with: dateFormat, timeZone: TimeZone.autoupdatingCurrent, locale: locale) } @@ -137,7 +137,7 @@ public extension Date { * * - returns: Represenation of the date (self) in the specified format */ - public func format(with dateFormat: String) -> String? { + func format(with dateFormat: String) -> String { #if os(Linux) return format(with: dateFormat, timeZone: TimeZone.autoupdatingCurrent, locale: Locale.current) #else diff --git a/DateToolsSwift/DateTools/Date+Inits.swift b/DateToolsSwift/DateTools/Date+Inits.swift index e3d6f6db..2e943e97 100644 --- a/DateToolsSwift/DateTools/Date+Inits.swift +++ b/DateToolsSwift/DateTools/Date+Inits.swift @@ -27,7 +27,7 @@ public extension Date { * - parameter minute: Minute component of new date * - parameter second: Second component of new date */ - public init(year: Int, month: Int, day: Int, hour: Int, minute: Int, second: Int) { + init(year: Int, month: Int, day: Int, hour: Int, minute: Int, second: Int) { var dateComponents = DateComponents() dateComponents.year = year dateComponents.month = month @@ -50,7 +50,7 @@ public extension Date { * - parameter month: Month component of new date * - parameter day: Day component of new date */ - public init(year: Int, month: Int, day: Int) { + init(year: Int, month: Int, day: Int) { self.init(year: year, month: month, day: day, hour: 0, minute: 0, second: 0) } @@ -61,7 +61,7 @@ public extension Date { * - parameter format: Format style using Apple's date formatting guide * - parameter timeZone: Time zone of date */ - public init(dateString: String, format: String, timeZone: TimeZone) { + init(dateString: String, format: String, timeZone: TimeZone) { let dateFormatter = DateFormatter() dateFormatter.dateStyle = .none; dateFormatter.timeStyle = .none; @@ -82,7 +82,7 @@ public extension Date { * - parameter dateString: Date in the formatting given by the format parameter * - parameter format: Format style using Apple's date formatting guide */ - public init (dateString: String, format: String) { + init (dateString: String, format: String) { self.init(dateString: dateString, format: format, timeZone: TimeZone.autoupdatingCurrent) } } diff --git a/DateToolsSwift/DateTools/Date+Manipulations.swift b/DateToolsSwift/DateTools/Date+Manipulations.swift index 72b31358..1d46307a 100644 --- a/DateToolsSwift/DateTools/Date+Manipulations.swift +++ b/DateToolsSwift/DateTools/Date+Manipulations.swift @@ -23,7 +23,7 @@ public extension Date { * - returns: A date retaining the value of the given component and all larger components, * with all smaller components set to their minimum */ - public func start(of component: Component) -> Date { + func start(of component: Component) -> Date { var newDate = self; if component == .second { newDate.second(self.second) @@ -60,7 +60,7 @@ public extension Date { * - returns: A date retaining the value of the given component and all larger components, * with all smaller components set to their maximum */ - public func end(of component: Component) -> Date { + func end(of component: Component) -> Date { var newDate = self; if component == .second { newDate.second(newDate.second + 1) @@ -96,7 +96,7 @@ public extension Date { return newDate } - public func daysInMonth(date: Date) -> Int { + func daysInMonth(date: Date) -> Int { let month = date.month if month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12 { // 31 day month @@ -125,7 +125,7 @@ public extension Date { * - returns: A date with components increased by the values of the * corresponding `TimeChunk` variables */ - public func add(_ chunk: TimeChunk) -> Date { + func add(_ chunk: TimeChunk) -> Date { let calendar = Calendar.autoupdatingCurrent var components = DateComponents() components.year = chunk.years @@ -146,7 +146,7 @@ public extension Date { * - returns: A date with components decreased by the values of the * corresponding `TimeChunk` variables */ - public func subtract(_ chunk: TimeChunk) -> Date { + func subtract(_ chunk: TimeChunk) -> Date { let calendar = Calendar.autoupdatingCurrent var components = DateComponents() components.year = -chunk.years @@ -164,28 +164,28 @@ public extension Date { /** * Operator overload for adding a `TimeChunk` to a date. */ - public static func +(leftAddend: Date, rightAddend: TimeChunk) -> Date { + static func +(leftAddend: Date, rightAddend: TimeChunk) -> Date { return leftAddend.add(rightAddend) } /** * Operator overload for subtracting a `TimeChunk` from a date. */ - public static func -(minuend: Date, subtrahend: TimeChunk) -> Date { + static func -(minuend: Date, subtrahend: TimeChunk) -> Date { return minuend.subtract(subtrahend) } /** * Operator overload for adding a `TimeInterval` to a date. */ - public static func +(leftAddend: Date, rightAddend: Int) -> Date { + static func +(leftAddend: Date, rightAddend: Int) -> Date { return leftAddend.addingTimeInterval((TimeInterval(rightAddend))) } /** * Operator overload for subtracting a `TimeInterval` from a date. */ - public static func -(minuend: Date, subtrahend: Int) -> Date { + static func -(minuend: Date, subtrahend: Int) -> Date { return minuend.addingTimeInterval(-(TimeInterval(subtrahend))) } diff --git a/DateToolsSwift/DateTools/Date+TimeAgo.swift b/DateToolsSwift/DateTools/Date+TimeAgo.swift index 527d02de..37852158 100644 --- a/DateToolsSwift/DateTools/Date+TimeAgo.swift +++ b/DateToolsSwift/DateTools/Date+TimeAgo.swift @@ -24,7 +24,7 @@ public extension Date { * * - returns String - Formatted return string */ - public static func timeAgo(since date:Date) -> String{ + static func timeAgo(since date:Date) -> String{ return date.timeAgo(since: Date(), numericDates: false, numericTimes: false) } @@ -36,7 +36,7 @@ public extension Date { * * - returns String - Formatted return string */ - public static func shortTimeAgo(since date:Date) -> String { + static func shortTimeAgo(since date:Date) -> String { return date.shortTimeAgo(since:Date()) } @@ -46,7 +46,7 @@ public extension Date { * * - returns String - Formatted return string */ - public var timeAgoSinceNow: String { + var timeAgoSinceNow: String { return self.timeAgo(since:Date()) } @@ -56,11 +56,11 @@ public extension Date { * * - returns String - Formatted return string */ - public var shortTimeAgoSinceNow: String { + var shortTimeAgoSinceNow: String { return self.shortTimeAgo(since:Date()) } - public func timeAgo(since date:Date, numericDates: Bool = false, numericTimes: Bool = false) -> String { + func timeAgo(since date:Date, numericDates: Bool = false, numericTimes: Bool = false) -> String { let calendar = NSCalendar.current let unitFlags = Set([.second,.minute,.hour,.day,.weekOfYear,.month,.year]) let earliest = self.earlierDate(date) @@ -155,7 +155,7 @@ public extension Date { } - public func shortTimeAgo(since date:Date) -> String { + func shortTimeAgo(since date:Date) -> String { let calendar = NSCalendar.current let unitFlags = Set([.second,.minute,.hour,.day,.weekOfYear,.month,.year]) let earliest = self.earlierDate(date) @@ -243,7 +243,7 @@ public extension Date { // However, a seemingly-equivalent method from NSBundle is: https://github.com/apple/swift-corelibs-foundation/blob/master/Foundation/NSBundle.swift return Bundle.main.localizedString(forKey: string, value: "", table: "DateTools") #else - return NSLocalizedString(string, tableName: "DateTools", bundle: Bundle.dateToolsBundle(), value: "", comment: "") + return NSLocalizedString(string, tableName: "DateTools", bundle: Bundle.dateToolsBundle() ?? .main, value: "", comment: "") #endif } @@ -257,7 +257,7 @@ public extension Date { * * - returns: The date that is earlier */ - public func earlierDate(_ date:Date) -> Date{ + func earlierDate(_ date:Date) -> Date{ return (self.timeIntervalSince1970 <= date.timeIntervalSince1970) ? self : date } @@ -268,7 +268,7 @@ public extension Date { * * - returns: The date that is later */ - public func laterDate(_ date:Date) -> Date{ + func laterDate(_ date:Date) -> Date{ return (self.timeIntervalSince1970 >= date.timeIntervalSince1970) ? self : date } diff --git a/DateToolsSwift/DateTools/DateTools.bundle/es.lproj/DateTools.strings b/DateToolsSwift/DateTools/DateTools.bundle/es.lproj/DateTools.strings index 4d7113f3..2aeffc05 100644 --- a/DateToolsSwift/DateTools/DateTools.bundle/es.lproj/DateTools.strings +++ b/DateToolsSwift/DateTools/DateTools.bundle/es.lproj/DateTools.strings @@ -52,6 +52,9 @@ /* No comment provided by engineer. */ "1 day ago" = "Hace un día"; +/* No comment provided by engineer. */ +"1 hour ago" = "Hace 1 hora"; + /* No comment provided by engineer. */ "This morning" = "Esta mañana"; diff --git a/DateToolsSwift/DateTools/Integer+DateTools.swift b/DateToolsSwift/DateTools/Integer+DateTools.swift index 3dc55657..55e4baab 100644 --- a/DateToolsSwift/DateTools/Integer+DateTools.swift +++ b/DateToolsSwift/DateTools/Integer+DateTools.swift @@ -15,49 +15,49 @@ public extension Int { /** * A `TimeChunk` with its seconds component set to the value of self */ - public var seconds: TimeChunk { + var seconds: TimeChunk { return TimeChunk(seconds: self, minutes: 0, hours: 0, days: 0, weeks: 0, months: 0, years: 0) } /** * A `TimeChunk` with its minutes component set to the value of self */ - public var minutes: TimeChunk { + var minutes: TimeChunk { return TimeChunk(seconds: 0, minutes: self, hours: 0, days: 0, weeks: 0, months: 0, years: 0) } /** * A `TimeChunk` with its hours component set to the value of self */ - public var hours: TimeChunk { + var hours: TimeChunk { return TimeChunk(seconds: 0, minutes: 0, hours: self, days: 0, weeks: 0, months: 0, years: 0) } /** * A `TimeChunk` with its days component set to the value of self */ - public var days: TimeChunk { + var days: TimeChunk { return TimeChunk(seconds: 0, minutes: 0, hours: 0, days: self, weeks: 0, months: 0, years: 0) } /** * A `TimeChunk` with its weeks component set to the value of self */ - public var weeks: TimeChunk { + var weeks: TimeChunk { return TimeChunk(seconds: 0, minutes: 0, hours: 0, days: 0, weeks: self, months: 0, years: 0) } /** * A `TimeChunk` with its months component set to the value of self */ - public var months: TimeChunk { + var months: TimeChunk { return TimeChunk(seconds: 0, minutes: 0, hours: 0, days: 0, weeks: 0, months: self, years: 0) } /** * A `TimeChunk` with its years component set to the value of self */ - public var years: TimeChunk { + var years: TimeChunk { return TimeChunk(seconds: 0, minutes: 0, hours: 0, days: 0, weeks: 0, months: 0, years: self) } } diff --git a/DateToolsSwift/DateTools/TimePeriod.swift b/DateToolsSwift/DateTools/TimePeriod.swift index 4a060a81..48881abe 100644 --- a/DateToolsSwift/DateTools/TimePeriod.swift +++ b/DateToolsSwift/DateTools/TimePeriod.swift @@ -40,7 +40,7 @@ public extension TimePeriodProtocol { /** * True if the `TimePeriod`'s duration is zero */ - public var isMoment: Bool { + var isMoment: Bool { return self.beginning == self.end } @@ -48,7 +48,7 @@ public extension TimePeriodProtocol { * The duration of the `TimePeriod` in years. * Returns the max int if beginning or end are nil. */ - public var years: Int { + var years: Int { if self.beginning != nil && self.end != nil { return self.beginning!.yearsEarlier(than: self.end!) } @@ -59,7 +59,7 @@ public extension TimePeriodProtocol { * The duration of the `TimePeriod` in weeks. * Returns the max int if beginning or end are nil. */ - public var weeks: Int { + var weeks: Int { if self.beginning != nil && self.end != nil { return self.beginning!.weeksEarlier(than: self.end!) } @@ -70,7 +70,7 @@ public extension TimePeriodProtocol { * The duration of the `TimePeriod` in days. * Returns the max int if beginning or end are nil. */ - public var days: Int { + var days: Int { if self.beginning != nil && self.end != nil { return self.beginning!.daysEarlier(than: self.end!) } @@ -81,7 +81,7 @@ public extension TimePeriodProtocol { * The duration of the `TimePeriod` in hours. * Returns the max int if beginning or end are nil. */ - public var hours: Int { + var hours: Int { if self.beginning != nil && self.end != nil { return self.beginning!.hoursEarlier(than: self.end!) } @@ -92,7 +92,7 @@ public extension TimePeriodProtocol { * The duration of the `TimePeriod` in minutes. * Returns the max int if beginning or end are nil. */ - public var minutes: Int { + var minutes: Int { if self.beginning != nil && self.end != nil { return self.beginning!.minutesEarlier(than: self.end!) } @@ -103,7 +103,7 @@ public extension TimePeriodProtocol { * The duration of the `TimePeriod` in seconds. * Returns the max int if beginning or end are nil. */ - public var seconds: Int { + var seconds: Int { if self.beginning != nil && self.end != nil { return self.beginning!.secondsEarlier(than: self.end!) } @@ -114,7 +114,7 @@ public extension TimePeriodProtocol { * The duration of the `TimePeriod` in a time chunk. * Returns a time chunk with all zeroes if beginning or end are nil. */ - public var chunk: TimeChunk { + var chunk: TimeChunk { if beginning != nil && end != nil { return beginning!.chunkBetween(date: end!) } @@ -125,15 +125,12 @@ public extension TimePeriodProtocol { * The length of time between the beginning and end dates of the * `TimePeriod` as a `TimeInterval`. */ - public var duration: TimeInterval { + var duration: TimeInterval { if self.beginning != nil && self.end != nil { return abs(self.beginning!.timeIntervalSince(self.end!)) } - #if os(Linux) - return TimeInterval(Double.greatestFiniteMagnitude) - #else - return TimeInterval(DBL_MAX) - #endif + + return TimeInterval(Double.greatestFiniteMagnitude) } @@ -150,7 +147,7 @@ public extension TimePeriodProtocol { * * - returns: The relationship between self and the given time period */ - public func relation(to period: TimePeriodProtocol) -> Relation { + func relation(to period: TimePeriodProtocol) -> Relation { //Make sure that all start and end points exist for comparison if (self.beginning != nil && self.end != nil && period.beginning != nil && period.end != nil) { //Make sure time periods are of positive durations @@ -210,7 +207,7 @@ public extension TimePeriodProtocol { * * - returns: True if the periods are the same */ - public func equals(_ period: TimePeriodProtocol) -> Bool { + func equals(_ period: TimePeriodProtocol) -> Bool { return self.beginning == period.beginning && self.end == period.end } @@ -222,7 +219,7 @@ public extension TimePeriodProtocol { * * - returns: True if self is inside of the given `TimePeriod` */ - public func isInside(of period: TimePeriodProtocol) -> Bool { + func isInside(of period: TimePeriodProtocol) -> Bool { return period.beginning!.isEarlierThanOrEqual(to: self.beginning!) && period.end!.isLaterThanOrEqual(to: self.end!) } @@ -234,7 +231,7 @@ public extension TimePeriodProtocol { * * - returns: True if the given `TimePeriod` is inside of self */ - public func contains(_ date: Date, interval: Interval) -> Bool { + func contains(_ date: Date, interval: Interval) -> Bool { if (interval == .open) { return self.beginning!.isEarlier(than: date) && self.end!.isLater(than: date) } @@ -253,7 +250,7 @@ public extension TimePeriodProtocol { * * - returns: True if the given `TimePeriod` is inside of self */ - public func contains(_ period: TimePeriodProtocol) -> Bool { + func contains(_ period: TimePeriodProtocol) -> Bool { return self.beginning!.isEarlierThanOrEqual(to: period.beginning!) && self.end!.isLaterThanOrEqual(to: period.end!) } @@ -264,7 +261,7 @@ public extension TimePeriodProtocol { * * - returns: True if there is a period of time that is shared by both `TimePeriod`s */ - public func overlaps(with period: TimePeriodProtocol) -> Bool { + func overlaps(with period: TimePeriodProtocol) -> Bool { //Outside -> Inside if (period.beginning!.isEarlier(than: self.beginning!) && period.end!.isLater(than: self.beginning!)) { return true @@ -287,7 +284,7 @@ public extension TimePeriodProtocol { * * - returns: True if there is a period of time or moment that is shared by both `TimePeriod`s */ - public func intersects(with period: TimePeriodProtocol) -> Bool { + func intersects(with period: TimePeriodProtocol) -> Bool { return self.relation(to: period) != .after && self.relation(to: period) != .before } @@ -298,7 +295,7 @@ public extension TimePeriodProtocol { * * - returns: True if there is a period of time between self and the given `TimePeriod` not contained by either period */ - public func hasGap(between period: TimePeriodProtocol) -> Bool { + func hasGap(between period: TimePeriodProtocol) -> Bool { return self.isBefore(period: period) || self.isAfter(period: period) } @@ -309,7 +306,7 @@ public extension TimePeriodProtocol { * * - returns: The gap between the periods. Zero if there is no gap. */ - public func gap(between period: TimePeriodProtocol) -> TimeInterval { + func gap(between period: TimePeriodProtocol) -> TimeInterval { if (self.end!.isEarlier(than: period.beginning!)) { return abs(self.end!.timeIntervalSince(period.beginning!)); } @@ -327,7 +324,7 @@ public extension TimePeriodProtocol { * * - returns: The gap between the periods, zero if there is no gap */ - public func gap(between period: TimePeriodProtocol) -> TimeChunk? { + func gap(between period: TimePeriodProtocol) -> TimeChunk? { if self.end != nil && period.beginning != nil { return (self.end?.chunkBetween(date: period.beginning!))! } @@ -341,7 +338,7 @@ public extension TimePeriodProtocol { * * - returns: True if self is after the given `TimePeriod` */ - public func isAfter(period: TimePeriodProtocol) -> Bool { + func isAfter(period: TimePeriodProtocol) -> Bool { return self.relation(to: period) == .after } @@ -352,7 +349,7 @@ public extension TimePeriodProtocol { * * - returns: True if self is after the given `TimePeriod` */ - public func isBefore(period: TimePeriodProtocol) -> Bool { + func isBefore(period: TimePeriodProtocol) -> Bool { return self.relation(to: period) == .before } @@ -365,7 +362,7 @@ public extension TimePeriodProtocol { * * - parameter timeInterval: The time interval to shift the period by */ - public mutating func shift(by timeInterval: TimeInterval) { + mutating func shift(by timeInterval: TimeInterval) { self.beginning?.addTimeInterval(timeInterval) self.end?.addTimeInterval(timeInterval) } @@ -375,7 +372,7 @@ public extension TimePeriodProtocol { * * - parameter chunk: The time chunk to shift the period by */ - public mutating func shift(by chunk: TimeChunk) { + mutating func shift(by chunk: TimeChunk) { self.beginning = self.beginning?.add(chunk) self.end = self.end?.add(chunk) } @@ -391,7 +388,7 @@ public extension TimePeriodProtocol { * - parameter timeInterval: The time interval to lengthen the period by * - parameter anchor: The anchor point from which to make the change */ - public mutating func lengthen(by timeInterval: TimeInterval, at anchor: Anchor) { + mutating func lengthen(by timeInterval: TimeInterval, at anchor: Anchor) { switch anchor { case .beginning: self.end = self.end?.addingTimeInterval(timeInterval) @@ -412,7 +409,7 @@ public extension TimePeriodProtocol { * - parameter chunk: The time chunk to lengthen the period by * - parameter anchor: The anchor point from which to make the change */ - public mutating func lengthen(by chunk: TimeChunk, at anchor: Anchor) { + mutating func lengthen(by chunk: TimeChunk, at anchor: Anchor) { switch anchor { case .beginning: self.end = self.end?.add(chunk) @@ -433,7 +430,7 @@ public extension TimePeriodProtocol { * - parameter timeInterval: The time interval to shorten the period by * - parameter anchor: The anchor point from which to make the change */ - public mutating func shorten(by timeInterval: TimeInterval, at anchor: Anchor) { + mutating func shorten(by timeInterval: TimeInterval, at anchor: Anchor) { switch anchor { case .beginning: self.end = self.end?.addingTimeInterval(-timeInterval) @@ -454,7 +451,7 @@ public extension TimePeriodProtocol { * - parameter chunk: The time chunk to shorten the period by * - parameter anchor: The anchor point from which to make the change */ - public mutating func shorten(by chunk: TimeChunk, at anchor: Anchor) { + mutating func shorten(by chunk: TimeChunk, at anchor: Anchor) { switch anchor { case .beginning: self.end = self.end?.subtract(chunk) diff --git a/DateToolsSwift/DateTools/TimePeriodGroup.swift b/DateToolsSwift/DateTools/TimePeriodGroup.swift index 6b1e51c2..240bda11 100644 --- a/DateToolsSwift/DateTools/TimePeriodGroup.swift +++ b/DateToolsSwift/DateTools/TimePeriodGroup.swift @@ -63,6 +63,11 @@ open class TimePeriodGroup: Sequence { return nil } + // MARK: - Initializers + + public init() { + + } // MARK: - Comparisons @@ -97,7 +102,7 @@ open class TimePeriodGroup: Sequence { } public func split(maxSplits: Int, omittingEmptySubsequences: Bool, whereSeparator isSeparator: (TimePeriodProtocol) throws -> Bool) rethrows -> [AnySequence] { - return try periods.split(maxSplits: maxSplits, omittingEmptySubsequences: omittingEmptySubsequences, whereSeparator: isSeparator) + return try periods.split(maxSplits: maxSplits, omittingEmptySubsequences: omittingEmptySubsequences, whereSeparator: isSeparator).map(AnySequence.init) } subscript(index: Int) -> TimePeriodProtocol { @@ -115,7 +120,7 @@ open class TimePeriodGroup: Sequence { return false // No need to sorting if they already have different counts } - var compArray1: [TimePeriodProtocol] = array1.sorted { (period1: TimePeriodProtocol, period2: TimePeriodProtocol) -> Bool in + let compArray1: [TimePeriodProtocol] = array1.sorted { (period1: TimePeriodProtocol, period2: TimePeriodProtocol) -> Bool in if period1.beginning == nil && period2.beginning == nil { return false } else if (period1.beginning == nil) { @@ -126,7 +131,7 @@ open class TimePeriodGroup: Sequence { return period2.beginning! < period1.beginning! } } - var compArray2: [TimePeriodProtocol] = array2.sorted { (period1: TimePeriodProtocol, period2: TimePeriodProtocol) -> Bool in + let compArray2: [TimePeriodProtocol] = array2.sorted { (period1: TimePeriodProtocol, period2: TimePeriodProtocol) -> Bool in if period1.beginning == nil && period2.beginning == nil { return false } else if (period1.beginning == nil) { diff --git a/DateToolsSwift/Tests/DateToolsTests/DateToolsTests.xcodeproj/project.pbxproj b/DateToolsSwift/Tests/DateToolsTests/DateToolsTests.xcodeproj/project.pbxproj index bf3cee48..02fb98d6 100644 --- a/DateToolsSwift/Tests/DateToolsTests/DateToolsTests.xcodeproj/project.pbxproj +++ b/DateToolsSwift/Tests/DateToolsTests/DateToolsTests.xcodeproj/project.pbxproj @@ -10,7 +10,6 @@ 562371581DBA6AF50083DF30 /* Date+Manipulations.swift in Sources */ = {isa = PBXBuildFile; fileRef = 562371571DBA6AF50083DF30 /* Date+Manipulations.swift */; }; 5623715A1DBA6E810083DF30 /* Date+Bundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 562371591DBA6E810083DF30 /* Date+Bundle.swift */; }; 5658E3801D6B559900D1465A /* TimePeriodTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5658E35B1D67782D00D1465A /* TimePeriodTests.swift */; }; - 5658E3811D6B55C800D1465A /* Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 5658E37A1D6B556B00D1465A /* Info.plist */; }; 56890C711D771BA8004E8959 /* TimePeriodCollectionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56890C701D771BA8004E8959 /* TimePeriodCollectionTests.swift */; }; 56890C731D771BB8004E8959 /* TimePeriodChainTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56890C721D771BB8004E8959 /* TimePeriodChainTests.swift */; }; 568CC77E1D9EC2FE000D614D /* DateManipulationsExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 568CC77D1D9EC2FE000D614D /* DateManipulationsExtensionTests.swift */; }; @@ -257,7 +256,7 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0800; - LastUpgradeCheck = 0800; + LastUpgradeCheck = 1130; ORGANIZATIONNAME = "Matthew York"; TargetAttributes = { 5658E3751D6B556B00D1465A = { @@ -279,6 +278,7 @@ developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( + English, en, Base, ); @@ -298,7 +298,6 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 5658E3811D6B55C800D1465A /* Info.plist in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -398,7 +397,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = edu.ua.caps.DateToolsTestsTests; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 4.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/DateToolsTests.app/DateToolsTests"; }; name = Debug; @@ -412,7 +411,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = edu.ua.caps.DateToolsTestsTests; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 4.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/DateToolsTests.app/DateToolsTests"; }; name = Release; @@ -421,20 +420,30 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_SUSPICIOUS_MOVES = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; @@ -457,12 +466,13 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.2; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; @@ -471,20 +481,30 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_SUSPICIOUS_MOVES = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; @@ -501,10 +521,11 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.2; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; @@ -519,7 +540,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.github.matthewyork.DateToolsTests; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 5.0; }; name = Debug; }; @@ -532,7 +553,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.github.matthewyork.DateToolsTests; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 5.0; }; name = Release; }; diff --git a/DateToolsSwift/Tests/DateToolsTests/DateToolsTests/AppDelegate.swift b/DateToolsSwift/Tests/DateToolsTests/DateToolsTests/AppDelegate.swift index a12762ec..067f8962 100644 --- a/DateToolsSwift/Tests/DateToolsTests/DateToolsTests/AppDelegate.swift +++ b/DateToolsSwift/Tests/DateToolsTests/DateToolsTests/AppDelegate.swift @@ -14,7 +14,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? - func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // Override point for customization after application launch. return true } diff --git a/DateToolsSwift/Tests/DateToolsTests/DateToolsTestsTests/DateComponentsExtensionTests.swift b/DateToolsSwift/Tests/DateToolsTests/DateToolsTestsTests/DateComponentsExtensionTests.swift index 5a7df836..98d0b8c1 100644 --- a/DateToolsSwift/Tests/DateToolsTests/DateToolsTestsTests/DateComponentsExtensionTests.swift +++ b/DateToolsSwift/Tests/DateToolsTests/DateToolsTestsTests/DateComponentsExtensionTests.swift @@ -36,28 +36,29 @@ class DateComponentsTests: XCTestCase { XCTAssertFalse(testDate.ordinality(of: .day, in: .year) == controlDate.ordinality(of: .day, in: .year)) } - func testUnit() { - let testDate = self.formatter.date(from: "2014 05 26 18:15:12.000")! - let testDate2 = self.formatter.date(from: "2012 05 26 18:15:12.000")! - let testDate3 = self.formatter.date(from: "2012 02 26 18:15:12.000")! - XCTAssertTrue(testDate.unit(of: .month, in: .year) == 12) - XCTAssertTrue(testDate.unit(of: .day, in: .month) == 31) - XCTAssertTrue(testDate.unit(of: .day, in: .year) == 365) - XCTAssertTrue(testDate.unit(of: .hour, in: .year) == 365 * 24) - XCTAssertTrue(testDate.unit(of: .minute, in: .day) == 60 * 24) - XCTAssertTrue(testDate.unit(of: .day, in: .minute) == nil) - XCTAssertTrue(testDate.unit(of: .second, in: .minute) == 60) - XCTAssertTrue(testDate.unit(of: .weekday, in: .month) == nil) - XCTAssertTrue(testDate.unit(of: .second, in: .month) == 60 * 60 * 24 * 31) - XCTAssertTrue(testDate.unit(of: .second, in: .year) == 60 * 60 * 24 * 365) - // Leap year test - XCTAssertTrue(testDate2.unit(of: .day, in: .year) == 366) - XCTAssertTrue(testDate2.unit(of: .hour, in: .year) == 366 * 24) - XCTAssertTrue(testDate2.unit(of: .second, in: .year) == 60 * 60 * 24 * 366) - XCTAssertTrue(testDate3.unit(of: .day, in: .month) == 29) - // Equality test - XCTAssertTrue(testDate.unit(of: .day, in: .month)! == controlDate.unit(of: .day, in: .month)! + 1) - } +// func testUnit() { +// let testDate = self.formatter.date(from: "2014 05 26 18:15:12.000")! +// let testDate2 = self.formatter.date(from: "2012 05 26 18:15:12.000")! +// let testDate3 = self.formatter.date(from: "2012 02 26 18:15:12.000")! +// +// XCTAssertTrue(testDate.unit(of: .month, in: .year) == 12) +// XCTAssertTrue(testDate.unit(of: .day, in: .month) == 31) +// XCTAssertTrue(testDate.unit(of: .day, in: .year) == 365) +// XCTAssertTrue(testDate.unit(of: .hour, in: .year) == 365 * 24) +// XCTAssertTrue(testDate.unit(of: .minute, in: .day) == 60 * 24) +// XCTAssertTrue(testDate.unit(of: .day, in: .minute) == nil) +// XCTAssertTrue(testDate.unit(of: .second, in: .minute) == 60) +// XCTAssertTrue(testDate.unit(of: .weekday, in: .month) == nil) +// XCTAssertTrue(testDate.unit(of: .second, in: .month) == 60 * 60 * 24 * 31) +// XCTAssertTrue(testDate.unit(of: .second, in: .year) == 60 * 60 * 24 * 365) +// // Leap year test +// XCTAssertTrue(testDate2.unit(of: .day, in: .year) == 366) +// XCTAssertTrue(testDate2.unit(of: .hour, in: .year) == 366 * 24) +// XCTAssertTrue(testDate2.unit(of: .second, in: .year) == 60 * 60 * 24 * 366) +// XCTAssertTrue(testDate3.unit(of: .day, in: .month) == 29) +// // Equality test +// XCTAssertTrue(testDate.unit(of: .day, in: .month)! == controlDate.unit(of: .day, in: .month)! + 1) +// } // MARK: - Components diff --git a/Examples/DateToolsExample/DateTools macOS/DateTools macOS.h b/Examples/DateToolsExample/DateTools macOS/DateTools macOS.h new file mode 100644 index 00000000..5d913b53 --- /dev/null +++ b/Examples/DateToolsExample/DateTools macOS/DateTools macOS.h @@ -0,0 +1,19 @@ +// +// DateTools macOS.h +// DateTools macOS +// +// Created by Tom Baranes on 22/09/2016. +// +// + +#import + +//! Project version number for DateTools macOS. +FOUNDATION_EXPORT double DateTools_macOSVersionNumber; + +//! Project version string for DateTools macOS. +FOUNDATION_EXPORT const unsigned char DateTools_macOSVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + + diff --git a/Examples/DateToolsExample/DateTools macOS/Info.plist b/Examples/DateToolsExample/DateTools macOS/Info.plist new file mode 100644 index 00000000..fbe1e6b3 --- /dev/null +++ b/Examples/DateToolsExample/DateTools macOS/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSPrincipalClass + + + diff --git a/Examples/DateToolsExample/DateToolsExample.xcodeproj/xcshareddata/xcschemes/DateTools macOS.xcscheme b/Examples/DateToolsExample/DateToolsExample.xcodeproj/xcshareddata/xcschemes/DateTools macOS.xcscheme new file mode 100644 index 00000000..1607381f --- /dev/null +++ b/Examples/DateToolsExample/DateToolsExample.xcodeproj/xcshareddata/xcschemes/DateTools macOS.xcscheme @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Package.swift b/Package.swift index 5219f31a..3055e681 100644 --- a/Package.swift +++ b/Package.swift @@ -1,9 +1,36 @@ +// swift-tools-version:5.3 +// The swift-tools-version declares the minimum version of Swift required to build this package. import PackageDescription let package = Package( - name: "DateTools", + name: "DateToolsSwift", + defaultLocalization: "en", + platforms: [ + .iOS(.v12), + .tvOS(.v12), + .macOS(.v10_13), + ], + products: [ + .library(name: "DateToolsSwift", targets: ["DateToolsSwift"]), + .library(name: "DateToolsObjc", targets: ["DateToolsObjc"]) + ], + dependencies: [ + ], targets: [ - Target(name: "DateTools") + .target( + name: "DateToolsSwift", + path: "DateToolsSwift/DateTools", + resources: [.copy("DateTools.bundle")], + swiftSettings: [.define("SPM")] + ), + .target( + name: "DateToolsObjc", + path: "DateTools/DateTools", + resources: [.copy("DateTools.bundle")], + publicHeadersPath: ".", + cSettings: [.define("SPM")] + ) ] ) -package.exclude = ["Examples", "Tests"] + + diff --git a/README.md b/README.md index a0f0b646..eb561e46 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,14 @@ -![Banner](https://raw.githubusercontent.com/MatthewYork/Resources/master/DateTools/DateToolsHeader.png) +![Banner](https://raw.githubusercontent.com/MatthewYork/Resources/master/DateTools/DateToolsHeader2.png) ## DateTools -DateTools was written to streamline date and time handling in Objective-C. Classes and concepts from other languages served as an inspiration for DateTools, especially the [DateTime](http://msdn.microsoft.com/en-us/library/system.datetime(v=vs.110).aspx) structure and [Time Period Library](http://www.codeproject.com/Articles/168662/Time-Period-Library-for-NET) for .NET. Through these classes and others, DateTools removes the boilerplate required to access date components, handles more nuanced date comparisons, and serves as the foundation for entirely new concepts like Time Periods and their collections. +DateTools was written to streamline date and time handling in iOS. Classes and concepts from other languages served as an inspiration for DateTools, especially the [DateTime](http://msdn.microsoft.com/en-us/library/system.datetime(v=vs.110).aspx) structure and [Time Period Library](http://www.codeproject.com/Articles/168662/Time-Period-Library-for-NET) for .NET. Through these classes and others, DateTools removes the boilerplate required to access date components, handles more nuanced date comparisons, and serves as the foundation for entirely new concepts like Time Periods and their collections. [![Build Status](https://travis-ci.org/MatthewYork/DateTools.svg?branch=master)](https://travis-ci.org/MatthewYork/DateTools) [![CocoaPods](https://cocoapod-badges.herokuapp.com/v/DateTools/badge.png)](http://cocoapods.org/?q=datetools) +[![CocoaPods](https://cocoapod-badges.herokuapp.com/v/DateToolsSwift/badge.png)](http://cocoapods.org/?q=datetoolsswift) -####Featured In +#### Featured In + - + +
@@ -23,28 +24,62 @@ DateTools was written to streamline date and time handling in Objective-C. Class - + + +
Yahoo! Livetext My Disney Experience ALDI GuidebookPitch Locator ProYoutube MusicKhan Academy
+#### Donate + + +bitcoin: 17ZEBFw5peuoUwYaEJeGkpoJwP1htViLUY + ## Installation **CocoaPods** +Swift + +pod 'DateToolsSwift' + +Objective-C (Legacy) + pod 'DateTools' **Manual Installation** All the classes required for DateTools are located in the DateTools folder in the root of this repository. They are listed below: +Swift (Found in DateToolsSwift/DateTools) +* Constants.swift +* Date+Bundle.swift +* Date+Comparators.swift +* Date+Components.swift +* Date+Format.swift +* Date+Inits.swift +* Date+Manipulations.swift +* Date+TimeAgo.swift +* DateTools.bundle +* Enums.swift +* Integer.DateTools.swift +* TimeChunk.swift +* TimePeriod.swift +* TimePeriodChain.swift +* TimePeriodCollection.swift +* TimePeriodGroup.swift + +Objective-C (Found in DateTools/DateTools) * DateTools.h * NSDate+DateTools.{h,m} * DTConstants.h @@ -62,7 +97,7 @@ The following bundle is necessary if you would like to support internationalizat ## Table of Contents -* [**NSDate+DateTools**](#nsdate-datetools) +* [**DateTools**](#datetools) * [Time Ago](#time-ago) * [Date Components](#date-components) * [Date Editing](#date-editing) @@ -80,22 +115,24 @@ The following bundle is necessary if you would like to support internationalizat * [**Credits**](#credits) * [**License**](#license) -##NSDate+DateTools +## DateTools + +**Full code documentation can be found [here](http://cocoadocs.org/docsets/DateToolsSwift/2.0.0/)** -One of the missions of DateTools was to make NSDate feel more complete. There are many other languages that allow direct access to information about dates from their date classes, but NSDate (sadly) does not. It safely works only in the Unix time offsets through the timeIntervalSince... methods for building dates and remains calendar agnostic. But that's not always what we want to do. Sometimes, we want to work with dates based on their date components (like year, month, day, etc) at a more abstract level. This is where DateTools comes in. +One of the missions of DateTools was to make Date feel more complete. There are many other languages that allow direct access to information about dates from their date classes, but Date (sadly) does not. It safely works only in the Unix time offsets through the timeIntervalSince... methods for building dates and remains calendar agnostic. But that's not always what we want to do. Sometimes, we want to work with dates based on their date components (like year, month, day, etc) at a more abstract level. This is where DateTools comes in. -####Time Ago +#### Time Ago No date library would be complete without the ability to quickly make an NSString based on how much earlier a date is than now. DateTools has you covered. These "time ago" strings come in a long and short form, with the latter closely resembling Twitter. You can get these strings like so: -```objc -NSDate *timeAgoDate = [NSDate dateWithTimeIntervalSinceNow:-4]; -NSLog(@"Time Ago: %@", timeAgoDate.timeAgoSinceNow); -NSLog(@"Time Ago: %@", timeAgoDate.shortTimeAgoSinceNow); +```swift +let timeAgoDate = 2.days.earlier +print("Time Ago: ", timeAgoDate.timeAgoSinceNow) +print("Time Ago: ", timeAgoDate.shortTimeAgoSinceNow) //Output: -//Time Ago: 4 seconds ago -//Time Ago: 4s +//Time Ago: 2 days ago +//Time Ago: 2d ``` Assuming you have added the localization to your project, `DateTools` currently supports the following languages: @@ -145,39 +182,31 @@ This project is user driven (by people like you). Pull requests close faster tha Thanks to Kevin Lawler for his work on [NSDate+TimeAgo](https://github.com/kevinlawler/NSDate-TimeAgo), which has been officially merged into this library. -####Date Components +#### Date Components -There is a lot of boilerplate associated with getting date components from an NSDate. You have to set up a calendar, use the desired flags for the components you want, and finally extract them out of the calendar. +There is a lot of boilerplate associated with getting date components from an Date. You have to set up a calendar, use the desired flags for the components you want, and finally extract them out of the calendar. With DateTools, this: -```objc +```swift //Create calendar -NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; -unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit; -NSDateComponents *dateComponents = [calendar components:unitFlags fromDate:date]; - +let calendar = Calendar(identifier: .gregorian) +let dateComponents = calendar.dateComponents(Set([.month,.year]), from: Date()) + //Get components -NSInteger year = dateComponents.year; -NSInteger month = dateComponents.month; +let year = dateComponents.year! +let month = dateComponents.month! ``` ...becomes this: -```objc -NSInteger year = date.year; -NSInteger month = date.month; -``` - -And if you would like to use a non-Gregorian calendar, that option is available as well. -```objc -NSInteger day = [date dayWithCalendar:calendar]; +```swift +let year = Date().year +let month = Date().month ``` -If you would like to override the default calendar that DateTools uses, simply change it in the defaultCalendar method of NSDate+DateTools.m. - -####Date Editing +#### Date Editing -The date editing methods in NSDate+DateTools makes it easy to shift a date earlier or later by adding and subtracting date components. For instance, if you would like a date that is 1 year later from a given date, simply call the method dateByAddingYears. +The date editing methods in DateTools makes it easy to shift a date earlier or later by adding and subtracting date components. For instance, if you would like a date that is 1 year later from a given date, simply call the method dateByAddingYears. With DateTools, this: ```objc @@ -199,9 +228,9 @@ NSDate *newDate = [date dateByAddingYears:1]; Subtraction of date components is also fully supported through the dateBySubtractingYears -####Date Comparison +#### Date Comparison -Another mission of the DateTools category is to greatly increase the flexibility of date comparisons. NSDate gives you four basic methods: +Another mission of the DateTools category is to greatly increase the flexibility of date comparisons. Date gives you four basic methods: * isEqualToDate: * earlierDate: * laterDate: @@ -213,7 +242,7 @@ Another mission of the DateTools category is to greatly increase the flexibility * isLaterThan * isLaterThanOrEqualTo -These methods are great for comparing dates in a boolean fashion, but what if we want to compare the dates and return some meaningful information about how far they are apart? NSDate comes with two methods timeIntervalSinceDate: and timeIntervalSinceNow which gives you a double offset representing the number of seconds between the two dates. This is great and all, but there are times when one wants to know how many years or days are between two dates. For this, DateTools goes back to the ever-trusty NSCalendar and abstracts out all the necessary code for you. +These methods are great for comparing dates in a boolean fashion, but what if we want to compare the dates and return some meaningful information about how far they are apart? Date comes with two methods timeIntervalSinceDate: and timeIntervalSinceNow which gives you a double offset representing the number of seconds between the two dates. This is great and all, but there are times when one wants to know how many years or days are between two dates. For this, DateTools goes back to the ever-trusty NSCalendar and abstracts out all the necessary code for you. With Date Tools, this: ```objc @@ -237,17 +266,17 @@ Methods for comparison in this category include: * minutesFrom:, minutesUntil, minutesAgo, minutesEarlierThan:, minutesLaterThan: * secondsFrom:, secondsUntil, secondsAgo, secondsEarlierThan:, secondsLaterThan: -####Formatted Date Strings +#### Formatted Date Strings Just for kicks, DateTools has a few convenience methods for quickly creating strings from dates. Those two methods are formattedDateWithStyle: and formattedDateWithFormat:. The current locale is used unless otherwise specified by additional method parameters. Again, just for kicks, really. -##Time Periods +## Time Periods -Dates are important, but the real world is a little less discrete than that. Life is made up of spans of time, like an afternoon appointment or a weeklong vacation. In DateTools, time periods are represented by the DTTimePeriod class and come with a suite of initializaiton, manipulation, and comparison methods to make working with them a breeze. +Dates are important, but the real world is a little less discrete than that. Life is made up of spans of time, like an afternoon appointment or a weeklong vacation. In DateTools, time periods are represented by the TimePeriod class and come with a suite of initializaiton, manipulation, and comparison methods to make working with them a breeze. -####Initialization +#### Initialization -Time peroids consist of an NSDate start date and end date. To initialize a time period, call the init function. +Time peroids consist of an Date start date and end date. To initialize a time period, call the init function. ```objc DTTimePeriod *timePeriod = [[DTTimePeriod alloc] initWithStartDate:startDate endDate:endDate]; @@ -257,15 +286,15 @@ or, if you would like to create a time period of a known length that starts or e DTTimePeriod *timePeriod = [DTTimePeriod timePeriodWithSize:DTTimePeriodSizeHour amount:5 startingAt:[NSDate date]]; ``` -####Time Period Info +#### Time Period Info -A host of methods have been extended to give information about an instance of DTTimePeriod. A few are listed below +A host of methods have been extended to give information about an instance of TimePeriod. A few are listed below * hasStartDate - Returns true if the period has a start date * hasEndDate - Returns true if the period has an end date * isMoment - Returns true if the period has the same start and end date * durationIn.... - Returns the length of the time period in the requested units -####Manipulation +#### Manipulation Time periods may also be manipulated. They may be shifted earlier or later as well as expanded and contracted. @@ -285,11 +314,9 @@ DTTimePeriod *timePeriod = [DTTimePeriod timePeriodWithSize:DTTimePeriodSizeMin ``` This doubles a time period of duration 1 minute to duration 2 minutes. The end date of "now" is retained and only the start date is shifted 1 minute earlier. -####Relationships +#### Relationships -There may come a need, say when you are making a scheduling app, when it might be good to know how two time periods relate to one another. Are they the same? Is one inside of another? All these questions may be asked using the relationship methods of DTTimePeriod. - -**The Basics** +There may come a need, say when you are making a scheduling app, when it might be good to know how two time periods relate to one another. Are they the same? Is one inside of another? All these questions may be asked using the relationship methods of TimePeriod. Below is a chart of all the possible relationships between two time periods: ![TimePeriods](https://raw.githubusercontent.com/MatthewYork/Resources/master/DateTools/PeriodRelations.png) @@ -305,19 +332,19 @@ You can also check for the official relationship (like those shown in the chart) ```objc -(DTTimePeriodRelation)relationToPeriod:(DTTimePeriod *)period; ``` -All of the possible relationships have been enumerated in the DTTimePeriodRelation enum. +All of the possible relationships have been enumerated in the TimePeriodRelation enum. **For a better grasp on how time periods relate to one another, check out the "Time Periods" tab in the example application. Here you can slide a few time periods around and watch their relationships change.** ![TimePeriods](https://raw.githubusercontent.com/MatthewYork/Resources/master/DateTools/TimePeriodsDemo.gif) -##Time Period Groups +## Time Period Groups -Time period groups are the final abstraction of date and time in DateTools. Here, time periods are gathered and organized into something useful. There are two main types of time period groups, DTTimePeriodCollection and DTTimePeriodChain. At a high level, think about a collection as a loose group where overlaps may occur and a chain a more linear, tight group where overlaps are not allowed. +Time period groups are the final abstraction of date and time in DateTools. Here, time periods are gathered and organized into something useful. There are two main types of time period groups, TimePeriodCollection and TimePeriodChain. At a high level, think about a collection as a loose group where overlaps may occur and a chain a more linear, tight group where overlaps are not allowed. -Both collections and chains operate like an NSArray. You may add,insert and remove DTTimePeriod objects from them just as you would objects in an array. The difference is how these periods are handled under the hood. +Both collections and chains operate like an NSArray. You may add,insert and remove TimePeriod objects from them just as you would objects in an array. The difference is how these periods are handled under the hood. -###Time Period Collections +### Time Period Collections Time period collections serve as loose sets of time periods. They are unorganized unless you decide to sort them, and have their own characteristics like a StartDate and EndDate that are extrapolated from the time periods within. Time period collections allow overlaps within their set of time periods. ![TimePeriodCollections](https://raw.githubusercontent.com/MatthewYork/Resources/master/DateTools/TimePeriodCollection.png) @@ -346,11 +373,11 @@ Sorting time periods in a collection is easy, just call one of the sort methods. * **Time Period Duration** - sortByDurationAscending, sortByDurationDescending **Operations** -It is also possible to check an NSDate's or DTTimePeriod's relationship to the collection. For instance, if you would like to see all the time periods that intersect with a certain date, you can call the periodsIntersectedByDate: method. The result is a new DTTimePeriodCollection with all those periods that intersect the provided date. There are a host of other methods to try out as well, including a full equality check between two collections. +It is also possible to check an Date's or TimePeriod's relationship to the collection. For instance, if you would like to see all the time periods that intersect with a certain date, you can call the periodsIntersectedByDate: method. The result is a new TimePeriodCollection with all those periods that intersect the provided date. There are a host of other methods to try out as well, including a full equality check between two collections. ![TimePeriodCollectionOperations](https://raw.githubusercontent.com/MatthewYork/Resources/master/DateTools/TimePeriodCollectionOperations.png) -###Time Period Chains +### Time Period Chains Time period chains serve as a tightly coupled set of time periods. They are always organized by start and end date, and have their own characteristics like a StartDate and EndDate that are extrapolated from the time periods within. Time period chains do not allow overlaps within their set of time periods. This type of group is ideal for modeling schedules like sequential meetings or appointments. ![TimePeriodChains](https://raw.githubusercontent.com/MatthewYork/Resources/master/DateTools/TimePeriodChain.png) @@ -379,10 +406,10 @@ Like collections, chains have an equality check and the ability to be shifted ea ![TimePeriodChainOperations](https://raw.githubusercontent.com/MatthewYork/Resources/master/DateTools/TimePeriodChainOperations.png) -##Documentation +## Documentation All methods and variables have been documented and are available for option+click inspection, just like the SDK classes. This includes an explanation of the methods as well as what their input and output parameters are for. Please raise an issue if you ever feel documentation is confusing or misleading and we will get it fixed up! -##Unit Tests +## Unit Tests Unit tests were performed on all the major classes in the library for quality assurance. You can find theses under the "Tests" folder at the top of the library. There are over 300 test cases in all! @@ -390,7 +417,9 @@ If you ever find a test case that is incomplete, please open an issue so we can Continuous integration testing is performed by Travis CI: [![Build Status](https://travis-ci.org/MatthewYork/DateTools.svg?branch=master)](https://travis-ci.org/MatthewYork/DateTools) -##Credits +## Credits + +Many thanks to [Grayson Webster](https://github.com/GraysonWebster) for helping rethink DateTools for Swift and crank out the necessary code! Thanks to [Kevin Lawler](https://github.com/kevinlawler) for his initial work on NSDate+TimeAgo. It laid the foundation for DateTools' timeAgo methods. You can find this great project [here](https://github.com/kevinlawler/NSDate-TimeAgo). @@ -400,7 +429,7 @@ Images were first published through itenso.com through [Code Project](http://www I would also like to thank **God** through whom all things live and move and have their being. [Acts 17:28](http://www.biblegateway.com/passage/?search=Acts+17%3A16-34&version=NIV) -##License +## License The MIT License (MIT)