NSDateFormatter dateFrom带有时代的字符串

时间:2011-01-26 15:24:17

标签: iphone nsdateformatter

我正在尝试解析只包含多年的日期 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.为什么我得到小时差异?

3 个答案:

答案 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")
}