做的东西涉及到日历类和时间类,各种操作。代码撸的要死。 这边注意下,在代码中撸的时间,系统默认都是格林时间 为基准的 1获取当前时区时间1.1获取当前时间类型为NSDate类型的 获取当前时区 判断当前时区与格林时区的时间差 获取当前时间加上时间差 //获取当前时区时间 +(NSDate *)getCurrentLocaleDate:(NSDate *)ADate { NSTimeZone *timeZone = [NSTimeZone systemTimeZone]; NSTimeInterval interval = [timeZone secondsFromGMTForDate:ADate]; NSDate *nowDate = [ADate dateByAddingTimeInterval:interval]; return nowDate; } 1.1获取当前时间类型为NSString类型的 系统提供了了一个NSDateFormatter 类 这个format的格式是 YYYY年 MM月 DD日 EE 星期 HH时 MM分钟 SS秒 这个不区分大小写的一般来说都是大写(可能显的正式一点) //获取当前是时间 string +(NSString *) getCurrentLocaleString:(NSDate *) Adate { NSDateFormatter *outputFormatter = [[NSDateFormatter alloc] init]; outputFormatter.locale = [NSLocale currentLocale]; [outputFormatter setDateFormat:@"yyyy-MM-DD HH:mm:ss"]; return [outputFormatter stringFromDate:Adate]; } 2.从服务器获取的时间 转换我当时在从服务器获取时间之后,就用NSDateFormatter 格式化直接用了,结果感觉蹦蹦哒0.0 我们从服务器获取的时间都是我们当前时区的时间,可因为获取的类型不通,我们需要转换成不同的类型供我们使用, 上面的代码 思路都是 格式时间+时间差 因为系统是按照格林时间为基准的,你从服务器获取的时间 系统会认为是格林时间。 这时候你转换的时候,就要告诉系统,这是正确的时间 和格林时间差为0。 +(NSString *) stringFormDate:(NSDate *) Adate{ NSDateFormatter *outputFormatter = [[NSDateFormatter alloc] init]; [outputFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]]; [outputFormatter setDateFormat:@"yyyy-MM-DD HH:mm:ss"]; return [outputFormatter stringFromDate:Adate]; } 3 Date 的某一个元素 进行调整项目中一开始有个需求就是对对明天后天 的这个时候做一些事情,我一开始想到就是就是加上时间差。最后感觉好蠢的感觉。查了一些资料,知道系统的提供的日历类,可以实现这些操作。 正书就是+ 负数就是:heavy_minus_sign: +(NSDate *)addYear:(NSInteger)year Month:(NSInteger)month Day:(NSInteger)day date:(NSDate *)date{ //这个是日历类 NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; //date元素类,可以对date的元素操作。 NSDateComponents *adcomps = [[NSDateComponents alloc] init]; [adcomps setYear:year]; [adcomps setMonth:month]; [adcomps setDay:day]; NSDate *date1 = [calendar dateByAddingComponents:adcomps toDate:date options:0]; return date1; } 我这边只写了年月日 不过NSDateCompoents 提供了这么多属性。想怎么玩就怎么玩。 @property NSInteger era; @property NSInteger year; @property NSInteger month; @property NSInteger day; @property NSInteger hour; @property NSInteger minute; @property NSInteger second; @property NSInteger nanosecond NS_AVAILABLE(10_7, 5_0); @property NSInteger weekday; @property NSInteger weekdayOrdinal; @property NSInteger quarter NS_AVAILABLE(10_6, 4_0); @property NSInteger weekOfMonth NS_AVAILABLE(10_7, 5_0); @property NSInteger weekOfYear NS_AVAILABLE(10_7, 5_0); @property NSInteger yearForWeekOfYear NS_AVAILABLE(10_7, 5_0); 4 Date 倒计时功能项目中还需要实现倒计时功能,我第一个想到的就是全部换成 秒 进行运算(感觉自己蠢得要死)。 其实 实现倒计时功能挺简单的,但其中还挺多坑的。 我简单提一下,要实现倒计时2种方法。 一个用NSTimer(这个要涉及到NSRunLoop ) 一个用GCD(这个写起来烦的要死,不过性能据说是杠杠的) 我代码都贴出来一下吧 4.1 NSTimer//设置一个未来的时间 计算时间差 - (void)resetTimerWithDate:(NSDate *)futureDate{ NSTimeInterval futureTimeInterval = [futureDate timeIntervalSinceDate:[[NSDate date] dateByAddingTimeInterval:3600*8]]; self.interval = futureTimeInterval; if (self.timer == nil) { self.timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timeDecrease:) userInfo:nil repeats:YES]; //因为我timer 是放在UI线程的 要指定NSRunloop的模式为NSRunLoopCommonModes [[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes]; } } - (void)timeDecrease:(NSTimer *)timer{ self.interval --; if (self.interval <= 0) { //如果计数器 = 0 或者 自己已经不在屏幕上了 [timer invalidate]; timer = nil; return; } int day = self.interval/(3600*24); int hour = (self.interval - day*(3600*24))/3600.0; int min = (self.interval - day*(3600*24) - hour*3600)/60; int sec = (self.interval - day*(3600*24) - hour*3600 - min*60); NSArray *arr = @[@(day),@(hour),@(min),@(sec)]; //到这里已经可以获取到具体的时差 这边可以显示在你 } 如果timer放在子线程里面, 可以不用设置Runloop的模式,但有一个要注意要手动启动runloop 4.2GCD//这个_timer 设置成成员变量 { dispatch_source_t _timer; } //借用上面的计算时间间隔的方法 计算出时间间隔 __block int timeout = timeInterval; //倒计时时间 //创建一个专门执行timer回调的GCD队列 dispatch_queue_t queue = dispatch_queue_create("my queue", 0); //创建Timer _timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue); //使用dispatch_source_set_timer函数设置timer参数 dispatch_source_set_timer(_timer, dispatch_time(DISPATCH_TIME_NOW, 0), interval, 0); //设置回调 dispatch_source_set_event_handler(_timer, ^(){ if(timeout<=0) { //倒计时结束,关闭 dispatch_source_cancel(_timer); _timer = nil; dispatch_async(dispatch_get_main_queue(), ^{ //主线程显示 }); timeout--; }); //dispatch_source默认是Suspended状态,通过dispatch_resume函数开始它 dispatch_resume(_timer);(责任编辑:好模板) |