博客已经迁移到www.chjsun.top

最近想做一个万年历似的东西,因为需要把农历也添加进去,就想直接调用苹果自带的api,这样还方便一些,

搜索了一下,苹果对于时间的处理,还是提供了很多选择给我们用的

比如:

  NSDate -- 表示一个绝对的时间点
  NSTimeZone -- 时区信息
  NSLocale -- 本地化信息
  NSDateComponents -- 一个封装了具体年月日、时秒分、周、季度等的类
  NSCalendar -- 日历类,它提供了大部分的日期计算接口,并且允许您在NSDate和NSDateComponents之间转换
  NSDateFormatter -- 用来在日期和字符串之间转换 。

今天,我们就说说我在开发时遇到的问题:

主要问题有两个

  1, 就是NSDate

  2, 就是NSCalendar

--1------

NSDate

// 日期和字符串之间的转换
- (NSDate *) strToDate
{
NSString *dateStr = @"1986-9-14"; NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
// 这个格式可以随便定义,比如:@"yyyy,MM,dd,HH,mm,ss"
[formatter setDateFormat:@"yyyy-MM-dd"]; // 年-月-日
// 将字符串按照格式转换成NSDate
NSDate *date = [formatter dateFromString:dateStr];
return date;
}

这段代码本身是可以用的

OC calendar 实践中的那些坑-LMLPHP

在这里,可以看到  已经成功的将9-29日转换成 utc的9-28日

但是(怎么问题总是在"但是"里 —_—):

  这段代码,在dateStr 是 @"1986-5-4"的时候,date为空,在@"1986-5-5" 和@"1986-9-14"之间
  date是 "xxxx-xx-xx 15:00:00 UTC"。下图为证

OC calendar 实践中的那些坑-LMLPHP

OC calendar 实践中的那些坑-LMLPHP

我们都是知道的,中国在东八区,应该是 16:00:00 才对,而且只有这一时间段出问题,这是不正常。

原因: 这是因为中国的"夏令时问题"

1986年4月,我国采取夏令时,具体作法是:每年从四月中旬第一个星期日的凌晨2时整(北京时间),将时钟拨快一小时,即将表针由2时拨至3时,夏令时开始;到九月中旬第一个星期日的凌晨2时整(北京夏令时),再将时钟拨回一小时,即将表针由2时拨至1时,夏令时结束。从1986年到1991年的六个年度,除1986年因是实行夏时制的第一年,从5月4日开始到9月14日结束外,其它年份均按规定的时段施行。在夏令时开始和结束前几天,新闻媒体均刊登有关部门的通告。1992年起,夏令时暂停实行

也就是说:

  1986年4月13日至9月14日,
  1987年4月12日至9月13日,
  1988年4月10日至9月11日,
  1989年4月16日至9月17日,
  1990年4月15日至9月16日,
  1991年4月14日至9月15日。

这些时间是有问题的,15:00:00,是因为夏令时的原因

哪还有一个问题,就是5月4号为空,这个就还没想到

要解决这个问题很简单,因为默认使用的是Asia/Shanghai  所以只要添加两句代码就搞定了

// 日期和字符串之间的转换
- (NSDate *) strToDate
{
NSString *dateStr = @"2057-9-29";
NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; // 新添加的两句代码 ---------- start ----------
[formatter setTimeZone:[NSTimeZone timeZoneWithName:@"GMT"]];
[formatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"en_US"]];
// ---------- end ----------
[formatter setDateFormat:@"yyyy-MM-dd"]; // 年-月-日 时:分:秒
// 这个格式可以随便定义,比如:@"yyyy,MM,dd,HH,mm,ss"
NSDate *date = [formatter dateFromString:dateStr];
NSLog(@"date = %@", date); return date;
}

解决;

问题2:在使用NSCalendar的时候,时间是 2057-9-28日那天,农历day返回的是0,而其他时间返回的是1~30之间,为什么会出现这个问题呢,请看下面两张图

OC calendar 实践中的那些坑-LMLPHP

OC calendar 实践中的那些坑-LMLPHP

这两张图的28号 农历都是一个 o  那么,调用api 部分代码

/** 农历月 */
@property (nonatomic, strong) NSArray *chineseMonths; //农历月数据,加载一次足矣
-(NSArray *)chineseMonths{
if (!_chineseMonths) {
_chineseMonths = [NSArray arrayWithObjects:
@"正月", @"二月", @"三月", @"四月", @"五月", @"六月", @"七月", @"八月",
@"九月", @"十月", @"冬月", @"腊月", nil]; }
return _chineseMonths;
}
// get chinese day
-(NSString *)getChineseWeekDaysWithDate:(NSDate *)date{ NSCalendar *chineseCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierChinese];
NSDateComponents *localeComp = [chineseCalendar components: NSCalendarUnitDay fromDate:date]; return [self.chineseDays objectAtIndex:localeComp.day-];
}

角标变成-1 就报错了,解决办法就是在返回的时候做一次判断,根据上图显示,姑且就认为 o 就是30号

    return [self.chineseDays objectAtIndex:(localeComp.day==? : localeComp.day-)];

转载请注明出处

05-02 14:24