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
显然,如果您不想显示时间,请使用 timeStyle
或 NSDateFormatterNoStyle
,但我包含它只是为了向您展示实际情况。
就个人而言,我发现以上所有内容都非常令人费解。我猜原始字符串试图反映一个独立于任何特定时间 and/or 时区(例如生日、周年纪念日等)的日期,然后我认为如果您省略时间,一切都会容易得多和来自原始字符串的时区信息,只需捕获 yyyy-MM-dd
格式的日期并将其保留在该格式。这样就简化了上面的大部分代码。
我可能会建议澄清你的实际意图,为什么你正在做你正在做的事情,我们也许能够提供更好的建议。
我有这段代码
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
显然,如果您不想显示时间,请使用 timeStyle
或 NSDateFormatterNoStyle
,但我包含它只是为了向您展示实际情况。
就个人而言,我发现以上所有内容都非常令人费解。我猜原始字符串试图反映一个独立于任何特定时间 and/or 时区(例如生日、周年纪念日等)的日期,然后我认为如果您省略时间,一切都会容易得多和来自原始字符串的时区信息,只需捕获 yyyy-MM-dd
格式的日期并将其保留在该格式。这样就简化了上面的大部分代码。
我可能会建议澄清你的实际意图,为什么你正在做你正在做的事情,我们也许能够提供更好的建议。