我拼命想要了解swift的DatePicker。我需要选择从Julian Day 0(公元前11/24/4714)到未来日期的日期。当我从DatePicker中提取DateComponents时,它们看起来并不像是一个“预防性的”。阳历日历。例如,通过选择3/1/300 AD(或CE),月和日是2/29。这似乎与朱利安日历一致,这是我无法选择将DatePicker的日历设置为iso8601或格里高利的日期。我熟悉格里高利历的采用日期,实际上这就是差异的开始。但为什么不能计算出预感日期,或者我误解了这一点。提取这些组件对于计算Julian Day等各种数量或从一个日历转换为另一个日历是必要的。即使是建议在哪里找到信息也会受到赞赏。
---编辑显示代码-----
@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!)
答案 0 :(得分:0)
结论:DatePicker中显示的内容与其生成的日期对象的“元素”(即年,月和日)之间的差异完全是由于我编写代码时出现的一个粗心错误:未能确保所有处理日期的对象都指定给同一个Calendar。最初,我的DateFormatter和DateComponents对象设置为“.iso8601”,并且没有为DatePicker指定日历,默认为我的语言环境,这意味着“.gregorian”。这在1582年10月15日之前产生了10天的差异。另外:使用公历的DatePicker将允许您选择1582年10月5日至1582年10月14日(含)的日期,正如我对预期的那样日历。使用ISO日历的DatePicker将不允许此范围内的日期。从1582年10月15日开始减少一天将导致DatePicker显示1582年10月4日...如果它是基于预感格里高利的话,我不会想到的结果。
但是,有些警告。 Apple的文档和ISO标准本身让我相信ISO日历是基于一个公历的阳历。事实证明这是不真实的。您可以自己重复以下操作:创建一个指定ISO日历的DatePicker,它将允许您选择公历中不存在的日期,即1500,1400,1300,1100,1000等年份的闰年这更符合ISO日历的行为,就像采用日期之前的Julian日历一样。实际上,由于ISO日历将这些年数量计为闰年,因此年数差异开始缩小。从公元300年3月1日到2月28日,错误变为零,正如人们对朱利安历法与公历日历的预期一样。我不知道我是否误解了ISO日历应该如何表现,或者这是一个错误。感谢Willeke带领我找到正确的解决方案!