我从string生成一个NSDate对象。
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
dateFormatter.timeZone = NSTimeZone(abbreviation: "GMT")
let stringToDate = dateFormatter.dateFromString(dateFromService) // 2015-07-20 12:00:43 +0000
我从网络服务器获取此字符串值。我需要修改个人设备时区。想要添加这个stringToDate对象的小时但不起作用
var addHours : Int = 2 // 2 hours will be added
var newDate = stringToDate.dateByAddingTimeInterval(addHours)
你问的是错误的问题。这就是所谓的"XY Problem"。您应该询问“如何在用户的本地时区显示从Web服务器获取的日期字符串”。
NSDate
以抽象形式表示不包含时区的日期/时间。您将其转换为特定时区进行显示。不要尝试向NSDate添加/减去小时以抵消时区。这是错误的做法。
正确的答案很简单。创建第二个日期格式化程序,不要将其时区设置为GMT。它默认为用户的本地时区。
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
dateFormatter.timeZone = NSTimeZone(abbreviation: "GMT")
let date = dateFormatter.dateFromString(dateFromService)
let outputDatedateFormatter = NSDateFormatter()
outputDatedateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
//leave the time zone at the default (user's time zone)
let displayString = outputDateFormatter.stringFromDate(date)
println("Date in local time zone = \(displayString)")
使用NSCalendarComponents
:
let calendar = NSCalendar.currentCalendar()
let newDate = calendar.dateByAddingUnit(
.CalendarUnitHour, // adding hours
value: 2, // adding two hours
toDate: oldDate,
options: .allZeros
)
使用NSCalendar
将解释闰秒,闰小等问题。
但正如Duncan C's answer指出的那样,简单地增加小时绝对是错误的做法。两个时区不会总是以相同的时间间隔分开。同样,当我们考虑夏令时时,尤其如此。 (例如,美国在与欧洲同一天没有开始/结束夏令时,亚利桑那州甚至没有夏令时)。
对于Swift 3,您可以使用此功能:
//get next date by adding hours func
getNewDateAfterAddingHours(hoursToAdd:NSInteger, oldDate:Date) -> Int64 {
let calendar = Calendar.current
let newDate = calendar.date(byAdding: .hour, value: hoursToAdd, to: oldDate)
return Int64((newDate?.timeIntervalSince1970)!)
}
如果您经常这样做,请查看名为SwiftMoment的库(灵感来自相同的.js库),它允许您执行以下操作(以及更多!):
// Create date using moment library
let myDate = moment(myString)
// Add one hour
let dateWithAddedHour = myDate + 1.hours
Moment是NSDate实例的包装器,而Duration(这是从Int.hours,Int.minutes等获得的)包装NSTimeInterval值。
实现这一点应该只需要一点时间! (双关语)。