zoukankan      html  css  js  c++  java
  • 跳出NSDate

    感觉任何语言关于时间的格式化处理,时区的处理都是多的,最近被NSDate的各种问题坑了好久

    先看看关于NSDate自己的问题

    1.NSDate

    NSDate获取当前时间

    NSDate *date=[NSDate date];

    [NSDate date],输出是GMT时间(GMT(Greenwich Mean Time)代表格林尼治标准时间),如果想获取当前时间需要通过时间戳进行转换

    +(NSDate *)GetLocalTimeNow:(NSDate *)date{
        NSTimeZone *timezone=[NSTimeZone systemTimeZone];
        NSInteger interval=[timezone secondsFromGMTForDate:date];
        NSDate *localdate=[date dateByAddingTimeInterval:interval];
        return localdate;
    }

    初步看起来是没有问题了,第一步获取当前时区,第二步计算当前时区和GMT时区的差值,第三步通过时区差将时间增加差值获取当前时间

    输出当前时间是

    "2014-12-16 10:20:58 +0000"

    看后面的+0000是不是感觉有不对了,假如当前时区是beijing,那么时间是不对的了,应该是+0800,这里我绕了个圈子,其实我们用[NSDate date]获得的就是当前时间,只不过是GMT的时间,如果我们加自己时区的间隔只不过是把GMT时间添加了8个小时而已,其实相对我们来说吧GMT时间加8小时输出,换算为我们本地时间的话也会增加8个小时,下面我们用NSString输出试一下看看

    2.NSDate与NSString的转换

    苹果用NSDateFormatter进行NSDate和NSString之间的转换,HH代表24小时制,hh代表12小时制

    +(NSString *)MakedatetoStr:(NSDate *)date{    
        NSDateFormatter *datef=[[NSDateFormatter alloc]init];
        [datef setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
        NSString *datestr=[datef stringFromDate:date];
        return datestr;
    }

    这次我们输入[NSDate date]的时间,看看输出是不是当前时间

    动手试一下,可以看到

    2014-12-16 10:20:58

    上下代码是一起运行的,所以可以看出,如果我们使用格式化字符串的默认输出就是本地时间,是不需要进行时间戳换算的,如果需要时间转换,只需设置时区就好了

    比如

    增加一行国外的时区

    [datef setTimeZone:[NSTimeZone timeZoneWithName: @"America/Adak"]];

    locatime:2014-12-16 11:31:38

    GMT        : 2014-12-16 03:31:38

    America :2014-12-15 17:31:38


    但是我想输出时区怎么办呢,如果换了格式怎么办呢,我需要找出苹果的格式化字符串说明文档,通过帮助文档居然找到了苹果的ISO文档

    Date Field Symbol Table

    image

    根据zone格式化字符说明只需增加一个大“Z”即可,年月日小时分秒 时区均是分开的格式化字符串,所以你可以随便排列他们的顺序

    +(NSString *)MakedatetoStr:(NSDate *)date{
        
        NSDateFormatter *datef=[[NSDateFormatter alloc]init];
         NSDateFormatter *datef2=[[NSDateFormatter alloc]init];
        [datef2 setDateFormat:@"yyyy-MM-dd HH:mm:ss Z"];
        [datef setDateFormat:@"Z yyyy-MM-dd HH:mm:ss}"];
        [datef setTimeZone:[NSTimeZone timeZoneWithName: @"America/Adak"]];
        NSString *datestr=[datef stringFromDate:date];
        NSLog(@"locatime%@,GMT:%@,America:%@",[datef2 stringFromDate:date],date,datestr);
        return datestr;
    }

    locatime2014-12-16 13:41:17 +0800

    ,GMT:2014-12-16 05:41:17 +0000,

    America:-1000 2014-12-15 19:41:17

    这样我们也就能进行反方向的转换了

    +(NSDate *)GetLocalTimeNowFromstr:(NSString *)dateString{
        
       NSDateFormatter *datef=[[NSDateFormatter alloc]init];
        [datef setDateFormat:@"yyyy-MM-dd HH:mm:ss Z"];
        NSDate *date=[datef dateFromString:dateString];
        return date;
    
    }
    输入

    2014-12-16 13:41:17 +0800

    输出

    2014-12-16 05:41:17 +0000

    瞧又回到我们一开的GMT时区了

    总结一下,其实我们在获得时间的时候完全不需要在进行时区转换,所有的地方按GMT时区来作为时间记录,想用的时候做一下时区转好就好了,本地时区的转换又非常的方便

    3.NSDate转.net Json格式时间

    通过上一篇介绍,.net格式化Json后的时间格式是/Date(xxxxxxxxxxxxx+xxxx)/,我试过无法通过AFNetwork直接按时间传入,那么只能格式化字符串了

    第一步获取时间和1970的时间间隔,返回时秒需要换成毫秒,即*1000,但是还会多两位,使用格式化字符串“%0.0lf”来取消小数点

    第二步获取时区数字 获得当前的时区,返回当前时区和标准时区的时间戳,单位是秒,需要×100抵消小数点,因为需要的是4位数,需要用零填充%04ld表示不满足4位用0填充

    第三步 获取时间,拼接字符串,这个大家都会吧。。

    +(NSString *)MakeJsonDate:(NSDate *)date{
        NSTimeInterval interval=[date timeIntervalSince1970]*1000;
        NSString *datestr=[[NSString alloc]initWithFormat:@"%0.0lf",interval];
        NSTimeZone *zone=[NSTimeZone systemTimeZone];
        NSInteger zoneinterval=[zone secondsFromGMT];
        NSInteger zonenum=zoneinterval/60/60*100;
        NSString *json=[[NSString alloc]initWithFormat:@"/Date(%@+%04ld)/",datestr,zonenum];
        return json;
    }

    至此终于解决这个头疼的问题了

    以后还是用字符串来传递时间吧。。。。

  • 相关阅读:
    Lucene.net中的异常处理
    解决lucene 1.* 使用排序后内存溢出问题
    常用的正则表达式
    我的博客开通了
    oracle 常用函数
    破解 office 正版增值计划补丁
    关于dbcommandbuilder的几点说明
    类型转换(一)
    可变数量的参数
    关闭页面时操作数据库
  • 原文地址:https://www.cnblogs.com/keithmoring/p/4167179.html
Copyright © 2011-2022 走看看