iOS Calendar.ordinality(of:in:for:) 时代月份的错误结果
iOS Calendar.ordinality(of:in:for:) wrong results for month in era
我不确定我是不是没有领会这里的东西还是 iOS SDK 问题:
问题: 我需要获得与当前月份的月份差值(例如:上个月为 -1)。任何选定月份的第一天和第二天除外的任何一天的下线工作。
我认为最初可能是我没有考虑的某种时区或日历方面,但简化了问题(例如,仅使用 UTC),获取当前时代的月份序号,用于 2 个不同的日期,一个在 1 日(或 2020 年 9 月的第 2 次)以及第 3 次,我得到了不同的结果。
var calendar = Calendar.current
let timezone = TimeZone(secondsFromGMT: 0)!
calendar.timeZone = timezone
let dateMonthFirst = calendar.date(from: DateComponents(calendar: calendar, timeZone: timezone, year: 2020, month: 9, day: 1))!
// let dateMonthFirst = Date(timeIntervalSince1970: 1598918400) // same using directly timestamp for sept 1st
let ordinalityFirst = calendar.ordinality(of: .month, in: .era, for: dateMonthFirst)!
let dateMonthThird = calendar.date(from: DateComponents(calendar: calendar, timeZone: timezone, year: 2020, month: 9, day: 3))!
// let dateMonthThird = Date(timeIntervalSince1970: 1599091200) // same using directly timestamp for sept 3rd
let ordinalityThird = calendar.ordinality(of: .month, in: .era, for: dateMonthThird)!
print("1st of month ordinality: \(ordinalityFirst)")
print("3rd of month ordinality: \(ordinalityThird)")
print("MONTHS AGO: \(ordinalityThird - ordinalityFirst)")
结果总是
1st of month ordinality: 24236
3rd of month ordinality: 24237
MONTHS AGO: 1
两者的预期结果都应该是 24237
我是不是漏掉了什么?
注意 (1):使用该月的第二天可以获得相同的“错误”结果,因此我将排除时区问题。
注(2):出于与1相同的原因,我怀疑它也是由于这个问题中显示的日历对齐的一些影响:
问题是因为您使用 era
而不是 year
。一旦将 in
的输入更改为 .year
,您就会得到预期的结果。也不需要设置 TimeZone
,尤其是不需要设置 calendar.locale = Locale.current
,因为无论如何这是 Calendar.current.locale
的默认值。
let calendar = Calendar.current
let dateMonthFirst = calendar.date(from: DateComponents(calendar: calendar, year: 2020, month: 9, day: 1))!
// let dateMonthFirst = Date(timeIntervalSince1970: 1598918400) // same using directly timestamp for sept 1st
let ordinalityFirst = calendar.ordinality(of: .month, in: .year, for: dateMonthFirst)!
let dateMonthThird = calendar.date(from: DateComponents(calendar: calendar, year: 2020, month: 9, day: 3))!
// let dateMonthThird = Date(timeIntervalSince1970: 1599091200) // same using directly timestamp for sept 3rd
let ordinalityThird = calendar.ordinality(of: .month, in: .year, for: dateMonthThird)!
print("1st of month ordinality: \(ordinalityFirst)")
print("3rd of month ordinality: \(ordinalityThird)")
print("MONTHS AGO: \(ordinalityThird - ordinalityFirst)")
但是,如果您只需要 2 Date
之间的月差,则有一个更简单的解决方案:您只需使用 calendar.dateComponents(_:from:to:)
.
calendar.dateComponents([.month], from: dateMonthFirst, to: dateMonthThird).month! // 0
即使你们的日期在不同的年份,这也会给你正确的答案。
let thisSept = calendar.date(from: DateComponents(calendar: calendar, year: 2020, month: 9, day: 3))!
let nextAug = calendar.date(from: DateComponents(calendar: calendar, year: 2021, month: 8, day: 3))!
calendar.dateComponents([.month], from: thisSept, to: nextAug).month! // 11
我不确定我是不是没有领会这里的东西还是 iOS SDK 问题:
问题: 我需要获得与当前月份的月份差值(例如:上个月为 -1)。任何选定月份的第一天和第二天除外的任何一天的下线工作。
我认为最初可能是我没有考虑的某种时区或日历方面,但简化了问题(例如,仅使用 UTC),获取当前时代的月份序号,用于 2 个不同的日期,一个在 1 日(或 2020 年 9 月的第 2 次)以及第 3 次,我得到了不同的结果。
var calendar = Calendar.current
let timezone = TimeZone(secondsFromGMT: 0)!
calendar.timeZone = timezone
let dateMonthFirst = calendar.date(from: DateComponents(calendar: calendar, timeZone: timezone, year: 2020, month: 9, day: 1))!
// let dateMonthFirst = Date(timeIntervalSince1970: 1598918400) // same using directly timestamp for sept 1st
let ordinalityFirst = calendar.ordinality(of: .month, in: .era, for: dateMonthFirst)!
let dateMonthThird = calendar.date(from: DateComponents(calendar: calendar, timeZone: timezone, year: 2020, month: 9, day: 3))!
// let dateMonthThird = Date(timeIntervalSince1970: 1599091200) // same using directly timestamp for sept 3rd
let ordinalityThird = calendar.ordinality(of: .month, in: .era, for: dateMonthThird)!
print("1st of month ordinality: \(ordinalityFirst)")
print("3rd of month ordinality: \(ordinalityThird)")
print("MONTHS AGO: \(ordinalityThird - ordinalityFirst)")
结果总是
1st of month ordinality: 24236
3rd of month ordinality: 24237
MONTHS AGO: 1
两者的预期结果都应该是 24237
我是不是漏掉了什么?
注意 (1):使用该月的第二天可以获得相同的“错误”结果,因此我将排除时区问题。
注(2):出于与1相同的原因,我怀疑它也是由于这个问题中显示的日历对齐的一些影响:
问题是因为您使用 era
而不是 year
。一旦将 in
的输入更改为 .year
,您就会得到预期的结果。也不需要设置 TimeZone
,尤其是不需要设置 calendar.locale = Locale.current
,因为无论如何这是 Calendar.current.locale
的默认值。
let calendar = Calendar.current
let dateMonthFirst = calendar.date(from: DateComponents(calendar: calendar, year: 2020, month: 9, day: 1))!
// let dateMonthFirst = Date(timeIntervalSince1970: 1598918400) // same using directly timestamp for sept 1st
let ordinalityFirst = calendar.ordinality(of: .month, in: .year, for: dateMonthFirst)!
let dateMonthThird = calendar.date(from: DateComponents(calendar: calendar, year: 2020, month: 9, day: 3))!
// let dateMonthThird = Date(timeIntervalSince1970: 1599091200) // same using directly timestamp for sept 3rd
let ordinalityThird = calendar.ordinality(of: .month, in: .year, for: dateMonthThird)!
print("1st of month ordinality: \(ordinalityFirst)")
print("3rd of month ordinality: \(ordinalityThird)")
print("MONTHS AGO: \(ordinalityThird - ordinalityFirst)")
但是,如果您只需要 2 Date
之间的月差,则有一个更简单的解决方案:您只需使用 calendar.dateComponents(_:from:to:)
.
calendar.dateComponents([.month], from: dateMonthFirst, to: dateMonthThird).month! // 0
即使你们的日期在不同的年份,这也会给你正确的答案。
let thisSept = calendar.date(from: DateComponents(calendar: calendar, year: 2020, month: 9, day: 3))!
let nextAug = calendar.date(from: DateComponents(calendar: calendar, year: 2021, month: 8, day: 3))!
calendar.dateComponents([.month], from: thisSept, to: nextAug).month! // 11