我喜欢在狮子座的解决方案的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