NSDateComponents 返回意外结果

NSDateComponents returning unexpected result

我有这段代码

NSDateComponents *comps = [[NSCalendar currentCalendar] components:(NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay) fromDate:sender.date];
[comps setTimeZone:[NSTimeZone timeZoneWithName:@"UTC"]];
NSDate *converted = [[NSCalendar currentCalendar] dateFromComponents:comps];

Sender.date可以像

一样输出到控制台

1963-02-23 12:00:00 am +0000

但是 UTC 的 comps.day 给了我 22。我希望它是 23,因为 UTC 中的发件人值显然包含等于 23 的日分量。

这与凌晨 12 点有某种关系吗?我在这里错过了什么?

谢谢!

这取决于您的意图。考虑:

NSString *string = @"1963-02-23 12:00:00 am +0000";
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateFormat = @"yyyy-MM-dd hh:mm:ss a X";
NSDate *date = [formatter dateFromString:string];
NSCalendar *calendar = [NSCalendar currentCalendar];
calendar.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0];
NSDateComponents *comps = [calendar components:NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay fromDate:date];
NSLog(@"%@", comps);

这将报告:

<NSDateComponents: 0x610000140420>
Calendar Year: 1963
Month: 2
Leap month: no
Day: 23

然后我可以将其转换为我们当地时区的日期:

NSDate *converted = [[NSCalendar currentCalendar] dateFromComponents:comps];
NSLog(@"%@", converted);

这将显示为我当地时区 (GMT-8) 的午夜,也就是格林威治标准时间上午 8 点:

1963-02-23 08:00:00 +0000

但是,当我使用格式化程序向用户显示此内容时,它会在我的本地时区向我显示:

NSDateFormatter *outputFormatter = [[NSDateFormatter alloc] init];
outputFormatter.dateStyle = NSDateFormatterMediumStyle;
outputFormatter.timeStyle = NSDateFormatterMediumStyle;
NSLog(@"%@", [outputFormatter stringFromDate:converted]);

那将显示:

Feb 23, 1963, 12:00:00 AM

显然,如果您不想显示时间,请使用 timeStyleNSDateFormatterNoStyle,但我包含它只是为了向您展示实际情况。

就个人而言,我发现以上所有内容都非常令人费解。我猜原始字符串试图反映一个独立于任何特定时间 and/or 时区(例如生日、周年纪念日等)的日期,然后我认为如果您省略时间,一切都会容易得多和来自原始字符串的时区信息,只需捕获 yyyy-MM-dd 格式的日期并将其保留在该格式。这样就简化了上面的大部分代码。

我可能会建议澄清你的实际意图,为什么你正在做你正在做的事情,我们也许能够提供更好的建议。