SWIFT:如何将小时添加到NSDate对象

我从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 

我从Web服务器获得这个string值。 我需要修改个人设备时区。 想要添加这个stringToDate对象但不能工作

 var addHours : Int = 2 // 2 hours will be added var newDate = stringToDate.dateByAddingTimeInterval(addHours) 

你问的是错误的问题。 这就是所谓的“XY问题” 。 你应该问:“我如何显示一个datestring,我从一个Web服务器在用户的本地时区”。

NSDate以不包含时区的抽象forms表示date/时间。 您将其转换为特定的时区以供显示。 不要尝试添加/减去NSDate小时以抵消时区。 这是错误的做法。

正确的答案很简单。 创build第二个date格式化程序,不要将它的时区设置为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的答案所指出的那样,简单地增加小时绝对是错误的方法。 两个时区不会总是以相同的时间分隔。 再一次,当我们考虑夏令时时,情况更是如此。 (例如,美国没有像欧洲那样开始/结束夏令时,亚利桑那甚至没有夏令时)。

如果你正在更频繁地使用它,请查看名为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值。

实施这个应该只需要一点时间! (Pun打算)。

对于SWIFT 3你可以使用这个function…

//通过添加小时func获取下一个date

getNewDateAfterAddingHours(hoursToAdd:NSInteger,oldDate:Date) – > Int64

{

  let calendar = Calendar.current let newDate = calendar.date(byAdding: .hour, value: hoursToAdd, to: oldDate) return Int64((newDate?.timeIntervalSince1970)!) }