如何计算不同时区的两个 NSDate 对象之间的天数差异?
How to calculate days difference between two NSDate objects in different time zones?
我有两个从 UTC 日期启动的 NSDate。
让我们称他们为 (A & B)
我知道A代表中国的一天,B代表美国的一天。 (我知道时区。)如何计算两者之间的天数差异...?
我一直在用下面的方法,明显不对
class func daysDifferenceIn(firstDate: NSDate, firstTimeZone: String, secondDate: NSDate, secondTimeZone: String) -> Int {
objc_sync_enter(self)
let firstDateComponents = NSCalendar.CommonCalendar.componentsInTimeZone(NSTimeZone(name: firstTimeZone)!, fromDate: firstDate)
let secondDateComponents = NSCalendar.CommonCalendar.componentsInTimeZone(NSTimeZone(name: secondTimeZone)!, fromDate: secondDate)
NSCalendar.CommonCalendar.timeZone = NSTimeZone(name: firstTimeZone)!
let firstCalDate = NSCalendar.CommonCalendar.dateFromComponents(firstDateComponents)
NSCalendar.CommonCalendar.timeZone = NSTimeZone(name: secondTimeZone)!
let secondCalDate = NSCalendar.CommonCalendar.dateFromComponents(secondDateComponents)
objc_sync_exit(self)
return firstCalDate!.numberOfDaysUntilDateTime(secondCalDate!)
}
func numberOfDaysUntilDateTime(toDateTime: NSDate, inTimeZone timeZone: NSTimeZone? = nil) -> Int {
let calendar = NSCalendar.CommonCalendar
if let timeZone = timeZone {
calendar.timeZone = timeZone
}
var fromDate: NSDate?, toDate: NSDate?
calendar.rangeOfUnit(.Day, startDate: &fromDate, interval: nil, forDate: self)
calendar.rangeOfUnit(.Day, startDate: &toDate, interval: nil, forDate: toDateTime)
let difference = calendar.components(.Day, fromDate: fromDate!, toDate: toDate!, options: [])
return difference.day
}
我可以手动从 firstDateComponents
和 secondDateComponents
中减去日期分量,但我不想这样做,因为我必须寻找 31 和 28 等的边缘情况。
任何帮助表示赞赏。谢谢。
更新
第一个日期是 2017-02-10 16:15:00 +0000
第二个日期是 2017-02-11 03:20:00 +0000 都是 UTC。
firstTimeZone 字符串 "Asia/Shanghai"
secondTimeZone 字符串 "America/Los_Angeles"
所以天差是-1天。基本上,我正在执行航班状态,您可以看到以下内容 link,因为航班在起飞前 1 天降落。当它从西向东飞时。
https://www.google.co.in/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=ua+890
还有日期组件的描述。
Printing description of firstDateComponents:
<NSDateComponents: 0x600000142310>
Calendar: <CFCalendar 0x60000088b6d0 [0x10c5d3df0]>{identifier = 'gregorian'}
TimeZone: Asia/Shanghai (GMT+8) offset 28800
Era: 1
Calendar Year: 2017
Month: 2
Leap month: no
Day: 11
Hour: 0
Minute: 15
Second: 0
Nanosecond: 0
Quarter: 0
Year for Week of Year: 2017
Week of Year: 6
Week of Month: 2
Weekday: 7
Weekday Ordinal: 2
Printing description of secondDateComponents:
<NSDateComponents: 0x60000014b8f0>
Calendar: <CFCalendar 0x60000049b620 [0x10c5d3df0]>{identifier = 'gregorian'}
TimeZone: America/Los_Angeles (PST) offset -28800
Era: 1
Calendar Year: 2017
Month: 2
Leap month: no
Day: 10
Hour: 19
Minute: 20
Second: 0
Nanosecond: 0
Quarter: 0
Year for Week of Year: 2017
Week of Year: 6
Week of Month: 2
Weekday: 6
Weekday Ordinal: 2
您尝试过使用 let interval = laterDate.timeIntervalSinceDate(earlierDate)
吗?这将 return 以秒为单位的两个日期之间的差异。
一个NSDate
代表一个时刻。它没有时区。只有日期的字符串表示具有时区信息。
如果您有日期,只需计算它们之间的天数即可。不用担心时区问题。
通常:
let difference = calendar.components(.Day, fromDate: self, toDate: toDate!, options: [])
return difference.day
应该够了。
这是一个奇怪的案例。当在特定时区评估这些日期时,您正在寻找两个日期之间的日历日期差异。
我玩了一把,想出了适用于同一年日期的代码:
let date = Date()
guard let nycTimeZone = TimeZone(abbreviation: "EST"),
let nzTimeZone = TimeZone(abbreviation: "NZDT") else {
fatalError()
}
var nycCalendar = Calendar(identifier: .gregorian)
nycCalendar.timeZone = nycTimeZone
var nzCalendar = Calendar(identifier: .gregorian)
nzCalendar.timeZone = nzTimeZone
let now = Date()
let nycDayOfYear = nycCalendar.ordinality(of: .day, in: .year, for: now)
var nzDayOfYear = nzCalendar.ordinality(of: .day, in: .year, for: now)
我使用纽约和新西兰奥克兰作为我的时区,因为在撰写本文时,这些时区的日期不同。
截至目前(2017 年 2 月 11 日下午 12:00,美国东部标准时间 (UTC - 5) 以上代码给出
nycDayOfYear = 42
和
nzDayOfYear = 43
需要做一些工作才能跨年度进行计算。
奇怪的是,下面的代码:
var nzDayOfEra = nzCalendar.ordinality(of: .day, in: .era, for: now)
let nycDayOfEra = nycCalendar.ordinality(of: .day, in: .era, for: now)
为 NZ 和 NYC 提供相同的值。我不知道为什么。
编辑:
好的,我做了一些试验并得到了有效的代码。我所做的是使用每次都设置为本地时区的日历将两个日期转换为 month/day/year 日期组件。然后我使用一种方法 dateComponents(_:from:to:)
来计算这 2 DateComponents
之间的差异,以天为单位:
import UIKit
let date = Date()
guard let nycTimeZone = TimeZone(abbreviation: "EST"),
let nzTimeZone = TimeZone(abbreviation: "NZDT") else {
fatalError()
}
var nycCalendar = Calendar(identifier: .gregorian)
nycCalendar.timeZone = nycTimeZone
var nzCalendar = Calendar(identifier: .gregorian)
nzCalendar.timeZone = nzTimeZone
let now = Date()
let nycDateComponents = nycCalendar.dateComponents([.month, .day, .year], from: now)
let nzDateComponents = nzCalendar.dateComponents([.month, .day, .year], from: now)
let difference = Calendar.current.dateComponents([.day],
from: nycDateComponents,
to: nzDateComponents)
let daysDifference = difference.days
在撰写本文时,daysDifference 为 1。由于我们使用的是 dateComponents(_:from:to:)
函数,因此它负责计算 2 month/day/year 之间的天数差异DateComponents
.
我有两个从 UTC 日期启动的 NSDate。 让我们称他们为 (A & B)
我知道A代表中国的一天,B代表美国的一天。 (我知道时区。)如何计算两者之间的天数差异...?
我一直在用下面的方法,明显不对
class func daysDifferenceIn(firstDate: NSDate, firstTimeZone: String, secondDate: NSDate, secondTimeZone: String) -> Int {
objc_sync_enter(self)
let firstDateComponents = NSCalendar.CommonCalendar.componentsInTimeZone(NSTimeZone(name: firstTimeZone)!, fromDate: firstDate)
let secondDateComponents = NSCalendar.CommonCalendar.componentsInTimeZone(NSTimeZone(name: secondTimeZone)!, fromDate: secondDate)
NSCalendar.CommonCalendar.timeZone = NSTimeZone(name: firstTimeZone)!
let firstCalDate = NSCalendar.CommonCalendar.dateFromComponents(firstDateComponents)
NSCalendar.CommonCalendar.timeZone = NSTimeZone(name: secondTimeZone)!
let secondCalDate = NSCalendar.CommonCalendar.dateFromComponents(secondDateComponents)
objc_sync_exit(self)
return firstCalDate!.numberOfDaysUntilDateTime(secondCalDate!)
}
func numberOfDaysUntilDateTime(toDateTime: NSDate, inTimeZone timeZone: NSTimeZone? = nil) -> Int {
let calendar = NSCalendar.CommonCalendar
if let timeZone = timeZone {
calendar.timeZone = timeZone
}
var fromDate: NSDate?, toDate: NSDate?
calendar.rangeOfUnit(.Day, startDate: &fromDate, interval: nil, forDate: self)
calendar.rangeOfUnit(.Day, startDate: &toDate, interval: nil, forDate: toDateTime)
let difference = calendar.components(.Day, fromDate: fromDate!, toDate: toDate!, options: [])
return difference.day
}
我可以手动从 firstDateComponents
和 secondDateComponents
中减去日期分量,但我不想这样做,因为我必须寻找 31 和 28 等的边缘情况。
任何帮助表示赞赏。谢谢。
更新
第一个日期是 2017-02-10 16:15:00 +0000 第二个日期是 2017-02-11 03:20:00 +0000 都是 UTC。
firstTimeZone 字符串 "Asia/Shanghai" secondTimeZone 字符串 "America/Los_Angeles"
所以天差是-1天。基本上,我正在执行航班状态,您可以看到以下内容 link,因为航班在起飞前 1 天降落。当它从西向东飞时。
https://www.google.co.in/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=ua+890
还有日期组件的描述。
Printing description of firstDateComponents:
<NSDateComponents: 0x600000142310>
Calendar: <CFCalendar 0x60000088b6d0 [0x10c5d3df0]>{identifier = 'gregorian'}
TimeZone: Asia/Shanghai (GMT+8) offset 28800
Era: 1
Calendar Year: 2017
Month: 2
Leap month: no
Day: 11
Hour: 0
Minute: 15
Second: 0
Nanosecond: 0
Quarter: 0
Year for Week of Year: 2017
Week of Year: 6
Week of Month: 2
Weekday: 7
Weekday Ordinal: 2
Printing description of secondDateComponents:
<NSDateComponents: 0x60000014b8f0>
Calendar: <CFCalendar 0x60000049b620 [0x10c5d3df0]>{identifier = 'gregorian'}
TimeZone: America/Los_Angeles (PST) offset -28800
Era: 1
Calendar Year: 2017
Month: 2
Leap month: no
Day: 10
Hour: 19
Minute: 20
Second: 0
Nanosecond: 0
Quarter: 0
Year for Week of Year: 2017
Week of Year: 6
Week of Month: 2
Weekday: 6
Weekday Ordinal: 2
您尝试过使用 let interval = laterDate.timeIntervalSinceDate(earlierDate)
吗?这将 return 以秒为单位的两个日期之间的差异。
一个NSDate
代表一个时刻。它没有时区。只有日期的字符串表示具有时区信息。
如果您有日期,只需计算它们之间的天数即可。不用担心时区问题。
通常:
let difference = calendar.components(.Day, fromDate: self, toDate: toDate!, options: [])
return difference.day
应该够了。
这是一个奇怪的案例。当在特定时区评估这些日期时,您正在寻找两个日期之间的日历日期差异。
我玩了一把,想出了适用于同一年日期的代码:
let date = Date()
guard let nycTimeZone = TimeZone(abbreviation: "EST"),
let nzTimeZone = TimeZone(abbreviation: "NZDT") else {
fatalError()
}
var nycCalendar = Calendar(identifier: .gregorian)
nycCalendar.timeZone = nycTimeZone
var nzCalendar = Calendar(identifier: .gregorian)
nzCalendar.timeZone = nzTimeZone
let now = Date()
let nycDayOfYear = nycCalendar.ordinality(of: .day, in: .year, for: now)
var nzDayOfYear = nzCalendar.ordinality(of: .day, in: .year, for: now)
我使用纽约和新西兰奥克兰作为我的时区,因为在撰写本文时,这些时区的日期不同。
截至目前(2017 年 2 月 11 日下午 12:00,美国东部标准时间 (UTC - 5) 以上代码给出
nycDayOfYear = 42
和
nzDayOfYear = 43
需要做一些工作才能跨年度进行计算。
奇怪的是,下面的代码:
var nzDayOfEra = nzCalendar.ordinality(of: .day, in: .era, for: now)
let nycDayOfEra = nycCalendar.ordinality(of: .day, in: .era, for: now)
为 NZ 和 NYC 提供相同的值。我不知道为什么。
编辑:
好的,我做了一些试验并得到了有效的代码。我所做的是使用每次都设置为本地时区的日历将两个日期转换为 month/day/year 日期组件。然后我使用一种方法 dateComponents(_:from:to:)
来计算这 2 DateComponents
之间的差异,以天为单位:
import UIKit
let date = Date()
guard let nycTimeZone = TimeZone(abbreviation: "EST"),
let nzTimeZone = TimeZone(abbreviation: "NZDT") else {
fatalError()
}
var nycCalendar = Calendar(identifier: .gregorian)
nycCalendar.timeZone = nycTimeZone
var nzCalendar = Calendar(identifier: .gregorian)
nzCalendar.timeZone = nzTimeZone
let now = Date()
let nycDateComponents = nycCalendar.dateComponents([.month, .day, .year], from: now)
let nzDateComponents = nzCalendar.dateComponents([.month, .day, .year], from: now)
let difference = Calendar.current.dateComponents([.day],
from: nycDateComponents,
to: nzDateComponents)
let daysDifference = difference.days
在撰写本文时,daysDifference 为 1。由于我们使用的是 dateComponents(_:from:to:)
函数,因此它负责计算 2 month/day/year 之间的天数差异DateComponents
.