我有以下代码:
getWeek(addDays(Date, amount: 6))
func addDays(date: NSDate, amount: Int) -> NSDate {
// calculation $additionalDays
let additionalDays = amount
// adding $additionalDays
let components = NSDateComponents()
components.day = additionalDays
// important: NSCalendarOptions(0)
let futureDate = NSCalendar.currentCalendar()
.dateByAddingComponents(components, toDate: date, options: NSCalendarOptions(rawValue: 0))
return futureDate!
}
func getWeek(today:NSDate)->Int? {
let formatter = NSDateFormatter()
formatter.dateFormat = "yyyy-MM-dd"
let myCalendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
let myComponents = myCalendar.components(.WeekOfYear, fromDate: today)
let weekNumber = myComponents.weekOfYear
return weekNumber
}
getWeek(addDays(Date, amount: 6))
中的日期返回dec 27, 2015, 7:16PM
这是正确的(下周日)但是,如果我尝试返回该日期的周数,则返回1
,而这应该是53.如何获得正确的周数?
答案 0 :(得分:8)
根据 Apple开发者技术支持:
2015年12月27日是第52周,而不是第53周。2015年第53周的第一天是12月28日。
无论如何,你的
getWeek()
函数返回的值与ISO 8601不匹配是正确的。原因是你使用的是NSCalendarIdentifierGregorian而不是NSCalendarIdentifierISO8601。有/很多/不同的方法来进行一周的计算。如果你愿意,我可以进入血腥细节,但这里的'带回家'信息是,如果你想要ISO 8601周计算,你应该使用NSCalendarIdentifierISO8601。
随着更改getWeek()
开始生成符合ISO 8601的结果。具体来说:
print(self.getWeek(self.dateFromFixedFormatString("2015-12-27 12:34")))
print(self.getWeek(self.dateFromFixedFormatString("2015-12-28 12:34")))
打印:
假设:
func dateFromFixedFormatString(dateStr: String) -> NSDate {
let df = NSDateFormatter()
df.locale = NSLocale(localeIdentifier: "en_US_POSIX")
df.dateFormat = "yyyy-MM-dd HH:mm"
return df.dateFromString(dateStr)!
}
func getWeek(today:NSDate) -> Int {
let myCalendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierISO8601)!
let myComponents = myCalendar.components(.WeekOfYear, fromDate: today)
let weekNumber = myComponents.weekOfYear
return weekNumber
}
所以任何说明GregorianCalendar在我的代码中不起作用的人都是正确的,并且应该特别使用NSCalendarIdentifierISO8601。 NSCalendar.currentCalendar()
不会自动获取ISO日历。 (很奇怪)
答案 1 :(得分:0)
这可能是Apple实施中的一个错误。 Apple似乎认为2015年12月27日是2016年第1周。但是,根据ISO周日期标准,它应该在第53周,因为12月31日是星期四。 (周三12月31日应被视为第1周:https://en.wikipedia.org/wiki/ISO_week_date#Last_week)。
要解决此问题,您可能需要进行一些额外的计算。例如,您可以检查.YearForWeekOfYear以检查2016周1并从那里做出决定。
答案 2 :(得分:0)
请记住ISO周和美国周编号不同!如果您查看上面提到的维基百科文章,请进一步阅读“其他周编号系统”。因此,必须有一个设置来控制美国与ISO周。
答案 3 :(得分:0)
我已经使用小修补程序编译程序,并将日历更改为ISO。这将为2015年带来理想的结果,请与其他年份一起测试。
import Foundation
let now = NSDate()
func addDays(date: NSDate, amount: Int) -> NSDate {
// calculation $additionalDays
let additionalDays = amount
// adding $additionalDays
let components = NSDateComponents()
components.day = additionalDays
// important: NSCalendarOptions(0)
let futureDate = NSCalendar.currentCalendar()
.dateByAddingComponents(components, toDate: date, options: NSCalendarOptions(rawValue: 0))
return futureDate!
}
func getWeek(today:NSDate)->Int {
let formatter = NSDateFormatter()
formatter.dateFormat = "yyyy-MM-dd"
let myCalendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierISO8601)!
let myComponents = myCalendar.components(.WeekOfYear, fromDate: today)
let weekNumber = myComponents.weekOfYear
return weekNumber
}
print(getWeek(addDays(now, amount: 6)))