在 Objective-C 中解析 ISO8601 日期(iPhone OS SDK)

发布于 2024-09-01 08:45:17 字数 59 浏览 4 评论 0原文

如何将“2010-04-30T00:45:48.711127”解析为 NSDate? (并保持所有精度)

How do I parse "2010-04-30T00:45:48.711127" into an NSDate? (and maintain all precision)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

偷得浮生 2024-09-08 08:45:17

你的工作已经为你完成了。

NSDate 将丢弃任何超过 3 位小数的值(秒)。您可以创建 NSDate 的子类来保持该精度,但您还需要实现自己的解析和自定义格式化程序来输入和显示它,因为 NSDateFormatter 和 <它所基于的 code>CFDateFormatter 也会截断小数点后 3 位的精度。取决于你在做什么,但这应该不会那么难。

这是一个简单的子类(未实现 NSCodingNSCopying),它将保留您赋予它的所有精度。

@interface RMPreciseDate : NSDate {
    double secondsFromAbsoluteTime;
}

@end

@implementation RMPreciseDate

- (NSTimeInterval)timeIntervalSinceReferenceDate {
    return secondsFromAbsoluteTime;
}

- (id)initWithTimeIntervalSinceReferenceDate:(NSTimeInterval)secsToBeAdded {
    if (!(self = [super init]))
        return nil;

    secondsFromAbsoluteTime = secsToBeAdded;

    return self;
}

@end

然后,您可以请求 -timeIntervalSince1970 来获取 UNIX 纪元时间。

已经有一个 ISO8601 日期/时间解析器类,但由于它使用 NSDateComponents 来生成其日期,目前仅限于整秒精度,但您可以使用它作为起点,也许可以创建更精确的表示。

You have your work cut out for you.

NSDate will throw out any values past 3 decimal places for seconds. You can create a subclass of NSDate to hold on to that precision but you'll also need to implement your own parsing and custom formatters to input and display it since NSDateFormatter and CFDateFormatter, which it is built on, will also truncate precision after 3 decimal places. Depending on what you're doing though that shouldn't be all that hard.

This is a simple subclass (not implementing NSCoding or NSCopying) that will hold on to all the precision you give it.

@interface RMPreciseDate : NSDate {
    double secondsFromAbsoluteTime;
}

@end

@implementation RMPreciseDate

- (NSTimeInterval)timeIntervalSinceReferenceDate {
    return secondsFromAbsoluteTime;
}

- (id)initWithTimeIntervalSinceReferenceDate:(NSTimeInterval)secsToBeAdded {
    if (!(self = [super init]))
        return nil;

    secondsFromAbsoluteTime = secsToBeAdded;

    return self;
}

@end

You can then ask for the -timeIntervalSince1970 to get UNIX epoch time.

There is an ISO8601 date/time parser class already out there, but since it's using NSDateComponents to generate its date it's limited to full-second precision currently, but you could use it as a starting point perhaps to create more precise representations.

凉栀 2024-09-08 08:45:17

我将尝试使用 ISO 8601 解析器和解解析器来处理类似的情况: http://boredzo.org/iso8601parser/< /a>

I'm going to try this ISO 8601 parser and unparser for a similar situation: http://boredzo.org/iso8601parser/

一身骄傲 2024-09-08 08:45:17

看来 NSDate 只有毫秒精度。

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:@"yyyy-MM-dd'T'hh:mm:ss.SSSSSS"];

    NSDate *date = [dateFormatter dateFromString:@"2010-04-30T00:45:48.711127"];

    NSLog(@"%@", date);

    NSString *string = [dateFormatter stringFromDate:date];

    NSLog(@"%@", string);

    [pool drain];
    return 0;
}

该代码产生以下控制台输出:

Program loaded.
run
[Switching to process 27202]
Running…
2010-05-08 20:02:46.342 TestNSDate[27202:a0f] 2010-04-30 00:45:48 -0700
2010-05-08 20:02:46.344 TestNSDate[27202:a0f] 2010-04-30T12:45:48.711000

Debugger stopped.
Program exited with status value:0.

因此 "2010-04-30T00:45:48.711127" 可能不会变成 "2010-04-30T00:45:48.711000"你的想法是什么。

It seems the NSDate only has millisecond precision.

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:@"yyyy-MM-dd'T'hh:mm:ss.SSSSSS"];

    NSDate *date = [dateFormatter dateFromString:@"2010-04-30T00:45:48.711127"];

    NSLog(@"%@", date);

    NSString *string = [dateFormatter stringFromDate:date];

    NSLog(@"%@", string);

    [pool drain];
    return 0;
}

That code yields the following console output:

Program loaded.
run
[Switching to process 27202]
Running…
2010-05-08 20:02:46.342 TestNSDate[27202:a0f] 2010-04-30 00:45:48 -0700
2010-05-08 20:02:46.344 TestNSDate[27202:a0f] 2010-04-30T12:45:48.711000

Debugger stopped.
Program exited with status value:0.

So "2010-04-30T00:45:48.711127" turning into "2010-04-30T00:45:48.711000" is probably not what you have in mind.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文