首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >关于NSDateFormatter和NSCalendar的问题(涉及时区)

关于NSDateFormatter和NSCalendar的问题(涉及时区)
EN

Stack Overflow用户
提问于 2011-08-02 02:08:10
回答 1查看 1.4K关注 0票数 0

我有以下代码:

代码语言:javascript
运行
复制
    self.formatter = [[NSDateFormatter alloc] init];
    [formatter setTimeZone:timeZone];
    [formatter setDateFormat:@"YYYY-MM-dd hh:mm:ss a z"];
    timeStampForCity = [formatter stringFromDate:[NSDate date]];
    NSLog(@"%@", timeStampForCity);
    updateDate = [formatter dateFromString:timeStampForCity];
    NSLog(@"%@", updateDate);

NSLog(@"%@", timeStampForCity);输出:

代码语言:javascript
运行
复制
2011-08-01 10:05:50 PM EDT

但是NSLog(@"%@", updateDate);输出:

代码语言:javascript
运行
复制
2011-08-02 02:05:50 +0000

我需要updateDate来显示当前时区中的时间(例如,如第一个NSLog()输出所示)。我该如何正确地做这件事?

编辑1

我也有这样的代码:

代码语言:javascript
运行
复制
    NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
    unsigned unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit |  NSDayCalendarUnit| NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit | NSTimeZoneCalendarUnit;
    NSDateComponents *dateComponents = [gregorian components:unitFlags fromDate:[NSDate date]];
    [dateComponents setTimeZone:[NSTimeZone timeZoneWithName:cityNameFormatted]];
    updateDate = [gregorian dateFromComponents:dateComponents];
    [gregorian release];

但是它所显示的时区对于很多地区来说都是关闭的。

提前感谢你的帮助。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-08-02 04:10:29

又来了..。

日期是一个独立的时间点。它的存在和将永远存在,无论人类和我们的时间测量设备是否存在。时区是人类的发明,帮助我们不要发疯。陪审团还不清楚他们在这方面是否有效。:P

当你谈到想要一个“EDT或任何其他时区中的日期”时,你无法理解日期是什么。时区只是显示时间点的一个方面。

所以,你有一个NSDate。无论您在哪个时区,此日期都是正确的日期。那么如何“显示当前时区中的时间”呢?您使用的是NSDateFormatter

NSDate本质上是不可读的。有一些方法可以表示日期,例如从不同的时间点来的秒间隔(这是一个任意长的间隔本身)。但是,要使日期具有可读性,只能通过将日期格式化为字符串来完成。所以,让我们这样做:

代码语言:javascript
运行
复制
NSDate *myDate = [NSDate date]; // or whatever date you want to make human-readable
NSDateFormatter *f = [[NSDateFormatter alloc] init];
[f setDateStyle:NSDateFormatterLongStyle];
[f setTimeStyle:NSDateFormatterLongStyle];

NSArray *timeZoneNames = [NSTimeZone knownTimeZoneNames];
for (NSString *name in timeZoneNames) {
    NSTimeZone *tz = [NSTimeZone timeZoneWithName:name];
    [f setTimeZone:tz];
    NSLog(@"%@", [f stringFromDate:date]);
}

现在,很明显,这个输出将非常长(我的输出超过400行)。但这里有一个输出的样本:

代码语言:javascript
运行
复制
...
August 2, 2011 1:03:38 AM GMT-03:00
August 2, 2011 12:03:38 AM AST
August 2, 2011 12:03:38 AM GMT-04:00
August 1, 2011 11:03:38 PM EST
August 2, 2011 1:03:38 AM GMT-03:00
August 1, 2011 11:03:38 PM CDT
August 2, 2011 12:03:38 AM AST
August 2, 2011 1:03:38 AM GMT-03:00
August 1, 2011 10:03:38 PM CST
August 2, 2011 12:03:38 AM AST
August 2, 2011 12:03:38 AM GMT-04:00
August 1, 2011 11:03:38 PM GMT-05:00
August 1, 2011 10:03:38 PM MDT
August 1, 2011 10:03:38 PM MDT
August 2, 2011 12:03:38 AM GMT-04:00
August 1, 2011 11:03:38 PM CDT
August 1, 2011 11:33:38 PM GMT-04:30
August 2, 2011 1:03:38 AM GMT-03:00
August 1, 2011 11:03:38 PM EST
August 1, 2011 11:03:38 PM CDT
August 1, 2011 10:03:38 PM MDT
...

我们在这里看到了什么?同一日期有一大堆不同的字符串表示!整洁!换句话说,格式化程序的时区是用来确定输出字符串的样子的。

因此:日期本身与无关,与时区无关。如果您想要一个日期看起来一定的方式,您必须配置格式化程序使它看起来那样。

更新从你的评论,我想我得到了你想要的。要为某个时区格式化日期组件吗?换句话说,你有一个时间点,你想知道美国东部时区的时间/分钟/秒是多少?

如果是这样的话,那么你可以根据日历来做

代码语言:javascript
运行
复制
NSDate *date = [NSDate date];
NSCalendar *cal = [NSCalendar currentCalendar];
[cal setTimeZone:[NSTimeZone timeZoneWithName:@"EST"]];

NSDateComponents *components = [cal components:NSUIntegerMax fromDate:date];
NSLog(@"%@", components);

这会给你:

代码语言:javascript
运行
复制
<NSDateComponents: 0x100124240> 
 Calendar: <CFCalendar 0x100133e90 [0x7fff7605cea0]>{identifier = 'gregorian'} / Time Zone: EST (GMT-05:00) offset -18000
 Era: 1
 Year: 2011
 Month: 8
 Day: 2
 Hour: 9
 Minute: 47
 Second: 21
 Week of Month: 1
 Week of Year: 31
 Year for Week of Year: 2011
 Weekday: 3
 Weekday Ordinal: 1
 Quarter: 0
票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6906584

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档