开发者

NSDateFormatter dateFrom String with era

开发者 https://www.devze.com 2023-02-07 08:01 出处:网络
I am trying to parse dates that only consist of years like 145 or 123 BC into NSDate Objects - with not much success so far.

I am trying to parse dates that only consist of years like 145 or 123 BC into NSDate Objects - with not much success so far.

NSDateFormatter f = [[NSDateFormatter alloc]init];
[f setTimeZone:[NSTimeZone systemTimeZone]];
[f setFormatterBehavior:NSDateFormatterBehaviorDefault];
[f setDat开发者_运维技巧eFormat:@"y GG"];
date = [f dateFromString:yearString];

yearString contains e.g. 145 or 123 BC

The results are:

I get nil if I specify the era (GG) in the dateFormat.

If I just specify the year (y) in setDateFormat and the year I parse is 145 I get a date, but it is actually 1 hour before 145.

Two questions:

1. What is the proper way to parse years with era suffixes into NSStrings? 2. Why do I get the hour difference?


how come the hour difference?

Your time zone is probably GMT+1. So you're not actually getting a date one hour earlier but (because your date formatter is set to your time zone), you are parsing the date as 145-01-01 00:00 +0100. When you now output the date with -[NSDate description], it will give you the equivalent point in time in GMT, which is 144-12-31 23:00 +0000.


You'll get nil from the formatter if you don't include an era suffix, as is the case for '145'. Make it '145 AD', and I think you'll find it works. The date format components aren't optional — you have to match the whole pattern.


Just came across this problem myself. @OleBergmann's answer to the second part of your question is correct, but although @bosmac's answer to the main part of your question is technically right, it's not very helpful.

Here's what I did...

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"

Or, more tersely...

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")
}
0

精彩评论

暂无评论...
验证码 换一张
取 消