iOS 倒计时,date 一些坑

这几天做的东西涉及到日历类和时间类,各种操作。代码撸的要死。

这边注意下,在代码中撸的时间,系统默认都是格林时间 为基准的

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的格式是

这个太TM重要了,我以前以为
大小写不区分的。蠢得要死,改了好长时间的BUG
大家一定要记住,不能乱写啊。乱写的话,转换就会出现问题。

G: 公元时代,例如AD公元
yy: 年的后2位
yyyy: 完整年
MM: 月,显示为1-12
MMM: 月,显示为英文月份简写,如 Jan
MMMM: 月,显示为英文月份全称,如 Janualy
dd: 日,2位数表示,如02
d: 日,1-2位显示,如 2
EEE: 简写星期几,如Sun
EEEE: 全写星期几,如Sunday
aa: 上下午,AM/PM
H: 时,24小时制,0-23
K:时,12小时制,0-11
m: 分,1-2位
mm: 分,2位
s: 秒,1-2位
ss: 秒,2位
S: 毫秒
//获取当前是时间 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 的某一个元素 进行调整

项目中一开始有个需求就是对对明天后天 的这个时候做一些事情,我一开始想到就是就是加上时间差。最后感觉好蠢的感觉。查了一些资料,知道系统的提供的日历类,可以实现这些操作。

正书就是+ 负数就是➖

+(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);

关于rounloop和timer 可以看这边https://www.mgenware.com/blog/?p=459

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,457评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,837评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,696评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,183评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,057评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,105评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,520评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,211评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,482评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,574评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,353评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,897评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,489评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,683评论 2 335

推荐阅读更多精彩内容

  • 在iOS开发中,经常会遇到各种各样的时间问题,8小时时差,时间戳,求时间间隔,农历等等。解决办法网上比比皆是,但大...
    真巧了_嘿阅读 2,742评论 0 7
  • 自2012初中毕业后,就出社会打工 记得那时我还是16岁呢,这3年来做过许多工作,j可没有一样是能坚持的,像在混日...
    不安的初衷阅读 323评论 1 2
  • “杜掌门……” “杜掌门……” “杜掌门……” 一遍遍的呼唤使杜闻涛从昏迷中猛然惊醒。 烛光微弱,四周黑影重重。一...
    葛弗阅读 232评论 0 0
  • 《爱情与友谊》一听便知是来自简奥斯汀的改编剧,和此前的《傲慢与偏见》、《理智与情感》等剧在名字上一气呵成。故事讲述...
    小烨子小叶子阅读 6,236评论 0 3
  • 从很小时候,就喜欢看别人跳舞。不管是什么舞蹈,都会看到人迷。后来,自己也去学了舞蹈,从按部就班的学习每一个肢...
    我是葉子阅读 295评论 0 0