处理两个时区

时间:2015-02-19 10:45:19

标签: ios swift timezone nsdate nstimezone

我从昨天起就一直在努力解决这个问题,但我仍然输了。与日期有关的东西真的是我在编程方面的祸根。

让我解释一下情况。我来自斯里兰卡(GMT +5:30),我和瑞典的客户(GMT +1)合作。我正在从那里托管的API中检索JSON响应。这是它的存根。响应中的每个字典数组都称为切换

[
  {
    "Tim" : 8,
    "Pat" : {
      "Id" : 5104
    },
    "Sta" : "Ej utfört",
    "SB" : 1066,
    "CB" : 0,
    "Date" : "2015-02-19T00:00:00+01:00",
    "DD" : null,
    "HTI" : 1
  },
  {
    "Tim" : 8,
    "Pat" : {
      "Id" : 5029
    },
    "Sta" : "",
    "SB" : null,
    "CB" : 0,
    "Date" : "2015-02-19T00:00:00+01:00",
    "DD" : null,
    "HTI" : 1
  }
]

这里的麻烦制造者是Date字段。如您所见,日期字符串以ISO 8601格式发送。我在应用程序方面做的是从中创建对象并将其存储在核心数据中。因此,为了保存此日期值,首先我使用名为ISO8601DateFormatter的库将日期字符串转换为NSDate。下面是我为此编写的辅助方法。

public class func getDateFromISO8601DateString(dateString: String?) -> NSDate? {
    if let dateString = dateString {
        let formatter = ISO8601DateFormatter()
        formatter.defaultTimeZone = NSTimeZone.localTimeZone()
        formatter.includeTime = true
        let convertedDate = formatter.dateFromString(dateString)
        return convertedDate
    } else {
        return nil
    }
}

现在当我转换日期字符串 2015-02-19T00:00:00 + 01:00 时,我得到NSDate这个值, 2015-02-18 23 :00:00 +0000

稍后在应用中,我需要检索当前日期的一组切换。下面是我为此编写的代码。

let fetchRequest = NSFetchRequest()
let entityDescription = NSEntityDescription.entityForName("Handover", inManagedObjectContext: NSManagedObjectContext.MR_defaultContext())
let datePredicate = NSPredicate(format: "date > %@ AND date < %@", NSDate().beginningOfDay(), NSDate().endOfDay())

fetchRequest.entity = entityDescription
fetchRequest.predicate = datePredicate

var error: NSError?
let handovers = NSManagedObjectContext.MR_defaultContext().executeFetchRequest(fetchRequest, error: &error) as? [Handover]
return handovers

这是另一个使用日期的地方。要根据日期值过滤掉记录,我需要获取日期的开始时间和结束时间。所以我有以下方法来返回这些值。这些方法取自this库。

func beginningOfDay() -> NSDate {
    let calendar = NSCalendar.currentCalendar()
    calendar.timeZone = NSTimeZone.localTimeZone()
    let components = calendar.components(.YearCalendarUnit | .MonthCalendarUnit | .DayCalendarUnit, fromDate: self)

    return calendar.dateFromComponents(components)!
}


func endOfDay() -> NSDate {
    let calendar = NSCalendar.currentCalendar()
    calendar.timeZone = NSTimeZone.localTimeZone()
    let components = NSDateComponents()
    components.day = 1

    return calendar.dateByAddingComponents(components, toDate: self.beginningOfDay(), options: .allZeros)!.dateByAddingTimeInterval(-1)
}

以下是我从这些方法中获得的值。

beginningOfDay() - 2015-02-18 18:30:00 +0000

endOfDay() - 2015-02-19 18:29:59 +0000

这是疯狂的一部分。当我从我住的地方运行应用程序时,所有这些代码都有效。但是当我的客户端运行它时,切换提取方法返回零结果!

我已经跟踪了这个问题并发现日期和时间有问题。但我无法找到纠正它的方法。日期操作完成后,我将时区设置为localTimeZone()。在AppDelegate的didFinishLaunchingWithOptions方法中,我还重置了时区NSTimeZone.resetSystemTimeZone()。似乎没什么用。

任何人都有任何想法/建议?如果你能帮我解决这个问题,我将不胜感激。

谢谢。

1 个答案:

答案 0 :(得分:1)

日期&#34; 2015-02-19T00:00:00 + 01:00&#34;正好是一天的开始 GMT + 01时区,因此与谓词

不匹配
NSPredicate(format: "date > %@ AND date < %@", NSDate().beginningOfDay(), NSDate().endOfDay())

>替换第一个>=可以解决问题:

NSPredicate(format: "date >= %@ AND date < %@", NSDate().beginningOfDay(), NSDate().endOfDay())

您的endOfDay()方法中也无需减去一秒, 因为您已将第二个日期与<进行比较。