iOS |斯威夫特|日期格式 |出了什么问题?

问题描述

我们正在从服务器获取格林威治标准时间的日期。在解析时,我们使用 dateDecodingStrategy 作为 iso8601。我们还从服务器获取特定的时区字符串。我们需要考虑该时区并将 GMT 日期转换为特定于该时区。

private func dateInUserTImeZone(date: Date) -> Date {
         //userSessionTImeZone is the TimeZone received from server.
        let timezoneOffset =  userSessionTImeZone.secondsFromGMT(for: date)
        let epochDate = date.timeIntervalSince1970
        let timezoneEpochOffset = epochDate + Double(timezoneOffset)
        let updatedDate = Date(timeIntervalSince1970: timezoneEpochOffset)
        return updatedDate
    }

转换为从服务器收到的时区 (CST) 后的日期 --> 2021-02-12 03:18:54 +0000 使用上述函数,其中我们传递了通过解析 JSON 响应创建的 iso8601 日期

//下面的代码是对上面的日期应用格式。

let dateFormatter: DateFormatter(dateFormat: "MMMdd",useTemplate: true)
dateFormatter.setLocalizedDateFormatFromTemplate(dateFormatTemplate)
dateFormatter.doesRelativeDateFormatting = isRelative
let strDate = dateFormatter.string(from: date) //** date is 2021-02-12 03:18:54 +0000**

我们在 strDate 中获得的值是 2 月 11 日而不是 2 月 12 日

这里出了什么问题,如何解决?将日期转换为特定时区也是进行其他计算的必要条件。

解决方法

iOS 中没有“某种时间格式的日期”。日期是一个时间点。它根本没有时区。

文本可以以依赖时区的方式描述日期。这就是你的输入:你有一个字符串,你被告知它是格林威治标准时间的字符串。因此,您使用具有 GMT 正确设置的 DateFormatter 将字符串转换为日期。你永远不会改变那个日期。您可以使用另一个具有正确设置的 DateFormatter 为用户将日期转换为用户时区中的字符串。

顺便说一句。绝对不需要通过调用 timeIntervalSince1970 为 Date 添加秒数。有一种方法可以将秒直接添加到日期。还有一些方法可以将分钟、小时、天、周、月、年添加到日期;这些需要一个 Calendar 对象,因为添加“一个月”的含义取决于日历。