我喜歡在獅子座的解決方案的API,並用它。然而,當我運行它時,我遇到了問題(2015年6月13日上午9:33)。症狀是:
當日期是將來,xFromToday功能正在返回 結果 - (叔-Δ)(例如,用於在未來1個月 XFromToday函數將返回(0, -4,-29,-719, -43199)對於x =(月,周,日,小時,分鐘)。relativeDates字符串將返回「從今天起1周」
當日期在過去,結果將是-t,除了相對日期字符串爲 。例如,過去一個月,I 會得到(1,4,31,744,44640)。日期的字符串是:「4周 和744個小時」
我不能測試輸出粘貼由於機密性,但是具有NSDate.test()的代碼被粘貼。它也沒有其他的東西從另一篇帖子(用代碼引用)和我寫的一些格式化東西中借用。
import Foundation
// https://stackoverflow.com/questions/27339072/working-with-nsdate-components-in-swift
// **** Use with caution may not do what you expect. See the stackoverflow post above. *******
public extension NSDate {
func xDays(x:Int) -> NSDate {
return NSCalendar.currentCalendar().dateByAddingUnit(.CalendarUnitDay, value: x, toDate: self, options: nil)!
}
func xWeeks(x:Int) -> NSDate {
return NSCalendar.currentCalendar().dateByAddingUnit(.CalendarUnitWeekOfYear, value: x, toDate: self, options: nil)!
}
func xMonths(x:Int) -> NSDate {
return NSCalendar.currentCalendar().dateByAddingUnit(.CalendarUnitMonth, value: x, toDate: self, options: nil)!
}
func xMins(x:Int) -> NSDate {
return NSCalendar.currentCalendar().dateByAddingUnit(.CalendarUnitMinute, value: x, toDate: self, options: nil)!
}
func xHours(x:Int) -> NSDate {
return NSCalendar.currentCalendar().dateByAddingUnit(.CalendarUnitHour, value: x, toDate: self, options: nil)!
}
var hoursFromToday: Int{
return NSCalendar.currentCalendar().components(.CalendarUnitHour, fromDate: self, toDate: NSDate(), options: nil).hour
}
var weeksFromToday: Int{
return NSCalendar.currentCalendar().components(.CalendarUnitWeekOfYear, fromDate: self, toDate: NSDate(), options: nil).weekOfYear
}
var daysFromToday: Int{
return NSCalendar.currentCalendar().components(.CalendarUnitDay, fromDate: self, toDate: NSDate(), options: nil).day
}
var monthsFromToday: Int{
return NSCalendar.currentCalendar().components(.CalendarUnitMonth, fromDate: self, toDate: NSDate(), options: nil).month
}
var minsFromToday: Int{
return NSCalendar.currentCalendar().components(.CalendarUnitMinute, fromDate: self, toDate: NSDate(), options: nil).minute
}
var relativeDateString: String {
if weeksFromToday > 0 { return weeksFromToday > 1 ? "\(weeksFromToday) weeks and \(hoursFromToday) hours" : "\(weeksFromToday) week and \(hoursFromToday) hours" }
if hoursFromToday > 0 { return hoursFromToday > 1 ? "\(hoursFromToday) hours" : "\(hoursFromToday) hour" }
return ""
}
//Date Comparisions
//https://stackoverflow.com/questions/26198526/nsdate-comparison-using-swift
func isGreaterThanDate(dateToCompare : NSDate) -> Bool
{
//Declare Variables
var isGreater = false
//Compare Values
if self.compare(dateToCompare) == NSComparisonResult.OrderedDescending
{
isGreater = true
}
//Return Result
return isGreater
}
func isLessThanDate(dateToCompare : NSDate) -> Bool
{
//Declare Variables
var isLess = false
//Compare Values
if self.compare(dateToCompare) == NSComparisonResult.OrderedAscending
{
isLess = true
}
//Return Result
return isLess
}
// Date printing converstions
var dayMonthYear: String {
let dateMonthYearFormatter: NSDateFormatter = NSDateFormatter()
let currentLocale: NSLocale = NSLocale.currentLocale()
let dateMonthYearFormatString: NSString! = NSDateFormatter.dateFormatFromTemplate("EdMMMyyyy",options: 0, locale: currentLocale)
dateMonthYearFormatter.dateFormat = dateMonthYearFormatString as! String
return dateMonthYearFormatter.stringFromDate(self)
}
var timeDayMonthYear: String {
let dateMonthYearFormatter: NSDateFormatter = NSDateFormatter()
let currentLocale: NSLocale = NSLocale.currentLocale()
let dateMonthYearFormatString: NSString! = NSDateFormatter.dateFormatFromTemplate("EdMMMyyyy' ' HH':'mm",options: 0, locale: currentLocale)
dateMonthYearFormatter.dateFormat = dateMonthYearFormatString as! String
return dateMonthYearFormatter.stringFromDate(self)
}
var hourMin: String {
let hourMinFormatter = NSDateFormatter();
hourMinFormatter.dateFormat = "HH:mm"
return hourMinFormatter.stringFromDate(self)
}
static func rfc3339DateFormatter() -> NSDateFormatter {
let rfc3339DateFormatterRet = NSDateFormatter()
let enUSPOSIXLocale: NSLocale = NSLocale(localeIdentifier: "en_US_POSIX")
rfc3339DateFormatterRet.dateFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'"
rfc3339DateFormatterRet.locale = enUSPOSIXLocale
rfc3339DateFormatterRet.timeZone = NSTimeZone(forSecondsFromGMT: 0)
return rfc3339DateFormatterRet
}
var rfcString: String {
return NSDate.rfc3339DateFormatter().stringFromDate(self)
}
func rfcDate(rfcString: String) -> NSDate {
return NSDate.rfc3339DateFormatter().dateFromString(rfcString)!
}
func changeDate(toDate: NSDate) -> NSDate {
let rfcToDate = toDate.rfcString
let rfcSelf = self.rfcString
let toDateArray : [String] = rfcToDate.componentsSeparatedByString("T")
let selfArray : [String] = rfcSelf.componentsSeparatedByString("T")
return rfcDate(toDateArray[0]+"T"+selfArray[1])
}
static func test(months: Int = 0, weeks: Int = 0, days: Int = 0, hrs: Int = 0, mins: Int = 0) {
NSLog("****************** Start Testing of NSDate **************************")
NSLog("Inputs: months:\(months) weeks:\(weeks) days:\(days) hrs: \(hrs) mins: \(mins)")
var today = NSDate()
NSLog("Today is: \(today.timeDayMonthYear)")
var monthsFromToday = today.xMonths(months)
NSLog("** \(months) months from today: \(monthsFromToday.timeDayMonthYear)")
NSLog("monthsFromToday returns: \(monthsFromToday.monthsFromToday)");
NSLog("weeksFromToday returns: \(monthsFromToday.weeksFromToday)");
NSLog("daysFromToday returns: \(monthsFromToday.daysFromToday)");
NSLog("hoursFromToday returns: \(monthsFromToday.hoursFromToday)");
NSLog("minsFromToday returns: \(monthsFromToday.minsFromToday)");
NSLog("relativeDateString returns: \(monthsFromToday.relativeDateString)")
var weeksFromToday = today.xWeeks(weeks)
NSLog("** \(weeks) weeks from today: \(weeksFromToday.timeDayMonthYear)")
NSLog("weeksFromToday returns: \(weeksFromToday.weeksFromToday)");
NSLog("relativeDateString returns: \(weeksFromToday.relativeDateString)")
var daysFromToday = today.xDays(days)
NSLog("** \(days) days from today: \(daysFromToday.timeDayMonthYear)")
NSLog("daysFromToday returns: \(daysFromToday.daysFromToday)");
NSLog("relativeDateString returns: \(daysFromToday.relativeDateString)")
var hrsFromToday = today.xHours(hrs)
NSLog("** \(hrs) hours from today: \(hrsFromToday.timeDayMonthYear)")
NSLog("hoursFromToday returns: \(hrsFromToday.hoursFromToday)");
NSLog("relativeDateString returns: \(hrsFromToday.relativeDateString)")
var minsFromToday = today.xMins(mins)
NSLog("** \(mins) minutes from today: \(minsFromToday.timeDayMonthYear)")
NSLog("minsFromToday returns: \(minsFromToday.minsFromToday)");
NSLog("relativeDateString returns: \(minsFromToday.relativeDateString)")
NSLog("__________________ End Testing of NSDate _________________________")
}
}
這裏是我所做的「修復」。我添加了santizedDates()函數,它返回「from」和「to」日期以及一個符號乘數(+ 1/-1)。如果將來進行比較,則會在日期範圍內添加1分鐘偏移量。它適用於測試用例。還可以從relativeDateString(capitalizeFirst:Bool = false)生成正確的和人類可讀的輸出,例如:「今天,過去1小時1分鐘」。我已經發布了一個問題,即爲什麼這行爲首先發生在這裏:
NSCalendar.components().minute returning inconsistent values
import Foundation
// https://stackoverflow.com/questions/27339072/working-with-nsdate-components-in-swift
public extension NSDate {
func xDays(x:Int) -> NSDate {
return NSCalendar.currentCalendar().dateByAddingUnit(.CalendarUnitDay, value: x, toDate: self, options: nil)!
}
func xWeeks(x:Int) -> NSDate {
return NSCalendar.currentCalendar().dateByAddingUnit(.CalendarUnitWeekOfYear, value: x, toDate: self, options: nil)!
}
func xMonths(x:Int) -> NSDate {
return NSCalendar.currentCalendar().dateByAddingUnit(.CalendarUnitMonth, value: x, toDate: self, options: nil)!
}
func xMins(x:Int) -> NSDate {
return NSCalendar.currentCalendar().dateByAddingUnit(.CalendarUnitMinute, value: x, toDate: self, options: nil)!
}
func xHours(x:Int) -> NSDate {
return NSCalendar.currentCalendar().dateByAddingUnit(.CalendarUnitHour, value: x, toDate: self, options: nil)!
}
var hoursFromToday: Int{
var fromDate: NSDate = self
var toDate: NSDate = NSDate()
var sign: Int = -1
(fromDate,toDate, sign) = self.sanitizedDates()
return (sign * NSCalendar.currentCalendar().components(.CalendarUnitHour, fromDate: fromDate, toDate: toDate, options: nil).hour)
}
var weeksFromToday: Int{
var fromDate: NSDate = self
var toDate: NSDate = NSDate()
var sign: Int = -1
(fromDate,toDate,sign) = self.sanitizedDates()
return (sign * NSCalendar.currentCalendar().components(.CalendarUnitWeekOfYear, fromDate: fromDate, toDate: toDate, options: nil).weekOfYear)
}
var daysFromToday: Int{
var fromDate: NSDate = self
var toDate: NSDate = NSDate()
var sign: Int = -1
(fromDate,toDate, sign) = self.sanitizedDates()
return (sign * NSCalendar.currentCalendar().components(.CalendarUnitDay, fromDate: fromDate, toDate: toDate, options: nil).day)
}
var monthsFromToday: Int{
var fromDate: NSDate = self
var toDate: NSDate = NSDate()
var sign: Int = -1
(fromDate,toDate, sign) = self.sanitizedDates()
return (sign * NSCalendar.currentCalendar().components(.CalendarUnitMonth, fromDate: fromDate, toDate: toDate, options: nil).month)
}
var minsFromToday: Int{
var fromDate: NSDate = self
var toDate: NSDate = NSDate()
var sign: Int = -1
var offset: Int = 0
(fromDate,toDate,sign) = self.sanitizedDates()
return (sign * NSCalendar.currentCalendar().components(.CalendarUnitMinute, fromDate: fromDate, toDate: toDate, options: nil).minute)
}
func relativeDateString(capitalizeFirst:Bool = false) -> String {
let days: Int = daysFromToday
let mins: Int = minsFromToday % 60
let tense: String = (minsFromToday > 0) ? " in the future" : " in the past"
let hrs: Int = hoursFromToday % 24
var retString = (capitalizeFirst) ? "Now" : "now"
if(minsFromToday != 0) {
if(days == 0) {
retString = (capitalizeFirst) ? "Today" : "today"
retString = (mins != 0 || hrs != 0) ? retString+"," : retString
}
else {
let absDays = abs(days)
retString = "\(absDays)"
retString += (absDays > 1) ? " days" : " day"
}
if(hrs != 0) {
let absHrs = abs(hrs)
retString += " \(absHrs)"
retString += (absHrs > 1) ? " hours" : " hour"
}
if(mins != 0) {
let absMins = abs(mins)
retString += " \(absMins)"
retString += (absMins > 1) ? " minutes" : " minute"
}
retString += tense
}
return retString
}
//Date Comparisons
//https://stackoverflow.com/questions/26198526/nsdate-comparison-using-swift
func isGreaterThanDate(dateToCompare : NSDate) -> Bool
{
//Declare Variables
var isGreater = false
//Compare Values
if self.compare(dateToCompare) == NSComparisonResult.OrderedDescending
{
isGreater = true
}
//Return Result
return isGreater
}
func isLessThanDate(dateToCompare : NSDate) -> Bool
{
//Declare Variables
var isLess = false
//Compare Values
if self.compare(dateToCompare) == NSComparisonResult.OrderedAscending
{
isLess = true
}
//Return Result
return isLess
}
// Date printing converstions
var dayMonthYear: String {
let dateMonthYearFormatter: NSDateFormatter = NSDateFormatter()
let currentLocale: NSLocale = NSLocale.currentLocale()
let dateMonthYearFormatString: NSString! = NSDateFormatter.dateFormatFromTemplate("EdMMMyyyy",options: 0, locale: currentLocale)
dateMonthYearFormatter.dateFormat = dateMonthYearFormatString as! String
return dateMonthYearFormatter.stringFromDate(self)
}
var timeDayMonthYear: String {
let dateMonthYearFormatter: NSDateFormatter = NSDateFormatter()
let currentLocale: NSLocale = NSLocale.currentLocale()
let dateMonthYearFormatString: NSString! = NSDateFormatter.dateFormatFromTemplate("EdMMMyyyy' ' HH':'mm",options: 0, locale: currentLocale)
dateMonthYearFormatter.dateFormat = dateMonthYearFormatString as! String
return dateMonthYearFormatter.stringFromDate(self)
}
var hourMin: String {
let hourMinFormatter = NSDateFormatter();
hourMinFormatter.dateFormat = "HH:mm"
return hourMinFormatter.stringFromDate(self)
}
static func rfc3339DateFormatter() -> NSDateFormatter {
let rfc3339DateFormatterRet = NSDateFormatter()
let enUSPOSIXLocale: NSLocale = NSLocale(localeIdentifier: "en_US_POSIX")
rfc3339DateFormatterRet.dateFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'"
rfc3339DateFormatterRet.locale = enUSPOSIXLocale
rfc3339DateFormatterRet.timeZone = NSTimeZone(forSecondsFromGMT: 0)
return rfc3339DateFormatterRet
}
var rfcString: String {
return NSDate.rfc3339DateFormatter().stringFromDate(self)
}
func rfcDate(rfcString: String) -> NSDate {
return NSDate.rfc3339DateFormatter().dateFromString(rfcString)!
}
func changeDate(toDate: NSDate) -> NSDate {
let rfcToDate = toDate.rfcString
let rfcSelf = self.rfcString
let toDateArray : [String] = rfcToDate.componentsSeparatedByString("T")
let selfArray : [String] = rfcSelf.componentsSeparatedByString("T")
return rfcDate(toDateArray[0]+"T"+selfArray[1])
}
private func sanitizedDates() -> (fromDate: NSDate, toDate: NSDate, sign: Int) {
var toDate: NSDate = self
var fromDate: NSDate = NSDate()
var sign: Int = 1
// For toDates in the past, results are reasonable, except for sign.
//In future dates, we to flip dates to make them past dates and add 1 minute for unknown reason.
if(toDate.isGreaterThanDate(fromDate)) {
// NSLog("****** Flipping dates ********")
toDate = fromDate.xMins(-1) // In this case, the results are consistently shorter by a minute
fromDate = self
sign = -1
}
return (fromDate,toDate,sign)
}
static func test(months: Int = 0, weeks: Int = 0, days: Int = 0, hrs: Int = 0, mins: Int = 0) {
NSLog("****************** Start Testing of NSDate **************************")
NSLog("Inputs: months:\(months) weeks:\(weeks) days:\(days) hrs: \(hrs) mins: \(mins)")
var today = NSDate()
NSLog("Today is: \(today.timeDayMonthYear)")
var monthsFromToday = today.xMonths(months)
NSLog("** \(months) months from today: \(monthsFromToday.timeDayMonthYear)")
NSLog("monthsFromToday returns: \(monthsFromToday.monthsFromToday)");
NSLog("weeksFromToday returns: \(monthsFromToday.weeksFromToday)");
NSLog("daysFromToday returns: \(monthsFromToday.daysFromToday)");
NSLog("hoursFromToday returns: \(monthsFromToday.hoursFromToday)");
NSLog("minsFromToday returns: \(monthsFromToday.minsFromToday)");
NSLog("relativeDateString returns: \(monthsFromToday.relativeDateString())")
var weeksFromToday = today.xWeeks(weeks)
NSLog("** \(weeks) weeks from today: \(weeksFromToday.timeDayMonthYear)")
NSLog("weeksFromToday returns: \(weeksFromToday.weeksFromToday)");
NSLog("relativeDateString returns: \(weeksFromToday.relativeDateString(capitalizeFirst:true))")
NSLog("minsFromToday returns: \(weeksFromToday.minsFromToday)");
NSLog("monthsFromToday returns: \(weeksFromToday.monthsFromToday)");
NSLog("weeksFromToday returns: \(weeksFromToday.weeksFromToday)");
NSLog("daysFromToday returns: \(weeksFromToday.daysFromToday)");
NSLog("hoursFromToday returns: \(weeksFromToday.hoursFromToday)");
NSLog("minsFromToday returns: \(weeksFromToday.minsFromToday)");
var daysFromToday = today.xDays(days)
NSLog("** \(days) days from today: \(daysFromToday.timeDayMonthYear)")
NSLog("daysFromToday returns: \(daysFromToday.daysFromToday)");
NSLog("relativeDateString returns: \(daysFromToday.relativeDateString())")
NSLog("minsFromToday returns: \(daysFromToday.minsFromToday)");
NSLog("monthsFromToday returns: \(daysFromToday.monthsFromToday)");
NSLog("weeksFromToday returns: \(daysFromToday.weeksFromToday)");
NSLog("daysFromToday returns: \(daysFromToday.daysFromToday)");
NSLog("hoursFromToday returns: \(daysFromToday.hoursFromToday)");
NSLog("minsFromToday returns: \(daysFromToday.minsFromToday)");
var hrsFromToday = today.xHours(hrs)
NSLog("** \(hrs) hours from today: \(hrsFromToday.timeDayMonthYear)")
NSLog("hoursFromToday returns: \(hrsFromToday.hoursFromToday)");
NSLog("minsFromToday returns: \(hrsFromToday.minsFromToday)");
NSLog("monthsFromToday returns: \(hrsFromToday.monthsFromToday)");
NSLog("weeksFromToday returns: \(hrsFromToday.weeksFromToday)");
NSLog("daysFromToday returns: \(hrsFromToday.daysFromToday)");
NSLog("hoursFromToday returns: \(hrsFromToday.hoursFromToday)");
NSLog("minsFromToday returns: \(hrsFromToday.minsFromToday)");
NSLog("relativeDateString returns: \(hrsFromToday.relativeDateString(capitalizeFirst:true))")
var minsFromToday = today.xMins(mins)
NSLog("** \(mins) minutes from today: \(minsFromToday.timeDayMonthYear)")
NSLog("minsFromToday returns: \(minsFromToday.minsFromToday)");
NSLog("monthsFromToday returns: \(minsFromToday.monthsFromToday)");
NSLog("weeksFromToday returns: \(minsFromToday.weeksFromToday)");
NSLog("daysFromToday returns: \(minsFromToday.daysFromToday)");
NSLog("hoursFromToday returns: \(minsFromToday.hoursFromToday)");
NSLog("minsFromToday returns: \(minsFromToday.minsFromToday)");
NSLog("relativeDateString returns: \(minsFromToday.relativeDateString())")
NSLog("__________________ End Testing of NSDate _________________________")
}
}
看。首先,這個故事中沒有NSDate。其次,閱讀文檔; NSDateComponents'week'不是你想象的那樣,無論如何它早已被棄用。 – matt 2014-12-07 03:01:15
我只是想在兩個NSDate的間隔中分割組件。 'calendar.components(unitFlags:NSCalendarUnit,fromDate:NSDate!,toDate:NSDate !, options:NSCalendarOptions)'方法需要兩個** NSDate **作爲參數。我看到'周'已被棄用,這就是爲什麼我在這裏問另一種方式來計算幾周 – Giorgio 2014-12-07 10:38:34