iOS自带三种日历,公历、佛教日历和日本日历,要设置日历能够进入"设置-通用-语言与地区-日历"设置,咱们中国使用的iPhone默认设置成公历。而泰国人使用的iPhone默认设置的日历是佛教日历。这样会致使一样的代码在国内显示正常,去泰国就仿佛穿越了通常。atom
问题:使用NSDate *today = [NSDate date];获取的当前的时间在国内显示正常是2017年,而到了泰国却变成了2056年,这是为何呢?即便是时区差异,也不能差如此多呀??spa
通过仔细思考,发现语言和地区的设置之中有一个地方能够设置日历,进去把公历改为佛教日历,发现原来显示的2017变成了2056。code
方法一:component
解决办法:提供一种不受时区、系统日历、本地化等限制,得到公历中的正确的年份、月份、时间等的方法。orm
Global.h对象
@property (strong,nonatomic) NSCalendar *calendar; @property (strong,nonatomic) NSDateComponents *components; @property (copy,nonatomic) NSString *year; @property (copy,nonatomic) NSString *month; @property (copy,nonatomic) NSString *day; @property (copy,nonatomic) NSString *hour; @property (copy,nonatomic) NSString *minute; @property (copy,nonatomic) NSString *second;
Global.mblog
- (NSCalendar *)calendar{ if(!_calendar){ #ifdef __IPHONE_8_0 _calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];//根据Identifer获取公历 #else _calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];//根据Identifer获取公历 #endif _calendar.timeZone = [NSTimeZone localTimeZone];//消除时区差别 _calendar.locale = [NSLocale currentLocale];//消除本地化差别,本地化包括语言、表示的日期格式等 } return _calendar; } - (NSDateComponents *)components{ if (!_components) { NSDate *date = [NSDate date]; _components = [self.calendar components:NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond | NSCalendarUnitWeekday fromDate:date]; } return _components; } //返回当前年份 - (NSString *)year{ if (!_year) { _year = [NSString stringWithFormat:@"%04ld",[kGlobal.components year]]; } return _year; } //返回当前月份 -(NSString *)month{ if (!_month) { _month = [NSString stringWithFormat:@"%02ld",[kGlobal.components month]]; } return _month; } //返回当前号数 - (NSString *)day{ if (!_day) { _day = [NSString stringWithFormat:@"%02ld",[kGlobal.components day]]; } return _day; } //返回当前的小时 - (NSString *)hour{ if (!_hour) { _hour = [NSString stringWithFormat:@"%02ld",[kGlobal.components hour]]; } return _hour; } //返回当前的分钟 - (NSString *)minute{ if (!_minute) { _minute = [NSString stringWithFormat:@"%02ld",[kGlobal.components minute]]; } return _minute; } //返回当前的秒钟 - (NSString *)second{ if (!_second) { _second = [NSString stringWithFormat:@"%02ld",[kGlobal.components second]]; } return _second; }
2017-02-04更新:string
方法二:正常获取公历年月日(系统日历为佛教日历或其余非公历日历)it
1.首先建立一个公历日历对象form
- (NSCalendar *)calendar{ if(!_calendar){ #ifdef __IPHONE_8_0 _calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];//根据Identifer获取公历 #else _calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];//根据Identifer获取公历 #endif _calendar.timeZone = [NSTimeZone localTimeZone];//消除时区差别 _calendar.locale = [NSLocale currentLocale];//消除本地化差别,本地化包括语言、表示的日期格式等 } return _calendar; }
2.在NSDateFormatter格式化对象的时候加上一条语句就行:[formatter setCalendar:self.calendar];
- (NSDateFormatter *)formatter{ if (!_formatter) { _formatter = [[NSDateFormatter alloc] init]; [_formatter setCalendar:kGlobal.calendar]; [_formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"]; } return _formatter; }
总结:NSDateFormatter若是不设置日历对象,默认使用的是系统的日历对象,因此不管你使用什么方式获得正确的公历年月日,若是最后格式化了日期,都会变成系统默认的日历日期,因此
格式化日期的时候须要设置NSDateFormatter的Calendar对象。同理系统默认的UIDatePicker应该也能够这么设置(有待验证)。