Xcode模拟器与Swift Playgrounds日期格式化结果不一致问题
日期格式化结果不一致问题
问题场景
Xcode iOS应用代码及运行结果
代码:
import SwiftUI struct ContentView: View { var body: some View { VStack { Button(action: { let dateToday = Date() let dateOneYearAgo = Calendar.current.date(byAdding: .year, value: -1, to: dateToday) ?? dateToday print("dateToday: \(dateToday) - dateOneYearAgo: \(dateOneYearAgo)") let dateFormatter = DateFormatter() dateFormatter.dateFormat = "YYYY-MM-dd" let dateTodayString = dateFormatter.string(from: dateToday) let dateOneYearAgoString = dateFormatter.string(from: dateOneYearAgo) print("dateTodayString: \(dateTodayString) - dateOneYearAgoString: \(dateOneYearAgoString)") }, label: { Text("Test").font(.largeTitle) }) } .padding() } }
运行输出:
dateToday: 2022-12-29 17:24:37 +0000 - dateOneYearAgo: 2021-12-29 17:24:37 +0000 dateTodayString: 2022-12-29 - dateOneYearAgoString: 2022-12-29
Swift Playgrounds代码及运行结果
代码:
import Foundation let dateToday = Date() let dateOneYearAgo = Calendar.current.date(byAdding: .year, value: -1, to: dateToday) ?? dateToday print("dateToday: \(dateToday) - dateOneYearAgo: \(dateOneYearAgo)") let dateFormatter = DateFormatter() dateFormatter.dateFormat = "YYYY-MM-dd" let dateString = dateFormatter.string(from: dateToday) let dateOneYearAgoString = dateFormatter.string(from: dateOneYearAgo) print("dateToday: \(dateString) - dateOneYearAgo: \(dateOneYearAgoString)")
运行输出:
dateToday: 2022-12-29 17:27:32 +0000 - dateOneYearAgo: 2021-12-29 17:27:32 +0000 dateTodayString: 2022-12-29 - dateOneYearAgoString: 2021-12-29
预期dateOneYearAgoString应为2021-12-29,但Xcode中结果不符,忽略了什么关键点?
问题原因与解决方案
核心问题是日期格式化字符串中YYYY和yyyy的区别:
YYYY代表基于周的年份(Week-Based Year):它会根据日期所属的周判断年份,比如部分年末日期可能属于下一年的第一周,部分年初日期可能属于上一年的最后一周。yyyy代表公历年(Calendar Year):即日期实际所属的公历年份,符合日常对年份的认知。
你的案例中,2021年12月29日在部分日历规则下属于2022年的第一周(比如ISO周历要求第一周至少包含4天在新公历年),所以用YYYY格式化时会得到2022;而Playgrounds和Xcode中Calendar.current的配置差异放大了这个问题,但本质是误用了YYYY。
解决方案
将日期格式字符串从"YYYY-MM-dd"改为"yyyy-MM-dd",即可得到预期的公历年结果:
dateFormatter.dateFormat = "yyyy-MM-dd"
内容的提问来源于stack exchange,提问作者THUB
相关产品推荐
相关产品推荐

