2015-12-21 99 views
4

我有以下代碼:的NSDate返回錯誤的週數

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

優秀的問題;許多感謝你......我以爲我瘋了:S lol –

回答

8

根據蘋果開發者技術支持

2015年12月27日爲52周,每週不53.53周在2015年的第一天是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日曆。 (很奇怪)

+0

以爲我瘋了大聲笑:)很多謝謝你的這篇文章/解決方案 –

0

這可能是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周,並從那裏做出決定。

+0

我以爲是這樣,我在蘋果提交了一個DTS。所以我期待第二週第3周的答案,因爲他們從23日開始暫時關閉。當我收到它時,我會發布DTS答案。:)! –

0

請記住,ISO周和美國周編號是不同的!如果您查閱上述維基百科文章,請進一步閱讀,直到「其他星期編號系統」。因此,必須有一個設置來控制美國與ISO周。

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)))