从一年中的一周开始的日期返回日期不在一周内

Posted

技术标签:

【中文标题】从一年中的一周开始的日期返回日期不在一周内【英文标题】:Date from week of year returning date not in week 【发布时间】:2014-12-26 00:08:12 【问题描述】:

我遇到了一个相当奇怪的“错误”。使用此方法获取一年中某一周的日期时:

let dates = NSMutableArray()
let cal = NSCalendar.currentCalendar()
cal.firstWeekday = 2
let formatter = NSDateFormatter()
formatter.dateFormat = "ww YYYY"
formatter.calendar = cal
let date = formatter.dateFromString(week as String)
println(date)

字符串 week52 2014,因此预期日期是 12 月 22 日星期一,但它返回的是 12 月 20 日星期六 23:00。首先,我以为我已经通过设置日历的firstWeekday-选项来处理一周的第一天,但​​没有运气。此外,返回的日期甚至不是第 52 周。

只是为了再次检查我运行cal.components(NSCalendarUnit.WeekOfYearCalendarUnit, fromDate: date!).weekOfYear 再次检查我不是白痴,不,先生,生成日期的周是 51,即所需周的前一周。

知道我怎样才能达到预期的结果吗?

【问题讨论】:

YYYY 对您来说可能是错误的格式化程序,因为它是“一年中的一周”日历中的年份。此日历适用于几周。大多数情况下,它与我们日常生活中所知道的日历相同,但在一年的开始和结束时,它可能会产生奇怪的结果:一月的前 3 天可能是去年的第 53 周,或者次年第 1 周 12 月的最后 3 天。您可能想使用yyyy @vikingosegundo 谢谢,我不知道 :) 对于投反对票的人,请发表评论,解释为什么这个问题不是一个好问题。 【参考方案1】:

知道我怎样才能达到预期的结果吗?

您真正想要的结果是什么?你想知道一周的第一天还是最后一天的第一天?比你可以托盘这个:

let now = NSDate()
var startDate: NSDate? = nil
var duration: NSTimeInterval = 0

let cal = NSCalendar.currentCalendar()
cal.firstWeekday = 2

cal.rangeOfUnit(.WeekCalendarUnit, startDate: &startDate, interval: &duration, forDate: now);


let endDate = startDate?.dateByAddingTimeInterval(duration)
print(startDate)
print(endDate)

打印出来

"Optional(2014-12-21 23:00:00 +0000)"
"Optional(2014-12-28 23:00:00 +0000)"

endDate 是一周中不再存在的第一秒。

请注意,1 小时的偏移量是因为它以 UTC 时间打印,实际上是 GMT 冬季时间。事实上,这些日期在我的时区 (GMT+1) 中是 2014-12-22 00:00:002014-12-29 00:00:00


或者干脆

let components = NSDateComponents()
components.weekOfYear = 52
components.weekday = 2
components.year = 2014

let cal = NSCalendar.currentCalendar()    
let day = cal.dateFromComponents(components)

此代码适用于尊重用户的日历:

let cal = NSCalendar.currentCalendar()
let components = NSDateComponents()
components.weekOfYear = 52
components.weekday = cal.firstWeekday
components.year = 2014

【讨论】:

我实际上首先尝试了您的第一个示例,但我发现这也给了我意想不到的结果,如果我没有得到一周的实际第一天,那将毫无用处,即案子。此外,简单地使用当前日期也会给出两个日期甚至不在同一周,证明 println(cal.components(NSCalendarUnit.WeekOfYearCalendarUnit, fromDate: startDate!).weekOfYear)println(cal.components(NSCalendarUnit.WeekOfYearCalendarUnit, fromDate: endDate!).weekOfYear) 返回 52 和 1。 他们给出了正确的结果。我所有的例子。但是您似乎不了解日历计算的基础知识。您不知道 NSDate 的性质是一个时间点,以 UTC 时间表示。你似乎忘记了时区。 我确实明白了,只是当根据日期中的相同日历 WeekOfYear 检查时,它返回的日期不在同一周内,这与它本身相矛盾。 日期在同一周。你只是不明白日期的描述。【参考方案2】:

将第一个工作日从 1 更改为 2 不会更改日期,它只会将第一个工作日从星期日更改为星期一。

你可以这样做:

func dateFromWeekOfYear(year:Int, weekOfYear:Int, weekday:Int) -> NSDate 
    return NSCalendar.currentCalendar().dateWithEra(1, yearForWeekOfYear: year, weekOfYear: weekOfYear, weekday: weekday, hour: 0, minute: 0, second: 0, nanosecond: 0)!


let date1 = dateFromWeekOfYear(2014, 52, 1)   // Dec 21, 2014, 12:00 AM
let date2 = dateFromWeekOfYear(2014, 52, 2)   // Dec 22, 2014, 12:00 AM
let date3 = dateFromWeekOfYear(2014, 52, 3)   // Dec 23, 2014, 12:00 AM

如果处理一个字符串并且你想设置他在当地的一周中独立,你可以这样做:

let myDate = "2 52 2014"
let cal = NSCalendar.currentCalendar()
let formatter = NSDateFormatter()
formatter.dateFormat = "c ww Y"
formatter.calendar = cal
if let date1 = formatter.dateFromString(myDate) 
    date1  // "Dec 22, 2014, 12:00 AM"

如果您需要进一步的参考,您可以使用这个:

【讨论】:

这非常有用!我想我知道我的逻辑在哪里失败,或者更确切地说是日历的逻辑,它不关心我将哪一天设置为第一个工作日,它总是将第一个星期日(在本例中为 12 月 21 日)计为该特定周的星期日。因此,例如,如果我正在寻找 2014 年第 52 周的星期一和星期日,并且我使用格式化程序方法,它会给我 12 月 21 日和 22 日。 但是,使用你的函数,只有将 firstWeekday-property 设置为 2 的日历,我得到了 12 月 22 日和 28 日的预期结果。似乎格式化程序根本不在乎关于它应该使用的日历。奇怪,但谢谢!

以上是关于从一年中的一周开始的日期返回日期不在一周内的主要内容,如果未能解决你的问题,请参考以下文章

“一年中的一周”算法需要改进

确定性标量函数,用于获取日期的一年中的一周

获取一周中特定日期的下一个日期

Excel中如何计算日期所在的这年的第几周,以周一作为一周的第一天

Angularjs如何获得一周内的所有日期和日期

一周内不同的日期计数