我拼命想理解 swift 的 DatePicker。我需要选择从儒略历第 0 天(公元前 11 年 24 月 4714 日)到未来日期的日期。当我从日期选取器中提取日期组件时,它们似乎不是"外推"公历。例如,通过选择 3/1/300 AD(或 CE),月份和日期为 2/29。这似乎与儒略历一致,我无法选择日期选择器的日历设置为 iso8601 或公历。我熟悉采用公历的日期,事实上,这就是差异开始的地方。但是为什么它不计算外推日期,还是我误解了这一点。提取这些分量对于计算各种数量(如儒略日)或从一个日历转换为另一个日历是必需的。甚至建议在哪里找到信息也将不胜感激。
---编辑以显示代码-----
@IBAction func calculate(_ sender: Any) {
var mycal = Calendar(identifier: .iso8601)
//var mycal = Calendar(identifier: .gregorian)
let picked_date:Date = datePicker.dateValue
let formatter1 = DateFormatter()
formatter1.locale = Locale(identifier: "en_US_POSIX")
formatter1.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZZZZZ"
let picked_format = formatter1.string(from: picked_date)
//print("picked_format: (picked_format)")
let format_date = formatter1.date(from: picked_format)
var tz: String { return TimeZone.current.identifier }
let myzone = UTC.state == NSOnState ? tz : "GMT"
//let era = AD.state == NSOnState ? 1 : 0
mycal.timeZone = TimeZone(identifier: myzone)!
var comps = mycal.dateComponents([.year,
.month,
.day,
.hour,
.minute,
.second,
//.era,
//.nanosecond,
.timeZone],
from: format_date!)
print(comps.month!)
print(comps.day!)
底线:DatePicker 中显示的内容与它生成的日期对象(即 YEAR、MONTH 和 DAY)的"元素"之间的差异完全是由于我在编写代码时犯的一个粗心的错误:未能确保所有处理日期的对象都指定到同一个日历。最初,我的 DateFormatter 和 DateComponents 对象设置为".iso8601",并且未能为 DatePicker 指定日历,将其默认为我的区域设置,这意味着".gregorian"。这在 1582 年 10 月 15 日之前的日期产生了 10 天的差异。另外:使用公历的日期选择器将允许您选择从 1582 年 10 月 5 日至 1582 年 10 月 14 日(含)的日期,就像我对外推日历所期望的那样。使用 ISO 日历的日期选取器将不允许此范围内的日期。从 1582 年 10 月 15 日下降一天将导致日期选择器显示 1582 年 10 月 4 日 ...如果它基于外推格里高利,则不是我所期望的结果。
不过,有一些警告。苹果的文档和ISO标准本身使我相信ISO日历是基于外推公历的。事实证明这是不真实的。您可以自己重复以下内容:创建一个指定 ISO 日历的日期选择器,它将允许您选择公历中不存在的日期,即 1500、1400、1300、1100、1000 等年份的闰年。这更符合 ISO 日历的行为,就像采用日期之前的儒略历一样。事实上,随着年数的减少,日期差异开始缩小,因为ISO日历将这些年份计为闰年。从公元 200 年 3 月 1 日至公元 300 年 2 月 28 日,误差变为零,与人们对儒略历与外推公历的预期完全一样。我不知道我是否误解了ISO日历的行为方式,或者这是否是一个错误。感谢Willeke带领我找到正确的解决方案!