我正在尝试解析只包含多年的日期 145 或 123 BC 进入NSDate对象 - 到目前为止还没有取得多大成功。
NSDateFormatter f = [[NSDateFormatter alloc]init];
[f setTimeZone:[NSTimeZone systemTimeZone]];
[f setFormatterBehavior:NSDateFormatterBehaviorDefault];
[f setDateFormat:@"y GG"];
date = [f dateFromString:yearString];
yearString包含例如 145 或 123 BC
结果是:
如果我在dateFormat中指定了时代(GG),我会变为零
如果我只是在setDateFormat中指定年份(y),而我解析的年份是145,我会得到一个日期,但实际上是 145之前的 1小时。
两个问题:
1.将带有时代后缀的年份解析为NSStrings的正确方法是什么?
2.为什么我得到小时差异?
答案 0 :(得分:2)
小时差异怎么样?
您的时区可能是GMT + 1。因此,您实际上并未提前一小时获取日期,但(因为您的日期格式化程序设置为您的时区),您将日期解析为145-01-01 00:00 +0100
。现在,当您使用-[NSDate description]
输出日期时,它会为您提供GMT中的等效时间点144-12-31 23:00 +0000
。
答案 1 :(得分:1)
如果您不包含时代后缀,您将从格式化程序中获得nil
,就像“145”的情况一样。让它'145 AD',我想你会发现它有效。日期格式组件不是可选的 - 您必须匹配整个模式。
答案 2 :(得分:1)
我自己遇到过这个问题。 @ OleBergmann对你问题第二部分的回答是正确的,但是虽然@ bosmac对问题主要部分的回答在技术上是正确的,但它并不是很有帮助。
这就是我所做的......
func laxDate(str: String) -> Date? {
let strictDF = DateFormatter()
strictDF.dateFormat = "yyyy GG"
let laxDF = DateFormatter()
laxDF.dateFormat = "yyyy"
if let d = strictDF.date(from: str) {
return d
} else if let d = laxDF.date(from: str) {
return d
} else {
return nil
}
}
print(String(describing: laxDate(str: "1901"))) // "Optional("1901-01-01 00:00:00 +0000")\n"
print(String(describing: laxDate(str: "10 BC"))) // "Optional("-0009-01-01 00:01:15 +0000")\n"
或者,更简洁......
func laxDate(str: String) -> Date? {
func df(_ f: String) -> Date? {
let df = DateFormatter()
df.dateFormat = f
return df.date(from: str)
}
return df("yyyy GG") ?? df("yyyy")
}