Swift 3 - 日期和不同时区的时间部分

时间:2017-03-10 02:36:46

标签: swift date timezone

我遇到了从REST Web服务收到的日期字符串的问题,以及如何在不同时区的Swift中表示它。我刚刚能够重现这个问题,所以我将谈谈这个具体的例子。

我从Web服务获取的信息是日期时间字符串和时区标识符。在这种情况下,系统位于 America / New_York 或美国东部时区。我创建了一个游乐场,我有以下代码

let dateFormatString = "yyyy-MM-dd'T'HH:mm:ssZZZZZ"
let easternTimeZone = "America/New_York"
let serverDate = "2017-03-01T00:00:00-05:00"

我有一个方法,它接受日期字符串和时区标识符,并创建一个Date对象,如下所示

func dateForDateString(dateString: String, timeZone: String) -> Date?
{
    let formatter = DateFormatter()
    if timeZone != ""
    {
        formatter.timeZone = TimeZone(identifier: timeZone)
    }

    formatter.dateFormat = dateFormatString

    return formatter.date(from: dateString)
}

当我使用从Web服务返回的内容调用此方法时

let easternDate = dateForDateString(dateString: serverDate, timeZone: easternTimeZone)
print("\(easternDate)")

print语句输出预期的Optional(2017-03-01 05:00:00 +0000)。没有问题。当设备处于不同的时区时会出现问题,为了这个例子,我正在太平洋时间进行测试。在操场上,easternTime变量显示为Feb 28, 2017, 9:00 PM。再一次,并非出乎意料。

日期将存储在Firebase数据库中,我根本不关心时间。所以我最终使用Calendar方法startOfDay,如下所示

let myDate = Calendar.current.startOfDay(for: ed)

正如您所料,这会返回日期Feb 28, 2017, 12:00 AM。显然不是我想要存储在Firebase中的内容。最重要的是,我需要将日期放在Web服务返回的时区中。

更新 正如评论中所提到的,我还尝试创建一个Calendar实例,并将其timeZone属性设置为TimeZone,其中包含从服务器接收的标识符。代码看起来像这样

var easternCal = Calendar(identifier: .gregorian)
if let etz = TimeZone(identifier: easternTimeZone)
{
    easternCal.timeZone = etz
}

if let ed = easternDate
{
    let convertedDate = dateToTimeZone(date: ed, toTimezone: easternTimeZone)
    let currentCalDate = Calendar.current.startOfDay(for: ed)
    let myDate = easternCal.startOfDay(for: ed)
    print("\(myDate)")
}

昨晚,我可以发誓这不起作用,但是当我现在在操场上试试时,它看起来工作得很好。 currentCalDate是我不想要的日期Feb 28, 2017, 12:00 AM,因为它使用的是设置了太平洋时区的用户日历。 myDate正确显示为Feb 28, 2017, 9:00 PM,正在打印为2017-03-01 05:00:00 +0000,这是我一直想要的。

我认为这个问题已经解决了。

1 个答案:

答案 0 :(得分:0)

正如我的问题更新中所提到的,创建一个Calendar实例并将timeZone属性设置为从后端返回的属性解决了我的问题。