首页 > 解决方案 > Swift 日期格式化程序错误地转换/创建日期/字符串

问题描述

女士们,先生们,您好!

长话短说,我有一个辅助结构,其中有一些辅助函数用于创建日期格式化程序、日期对象和日期的字符串表示。我已经调试并将其缩小到这个:

func getFormattedString(from stringDate: String,
                                   with timeZoneID: String? = nil,
                                   appFormat appDateFormat: DateFormats = .api,
                                   apiFormat apiDateFormat: DateFormats = .api) -> String? {
        //this must use the default utc timezone so pass in the nil value here
        let apiDateFormatter = dateFormatter(with: apiDateFormat, timeZoneID: nil)
        if let utcDate = apiDateFormatter.date(from: stringDate) {
            let appDateFormatter = dateFormatter(with: appDateFormat, timeZoneID: timeZoneID)
            return appDateFormatter.string(from: utcDate)
        }
        return nil
    }

对于 dateFormatter(with:) 使用这个函数:

enum DateFormats: String {
    case api = "YYYY-MM-dd HH:mm:ss"
    // more cases here
}

let utcTimeZone = TimeZone(abbreviation: "UTC")

func dateFormatter(with dateFormat: DateFormats = .api, timeZoneID: String?) -> DateFormatter {
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = dateFormat.rawValue
        if let timeZoneID = timeZoneID {
            if let timezoneIdentifier = TimeZone(identifier: timeZoneID) {
                dateFormatter.timeZone = timezoneIdentifier
            } else if let abbreviatedTimezone = TimeZone(abbreviation: timeZoneID) {
                dateFormatter.timeZone = abbreviatedTimezone
            } else {
                dateFormatter.timeZone = utcTimeZone
            }
        } else {
            dateFormatter.timeZone = utcTimeZone
        }
        return dateFormatter
    }

基本上我从服务器得到一个字符串,它是 UTC,所以我从 UTC 时区的那个字符串创建我的 Date 对象。然后我正在创建另一个日期格式化程序,这次使用来自服务器的时区。到目前为止一切都很好,但我最近遇到了一个奇怪的案例。

假设我们有来自“服务器”的以下字符串: let start = "2021-12-25 00:00:00" let end = "2021-12-26 23:59:59"

当我们调用 getFormattedString(from: start) 时,它会为我们提供一个表示相同日期(年、月和日)的字符串,但如果我们在任何一年的 12 月 26 日调用它,则由日期格式化程序创建的字符串将从 2021 年自动递增到 2022 年...我看到这只发生在以下日期:从 12 月 26 日到 31 日,包括 26 日和 31 日。但是对于任何其他月份,这不会发生。

我真的想知道我是否从一开始就做错了什么,或者这确实是一个非常边缘的错误?

我必须根据事件的时区显示日期和字符串日期,再加上我们从服务器获得基于 UTC 时区的日期的事实,并且有一个日历必须显示从 UTC 到事件正确时区的所有内容,同时还确保整个日历可能会根据用户的当前时区而改变。我知道,处理日期并不愉快,但我 100% 肯定代码工作正常。我的意思是这是一个已经投入生产多年的功能,没有人提出这个问题(谢天谢地,这是一个每个人都花时间不工作的时期,不像我哈哈)。老实说,我什至不知道我是如何遇到这种超级边缘情况的......

任何帮助或建议都意义重大。提前谢谢大家:)

标签: iosswiftdatensdateformatterdateformatter

解决方案


问题是大写的“YYYY”,因为应该有小写的,如“yyyy”。解决方案。非常感谢Joakim大人。


推荐阅读