如何计算不同时区中两个NSDate对象之间的时差



我有两个从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
}

我可以手动从firstDateComponentssecondDateComponents中减去日分量,这是我不想做的,因为我必须查找31和28的边缘情况,等等。感谢您的帮助。谢谢

更新

第一个日期是2017-02-10 16:15:00+000第二个日期是2017-02-11 03:20:00+0000两者都是UTC。

firstTimeZone字符串"亚洲/上海"second时区字符串"America/Loss_Angeles">

所以时差是-1天。基本上,我正在执行航班状态,您可以看到以下链接,因为航班在起飞日前一天降落。当它从西向东飞行时。

https://www.google.co.in/webhp?sourceid=chrome-即时&离子=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 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),上述代码给出

nycDayOfYear = 42

nzDayOfYear = 43

要使这种计算跨越年份界限,还需要一些工作。

奇怪的是,以下代码:

var nzDayOfEra = nzCalendar.ordinality(of: .day, in: .era, for: now)
let nycDayOfEra = nycCalendar.ordinality(of: .day, in: .era, for: now)

为新西兰和纽约市提供相同的价值。我不知道为什么。

编辑:

好吧,我做了一些实验,得到了有效的代码。我所做的是使用设置为每个时间的本地时区的日历将两个日期转换为月/日/年日期组件。然后我使用方法dateComponents(_:from:to:)来计算这两个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

截至本文撰写之时,天差为1。由于我们使用的是dateComponents(_:from:to:)函数,因此它需要计算2个月/天/年DateComponents之间的天数差。

NSDate表示一个时刻。它没有时区。只有日期的字符串表示具有时区信息。

如果你有日期,就记下它们之间的天数。不要担心时区。

通常:

let difference = calendar.components(.Day, fromDate: self, toDate: toDate!, options: [])
return difference.day

应该足够了。

您尝试过使用let interval = laterDate.timeIntervalSinceDate(earlierDate)吗?这将以秒为单位返回两个日期之间的差异。

最新更新