• iOS 关于时区转化问题

    2017-10-16 16:23:08
    NSDate存储的是世界标准时(UTC),输出时需要根据时区转换为本地时间 转载出处 --------> 点击打开链接 好像是从ios4.1开始[NSDate date];获取的是GMT时间,这个时间和北京时间相差8个小时,以下代码可以解决...

    NSDate存储的是世界标准时(UTC),输出时需要根据时区转换为本地时间


    转载出处    -------->    点击打开链接

    好像是从ios4.1开始[NSDate date];获取的是GMT时间,这个时间和北京时间相差8个小时,以下代码可以解决这个问题

    //方法一

    - (void)tDate

    {

        NSDate *date = [NSDatedate];

        NSTimeZone *zone = [NSTimeZonesystemTimeZone];

        NSInteger interval = [zone secondsFromGMTForDate: date];

        NSDate *localeDate = [date  dateByAddingTimeInterval: interval];  

        NSLog(@"%@", localeDate);

    }

    方法二

    - (NSString*)dateAsString:(NSDate*)date

     {

    /* Create a single string expressing a mountain's climbed date, properly localized */

    NSString *returnValue = @"";

        NSDateFormatter *dateFormatter = nil;

    if (date != nil) {

    if (dateFormatter ==nil) {

    dateFormatter = [[NSDateFormatteralloc]init];

    }

    //原文地址:http://blog.csdn.net/diyagoanyhacker/article/details/7096612

    //作者:禚来强

    [dateFormatter setDateStyle:NSDateFormatterMediumStyle];

    [dateFormatter setTimeStyle:NSDateFormatterNoStyle];

    [dateFormatter setLocale:[NSLocalecurrentLocale]];

    returnValue = [dateFormatter stringFromDate:date];

    }

    /* As this code uses the current "locale", the date format will be in the format 

         specified by the user's "Region Format" settings.  If you need to use an

         alternate format internally, you can create and use NSLocales, e.g.:

     

         NSLocale *enGBLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_GB"];

         [numberFormatter setLocale:enGBLocale];

     

         Doing so will not affect the current user-set language or region format. 

         

         Similarly, while you should always rely on the system and application bundle

         to pick the most appropriate resources for the current user language setting,

         if you need to know what the current user language setting is, you can do

         something like the following:

     

         NSUserDefaults* defs = [NSUserDefaults standardUserDefaults];

         NSArray* languages = [defs objectForKey:@"AppleLanguages"];

         NSString* preferredLang = [languages objectAtIndex:0];

         NSLog(@"Current language is %@", preferredLang);

     

         Note that the iPhone does not support locales in the same way that Mac OS

         does (really only using locales for the Region Format settings) so if you

         try and get an array from standardUserDefaults for the key "AppleLocale",

         this will fail on the iPhone. */

    return returnValue;

    }


    //方法三

    + (NSString *)fixStringForDate:(NSDate *)date 

    {

        NSDateFormatter* dateFormatter = [[NSDateFormatteralloc]init];

        [dateFormatter setDateStyle:kCFDateFormatterFullStyle];

        [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];

        NSString *fixString = [dateFormatter stringFromDate:date]; 

        [dateFormatter release];

        return fixString;

    }


    方法四

        NSDateComponents *comps = [[NSDateComponentsalloc]init];

        [comps setYear:2010];

        [comps setMonth:8];

        [comps setDay:24];

        [comps setHour:17];

        [comps setMinute:5];

        [comps setTimeZone: [NSTimeZonetimeZoneWithAbbreviation:@"UTC"]];

        NSLog(@"%@", [NSTimeZonetimeZoneWithAbbreviation:@"UTC"]);

        

        NSCalendar *cal = [[NSCalendaralloc]initWithCalendarIdentifier:NSGregorianCalendar];

        NSDate *referenceTime = [cal dateFromComponents:comps];

        NSLog(@"%@", referenceTime);


    以下信息为转载

     

    GMT、UTC与24时区 等时间概念

     许多人都知道两地时间表简称为GMT或UTC,而世界时区表则通称为World Time,那么GMT与UTC的实质原意又是为何?世界时区又是怎么区分的?面盘上密密麻麻的英文单字代表着什么意义与作用呢?这些都是新手在接触两地时间表或世界时区表时,脑海中所不断浮现的种种疑问,以下将带您一探时区奥妙的究竟。

     

    世界时区及国际换日线示意图

     


    全球24个时区的划分 
          相较于两地时间表,可以显示世界各时区时间和地名的世界时区表(World Time),就显得精密与复杂多了,通常世界时区表的表盘上会标示着全球24个时区的城市名称,但究竟这24个时区是如何产生的?过去世界各地原本各自订定当地时间,但随着交通和电讯的发达,各地交流日益频繁,不同的地方时间,造成许多困扰,于是在西元1884年的国际会议上制定了全球性的标准时,明定以英国伦敦格林威治这个地方为零度经线的起点(亦称为本初子午线),并以地球由西向东每24小时自转一周360°,订定每隔经度15°,时差1小时。而每15°的经线则称为该时区的中央经线,将全球划分为24个时区,其中包含23个整时区及180°经线左右两侧的2个半时区。就全球的时间来看,东经的时间比西经要早,也就是如果格林威治时间是中午12时,则中央经线15°E的时区为下午1时,中央经线30°E时区的时间为下午2时;反之,中央经线15°W的时区时间为上午11时,中央经线30°W时区的时间为上午10时。以台湾为例,台湾位于东经121°,换算后与格林威治就有8小时的时差。如果两人同时从格林威治的0°各往东、西方前进,当他们在经线180°时,就会相差24小时,所以经线180°被定为国际换日线,由西向东通过此线时日期要减去一日,反之,若由东向西则要增加一日。

     

    格林威治标准时间GMT
          十七世纪,格林威治皇家天文台为了海上霸权的扩张计画而进行天体观测。1675年旧皇家观测所(Old Royal Observatory) 正式成立,到了1884年决定以通过格林威治的子午线作为划分地球东西两半球的经度零度。观测所门口墙上有一个标志24小时的时钟,显示当下的时间,对全球而言,这里所设定的时间是世界时间参考点,全球都以格林威治的时间作为标准来设定时间,这就是我们耳熟能详的「格林威治标准时间」(Greenwich Mean Time,简称G.M.T.)的由来,标示在手表上,则代表此表具有两地时间功能,也就是同时可以显示原居地和另一个国度的时间。

     

    世界协调时间UTC
          多数的两地时间表都以GMT来表示,但也有些两地时间表上看不到GMT字样,出现的反而是UTC这3个英文字母,究竟何谓UTC?事实上,UTC指的是Coordinated Universal Time- 世界协调时间(又称世界标准时间、世界统一时间),是经过平均太阳时(以格林威治时间GMT为准)、地轴运动修正后的新时标以及以「秒」为单位的国际原子时所综合精算而成的时间,计算过程相当严谨精密,因此若以「世界标准时间」的角度来说,UTC比GMT来得更加精准。其误差值必须保持在0.9秒以内,若大于0.9秒则由位于巴黎的国际地球自转事务中央局发布闰秒,使UTC与地球自转周期一致。所以基本上UTC的本质强调的是比GMT更为精确的世界时间标准,不过对于现行表款来说,GMT与UTC的功能与精确度是没有差别的。

     

    夏日节约时间DST
          所谓「夏日节约时间」Daylight Saving Time(简称D.S.T.),是指在夏天太阳升起的比较早时,将时钟拨快一小时,以提早日光的使用,在英国则称为夏令时间(Summer Time)。这个构想于1784年由美国班杰明·富兰克林提出来,1915年德国成为第一个正式实施夏令日光节约时间的国家,以削减灯光照明和耗电开支。自此以后,全球以欧洲和北美为主的约70个国家都引用这个做法。目前被划分成两个时区的印度也正在商讨是否全国该统一实行夏令日光节约时间。欧洲手机上也有很多GSM系统的基地台,除了会传送当地时间外也包括夏令日光节约时间,做为手机的时间标准,使用者可以自行决定要开启或关闭。值得注意的是,某些国家有实施「夏日节约时间」的制度,出国时别忘了跟随当地习惯在表上调整一下,这可是机械表没有的功能设计哦!

    展开全文
  • - (NSDate *)getNowDateFromatAnDate:(NSDate *)anyDate { //设置源日期时区 NSTimeZone* sourceTimeZone = [NSTimeZone timeZoneWithAbbreviation:...//或GMT //设置转换后的目标日期时区 NSTimeZone* destination
    - (NSDate *)getNowDateFromatAnDate:(NSDate *)anyDate
    {
        //设置源日期时区
        NSTimeZone* sourceTimeZone = [NSTimeZone timeZoneWithAbbreviation:@"UTC"];//或GMT
        //设置转换后的目标日期时区
        NSTimeZone* destinationTimeZone = [NSTimeZone localTimeZone];
        //得到源日期与世界标准时间的偏移量
        NSInteger sourceGMTOffset = [sourceTimeZone secondsFromGMTForDate:anyDate];
        //目标日期与本地时区的偏移量
        NSInteger destinationGMTOffset = [destinationTimeZone secondsFromGMTForDate:anyDate];
        //得到时间偏移量的差值
        NSTimeInterval interval = destinationGMTOffset - sourceGMTOffset;
        //转为现在时间
        NSDate* destinationDateNow = [[[NSDate alloc] initWithTimeInterval:interval sinceDate:anyDate] autorelease];
        return destinationDateNow;
    }


    例子演示:我的机器是北京时区东八区。

         //2013-08-03T12:53:51+0800     UTC时间格式下的北京时间,可以看到北京时间= UTC + 8小时。

        NSDateFormatter *dateFormatter = [[NSDateFormatteralloc] init];

        [dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssZ"];

        NSDate *localDate = [dateFormatter dateFromString:@"2013-08-03T04:56:52+0000"];      +0000 表示的是当前时间是个世界时间。

        [dateFormatter release];

        

        NSLog(@"now Time = %@",[selfgetNowDateFromatAnDate:localDate]);


    结果:

    2013-08-03 12:57:33.391 xxxx[2547:c07] now Time = 2013-08-03 12:56:52 +0000


     以上注意一点,在转出来后带的时间是原参数anydate的时区,因此切不可再用NSDateFormatter 转换。否则会多增加一个时区的时间值。应该使用如下来提取字符串


        NSString *str = [NSStringstringWithFormat:@"%@",[selfgetNowDateFromatAnDate:localDate]];

        NSLog(@"str = %@",str);


    注NSDate对象存放的日期始终是UTC的标准时间,可以根据这个时间进行其它时间的转换。因此上面算出来的时间中时区为 +0000,如果此时再转为字符串




    几个转换函数

    //NSString 2 NSDate

    - (NSDate *)stringToDate:(NSString *)strdate

    {

        NSDateFormatter *dateFormatter = [[NSDateFormatteralloc] init];

        [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];

        NSDate *retdate = [dateFormatter dateFromString:strdate];

        [dateFormatter release];

        return retdate;

    }


    //NSDate 2 NSString

    - (NSString *)dateToString:(NSDate *)date

    {

        NSDateFormatter *dateFormatter = [[NSDateFormatteralloc] init];

        [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];

        NSString *strDate = [dateFormatter stringFromDate:date];

        [dateFormatter release];

        return strDate;

    }

    //将本地日期字符串转为UTC日期字符串
    //本地日期格式:2013-08-03 12:53:51
    //可自行指定输入输出格式
    -(NSString *)getUTCFormateLocalDate:(NSString *)localDate
    {
        NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
        //输入格式
        [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
        
        NSDate *dateFormatted = [dateFormatter dateFromString:localDate];
        NSTimeZone *timeZone = [NSTimeZone timeZoneWithName:@"UTC"];
        [dateFormatter setTimeZone:timeZone];
        //输出格式
        [dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssZ"];
        NSString *dateString = [dateFormatter stringFromDate:dateFormatted];
        [dateFormatter release];
        return dateString;
    }
    
    //将UTC日期字符串转为本地时间字符串
    //输入的UTC日期格式2013-08-03T04:53:51+0000
    -(NSString *)getLocalDateFormateUTCDate:(NSString *)utcDate
    {
        NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
        //输入格式
        [dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssZ"];
        NSTimeZone *localTimeZone = [NSTimeZone localTimeZone];
        [dateFormatter setTimeZone:localTimeZone];
        
        NSDate *dateFormatted = [dateFormatter dateFromString:utcDate];
        //输出格式
        [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
        NSString *dateString = [dateFormatter stringFromDate:dateFormatted];
        [dateFormatter release];
        return dateString;
    }
    



    - (NSString *)getUTCFormatDate:(NSDate *)localDate

    {

        NSDateFormatter *dateFormatter = [[NSDateFormatteralloc] init];

        NSTimeZone *timeZone = [NSTimeZonetimeZoneWithName:@"UTC"];

        [dateFormatter setTimeZone:timeZone];

        [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss Z"];

        NSString *dateString = [dateFormatter stringFromDate:localDate];

        [dateFormatter release];

        return dateString;

    }


    - (NSDate *)getLocalFromUTC:(NSString *)utc

    {

        NSDateFormatter *dateFormatter = [[NSDateFormatteralloc] init];

        NSTimeZone *timeZone = [NSTimeZonelocalTimeZone];

        [dateFormatter setTimeZone:timeZone];

        [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss Z"];

        NSDate *ldate = [dateFormatter dateFromString:utc];

        [dateFormatter release];

        return ldate;

    }


    //以上注意字符串时的输入参数的格式,别外不要用%@来查看NSDate的值,因为本身存的就是UTC ,小心被误倒。将期转换出字符串来查看一下。


    展开全文
  • iOS开发中,经常会遇到各种各样的时间问题,8小时时差,时间戳,求时间间隔,农历等等。解决办法网上比比皆是,但大多零零散散,很多资料并没有说明其中问题。这里集中总结一下,以便于以后查阅和供大家参考。有我...

    在iOS开发中,经常会遇到各种各样的时间问题,8小时时差,时间戳,求时间间隔,农历等等。解决办法网上比比皆是,但大多零零散散,很多资料并没有说明其中问题。这里集中总结一下,以便于以后查阅和供大家参考。有我自己的理解,错漏之处请大家吐槽。

    NSDate的8小时问题

    • NSDate转字符串时间

    初始化一个NSDate时间[NSDate date],获取的是零时区的时间(格林尼治的时间: 年-月-日 时:分:秒: +时区),而北京时间是东八区时间,因为时区不同,所以打印的时间相差了8小时。此刻表示的时间是一样的。

    1
    2
    3
    4
    5
    6
    7
    NSDate *date = [NSDate date];
    NSLog(@"date时间 = %@", date);
     
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss Z"];
    NSString *dateStr = [formatter stringFromDate:date];
    NSLog(@"字符串时间 = %@", dateStr);

    打印结果:

    1
    2
    2016-12-07 10:44:24.470 timeTest[32743:2995134] date时间 = 2016-12-07 02:44:24 +0000
    2016-12-07 10:44:24.471 timeTest[32743:2995134] 字符串时间 = 2016-12-07 10:44:24 +0800

    打印结果前面的时间是北京时间:2016-12-07 10:44:24.470。而date打印出来的时间显示少了8小时,因为它表示的是零时区(+0000)时间02:44:24。此刻对应东八区的北京时间就是10:44:24。只是时区不同,表示的时间点是一样的。好比1公斤和2斤,重量是一样的。[NSDate date]获取的时间单位是零时区(+0000),我们所要的北京时间的单位是东八区(+0800)。

    系统会默认[NSDate date]获取的时间为零时区时间,而经过NSDateFormatter转化为字符串时间就是当前所在时区的准确时间,并没有8小时误差。

    • 转字符串时间的时区设定

    上文中NSDate时间转为字符串时间并没有设置NSDateFormatter的timeZone。不设置会默认使用当前所在的时区,与设置系统时区formatter.timeZone = [NSTimeZone systemTimeZone]的效果是一样的。

    也可以设置时区,获取指定时区的字符串时间

    1
    2
    3
    4
    5
    6
    NSDate *date = [NSDate date];
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    formatter.timeZone = [NSTimeZone timeZoneWithName:@"Asia/Shanghai"];//东八区时间
    NSString *dateStr = [formatter stringFromDate:date];
    NSLog(@"字符串时间 = %@", dateStr);

    这时获取的时间就是东八区时间,哪怕手机拿到零时区的格林尼治,获取的也是东八区的时间,因为这里指定时区了。也有如下时区指定:

    1
    2
    formatter.timeZone = [NSTimeZone timeZoneWithName:@"Asia/Tokyo"];//东九区时间
    formatter.timeZone = [NSTimeZone timeZoneWithName:@"GMT"];//零区时间

    通过下面方法可得到系统支持的时区对应的字符串常量:

    1
    2
    3
    4
    NSArray *zones = [NSTimeZone knownTimeZoneNames];
    for (NSString *zone in zones) {
       NSLog(@"时区名 = %@", zone);
    }

    QQ截图20161209172944.png

    时区对照表

    • 字符串时间转NSDate

    字符串时间转为NSDate时间也会有时区问题。也会遇到有所谓的8小时误差,其实就是时区不同。比如下面的例子:

    1
    2
    3
    4
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss Z"];
    NSDate *newDate = [formatter dateFromString:@"2016-12-07 14:06:24 +0800"];
    NSLog(@"newDate = %@", newDate);

    打印结果:

    1
    2016-12-07 14:12:17.468 timeTest[34279:3155380] newDate = 2016-12-07 06:06:24 +0000

    NSDateFormatter的指定格式是:@"yyyy-MM-dd HH:mm:ss Z"。这里面的Z指的是时区。要转化的字符串时间格式必须和这个格式匹配,上面给定的字符串时间是:@"2016-12-07 14:06:24 +0800",是一个东八区时间,转化为NSDate后是零区时间2016-12-07 06:06:24 +0000,字面显示上少了8小时,其实时间一样。

    其实如果上面给定的字符串时间为@"2016-12-07 14:06:24 +0000",转化出来的NSDate时间会完全一样,因为字符串时间为零时区时间,不存在时区误差。大家可以试一下。

    当不指定字符串时间的时区时,即没有后面的+0800,同时要把NSDateFormatter时间格式里的Z去掉,保证格式匹配。系统会认为字符串时间是系统所在时区的时间,转化为NSDate时间是零时区时间。

    同样,也可以使用formatter.timeZone = [NSTimeZone timeZoneWithName:@"GMT"];这种方式指定字符串时间的时区,和用Z对应+0000是一样的。

    • NSDate转当前时区的NSDate时间

    因为[NSDate date]得出的时间是零时区时间,当我们要获取当前所在时区的NSDate时间时,通常会用以下方法:

    1
    2
    3
    4
    5
    NSDate *date = [NSDate date];
    NSTimeZone *zone = [NSTimeZone systemTimeZone];
    NSInteger interval = [zone secondsFromGMTForDate:date];
    NSDate *localDate = [date  dateByAddingTimeInterval:interval];
    NSLog(@"localDate = %@",localDate);

    打印结果:

    1
    2016-12-07 14:49:03.777 timeTest[34519:3183548] localDate = 2016-12-07 14:49:03 +0000

    上面代码中zone是当前时区,interval是当前时区和零时区时间的差值,最后结果localDate是零时区时间date加上这个差值interval,得到当前时区的NSDate时间。更有甚者,在开发中直接加8*60*60或28800这样的值,因为相差8小时嘛。这样在东八区没问题,在其他时区时间就错了。

    其实这种做法是不科学的,因为得到的最终时间还是零时区时间,时间后面明显是+0000,在使用中一般不显示时区,所以认为当做当前时区的时间使用也未尝不可。此为大坑!

    坑1:这时如果转为字符串时间,又会增加8小时。因为做时间转换的时候,系统会认为这个NSDate是零时区,得到的字符串时间是东八区的。

    解决办法是:将错就错,字符串时间也设置为零时区的字符串时间。从深坑跌入更深的坑!

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    NSDate *date = [NSDate date];
    NSTimeZone *zone = [NSTimeZone systemTimeZone];
    NSInteger interval = [zone secondsFromGMTForDate:date];
    NSDate *localDate = [date dateByAddingTimeInterval:interval];
     
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    formatter.timeZone = [NSTimeZone timeZoneWithName:@"UTC"];
    NSString *dateStr = [formatter stringFromDate:localDate];
    NSLog(@"字符串时间 = %@", dateStr);

    这里的@"UTC"是指世界标准时间,也是现在用的时间标准,东八区比这个时间也是快8小时,这里填@"GMT"也是可以的。

    坑2:在与后台交互时,有时需要+0000时区,这时只能手动拼接字符串更改这个时区字段,改为正确的时区。

    所以,在开发中尽量不要这么做,当时间要求显示、存储或与后台交互的时候,使用字符串时间!不要使用转化的NSDate。

    时间换算,时间戳的概念

    • 当前时间转时间戳

    时间戳是指1970年1月1日0时0分0秒到当前时间的秒数。注意:这里的当前时间是指零时区的NSDate时间。

    1
    2
    3
    NSDate *date = [NSDate date];
    NSTimeInterval timeIn = [date timeIntervalSince1970];
    NSLog(@"时间戳 = %.0f", timeIn);

    打印结果:

    2016-12-07 15:41:04.000 timeTest[34994:3232390] 时间戳 = 1481096464

    • 时间戳转当前时间

    1
    2
    3
    4
    5
    6
    7
    NSDate *date = [NSDate date];
    NSTimeInterval timeIn = [date timeIntervalSince1970];
    NSDate *newDate = [NSDate dateWithTimeIntervalSince1970:timeIn];
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss Z"];
    NSString *newTime = [dateFormatter stringFromDate:newDate];
    NSLog(@"初始化时间 = %@,时间戳=%.0f,时间戳转为NSDate时间 = %@,转为字符串时间 = %@", date, timeIn, newDate, newTime);

    打印结果:

    1
    2016-12-07 16:11:56.146 timeTest[35186:3253589] 初始化时间 = 2016-12-07 08:11:56 +0000,时间戳=1481098316,时间戳转为NSDate时间 = 2016-12-07 08:11:56 +0000,转为字符串时间 = 2016-12-07 16:11:56 +0800

    注意时间戳使用的NSDate时间是当前零时区的时间!当前零时区时间!当前零时区时间!重要的事情说三遍!不要进行NSDate转当前时区的NSDate时间,再转时间戳。下面是验证:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    NSDate *date = [NSDate date];
    NSLog(@"系统零时区NSDate时间 = %@", date);    
    NSTimeInterval timeIn = [date timeIntervalSince1970];
    NSLog(@"系统零时区NSDate时间转化为时间戳 = %.0f", timeIn);
    NSTimeZone *zone = [NSTimeZone systemTimeZone];
    NSInteger interval = [zone secondsFromGMTForDate:date];
    NSDate *localDate = [date  dateByAddingTimeInterval:interval];
    NSLog(@"转化为本地NSDate时间 = %@", localDate);
    NSTimeInterval timeIn2 = [localDate timeIntervalSince1970];
    NSLog(@"本地NSDate时间转化为时间戳 = %.0f", timeIn2);
    NSDate *detaildate = [NSDate dateWithTimeIntervalSince1970:timeIn];
    NSDate *detaildate2 = [NSDate dateWithTimeIntervalSince1970:timeIn2];
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss Z"];
    NSString *newTime = [dateFormatter stringFromDate:detaildate];
    NSString *newTime2 = [dateFormatter stringFromDate:detaildate2];
    NSLog(@"最终转为字符串时间1 = %@, 时间2 = %@", newTime, newTime2);

    打印结果:

    1
    2
    3
    4
    5
    2016-12-07 16:13:57.834 timeTest[35211:3255842] 系统零时区NSDate时间 = 2016-12-07 08:13:57 +0000
    2016-12-07 16:13:57.834 timeTest[35211:3255842] 系统零时区NSDate时间转化为时间戳 = 1481098438
    2016-12-07 16:13:57.835 timeTest[35211:3255842] 转化为本地NSDate时间 = 2016-12-07 16:13:57 +0000
    2016-12-07 16:13:57.835 timeTest[35211:3255842] 本地NSDate时间转化为时间戳 = 1481127238
    2016-12-07 16:13:57.836 timeTest[35211:3255842] 最终转为字符串时间1 = 2016-12-07 16:13:57 +0800, 时间2 = 2016-12-08 00:13:57 +0800

    问题解释详见上文的NSDate转当前时区的NSDate时间。

    时间操作与比较

    • 时间初始化和比较方法

    几个时间初始化方法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    //初始化当前时间,返回零时区时间
    NSDate *date = [NSDate date];
    //以当前时间为准,正数超前指定秒数,负数延后指定秒数
    NSDate *laterDate = [NSDate dateWithTimeIntervalSinceNow:60];
    //以2001-01-01 00:00:00 +0000为基准,正数超前指定秒数,负数延后指定秒数
    NSDate *newDate = [NSDate dateWithTimeIntervalSinceReferenceDate:60];
    //以1970-01-01 00:00:00 +0000为基准,正数超前指定秒数,负数延后指定秒数
    NSDate *newDate1 = [NSDate dateWithTimeIntervalSince1970:60];
    //实例方法,以指定时间为基准,正数超前指定秒数,负数延后指定秒数
    NSDate *newDate2 = [date dateByAddingTimeInterval:60];
    //很久以后的某一天
    NSDate *newDate3 = [NSDate distantFuture];
    //很久以前的某一天
    NSDate *newDate4 = [NSDate distantPast];

    几个时间比较方法:

    1
    2
    3
    4
    5
    6
    7
    8
    //比较两个时间是否相等
    - (BOOL)isEqualToDate:(NSDate *)otherDate;
    //两个时间比较,返回较早时间
    - (NSDate *)earlierDate:(NSDate *)anotherDate;
    //两个时间比较,返回较晚时间
    - (NSDate *)laterDate:(NSDate *)anotherDate;
    //两个时间比较,返回枚举类型
    - (NSComparisonResult)compare:(NSDate *)other;

    几个计算时间间隔的方法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    //返回实例时间与refDate时间间隔秒数
    - (NSTimeInterval)timeIntervalSinceDate:(NSDate *)refDate;
    //返回实例时间与当前时间间隔秒数
    - (NSTimeInterval)timeIntervalSinceNow;
    //返回实例时间的时间戳
    - (NSTimeInterval)timeIntervalSince1970;
    //返回实例时间和2001-01-01 00:00:00 +0000的间隔秒数
    - (NSTimeInterval)timeIntervalSinceReferenceDate;
    //返回当前时间和2001-01-01 00:00:00 +0000的间隔秒数
    + (NSTimeInterval)timeIntervalSinceReferenceDate;
    • 获取年月日时分秒周时区

    OC里的时间坑太多,根本没办法像其他语言那样直接time.year就能获取年份。要想获取NSDate的年月日需要使用日历对象NSCalendar。

    1
    2
    3
    4
    5
    NSDate *date = [NSDate date];
    NSCalendar *cal = [NSCalendar currentCalendar];
    NSDateComponents *dateComps = [cal components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay|NSCalendarUnitHour|NSCalendarUnitMinute|NSCalendarUnitSecond|NSCalendarUnitWeekday|NSCalendarUnitWeekOfMonth|NSCalendarUnitWeekOfYear|NSCalendarUnitTimeZone fromDate:date];
    NSLog(@"时间 = %@", date);
    NSLog(@"年=%ld,月=%ld,日=%ld,时=%ld,分=%ld,秒=%ld,周=%ld,本月第%ld周,本年第%ld周,时区=%@", dateComps.year, dateComps.month, dateComps.day, dateComps.hour, dateComps.minute, dateComps.second, dateComps.weekday, dateComps.weekOfMonth, dateComps.weekOfYear, dateComps.timeZone.name);

    打印结果:

    1
    2
    2016-12-07 17:20:41.639 timeTest[35734:3311752] 时间 = 2016-12-07 09:20:41 +0000
    2016-12-07 17:20:41.640 timeTest[35734:3311752] 年=2016,月=12,日=7,时=17,分=20,秒=41,周=4,本月第2周,本年第50周,时区=Asia/Shanghai

    NSDateComponents创建方法中添加的枚举NSCalendarUnit,是后面要获取的年月日时分秒必须对应添加的。比如要获取年dateComps.year,就需要添加枚举NSCalendarUnitYear。

    可以看到,[NSDate date]时间可以使用NSCalendar直接获取当前时区的时分秒,打印的时和时区即可看出。这是[NSCalendar currentCalendar]日历对象初始化的原因,也可以用[[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]指定Identifier的方式初始化阳历日历。可以试试指定Identifier为NSCalendarIdentifierChinese,打印的是中国农历。

    dateComps.weekOfMonth是今天属于本月的第几周。

    dateComps.weekOfYear是今天属于本年的第几周。

    dateComps.weekday是星期,这个和日常使用有些不同。上述程序打印的是周=4,但2016-12-07是周三。这里weekday的对应关系是:周日-1,周一-2,周二-3,周三-4,周四-5,周五-6,周六-7。毕竟国外惯例周日是每周的第一天。

    农历

    获取农历的工具方法,可根据需求添加农历节日和二十四节气

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    + (NSString *)LunarForSolarYear:(int)wCurYear Month:(int)wCurMonth Day:(int)wCurDay
    {
        //农历日期名
        NSArray *cDayName =  [NSArray arrayWithObjects:@"*",@"初一",@"初二",@"初三",@"初四",@"初五",@"初六",@"初七",@"初八",@"初九",@"初十",@"十一",@"十二",@"十三",@"十四",@"十五",@"十六",@"十七",@"十八",@"十九",@"二十",@"廿一",@"廿二",@"廿三",@"廿四",@"廿五",@"廿六",@"廿七",@"廿八",@"廿九",@"三十",nil];
        //农历月份名
        NSArray *cMonName =  [NSArray arrayWithObjects:@"*",@"正月",@"二月",@"三月",@"四月",@"五月",@"六月",@"七月",@"八月",@"九月",@"十月",@"冬月",@"腊月",nil];
        //公历每月前面的天数
        const int wMonthAdd[12] = {0,31,59,90,120,151,181,212,243,273,304,334};
        //农历数据
        const int wNongliData[100] = {2635,333387,1701,1748,267701,694,2391,133423,1175,396438
            ,3402,3749,331177,1453,694,201326,2350,465197,3221,3402
            ,400202,2901,1386,267611,605,2349,137515,2709,464533,1738
            ,2901,330421,1242,2651,199255,1323,529706,3733,1706,398762
            ,2741,1206,267438,2647,1318,204070,3477,461653,1386,2413
            ,330077,1197,2637,268877,3365,531109,2900,2922,398042,2395
            ,1179,267415,2635,661067,1701,1748,398772,2742,2391,330031
            ,1175,1611,200010,3749,527717,1452,2742,332397,2350,3222
            ,268949,3402,3493,133973,1386,464219,605,2349,334123,2709
            ,2890,267946,2773,592565,1210,2651,395863,1323,2707,265877};
        static int nTheDate,nIsEnd,m,k,n,i,nBit;
        //计算到初始时间1921年2月8日的天数:1921-2-8(正月初一)
        nTheDate = (wCurYear - 1921) * 365 + (wCurYear - 1921) / 4 + wCurDay + wMonthAdd[wCurMonth - 1] - 38;
        if((!(wCurYear % 4)) && (wCurMonth > 2))
            nTheDate = nTheDate + 1;
        //计算农历天干、地支、月、日
        nIsEnd = 0;
        m = 0;
        while(nIsEnd != 1) {
            if(wNongliData[m] < 4095)
                k = 11;
            else
                k = 12;
            n = k;
            while(n>=0) {
                //获取wNongliData(m)的第n个二进制位的值

    55.png

    展开全文
  • iOS获取当前时区

    2015-09-10 10:56:00
    //ios 貌似没有提供直接获取时区的方法,反正我是没看到 //所以我们只能获取当前所在时区相对0时区的偏移秒数 //即使用secondsFromGMTForDate方法获取偏移秒数  NSTimeZone* destinationTimeZone = ...

    //在程序中,有时候需要获得当前时区,比如北京是在东8区,

    //ios 貌似没有提供直接获取时区的方法,反正我是没看到可怜

    //所以我们只能获取当前所在时区相对0时区的偏移秒数

    //即使用secondsFromGMTForDate方法获取偏移秒数

        NSTimeZone* destinationTimeZone = [NSTimeZone localTimeZone] ;///获取当前时区信息

        NSInteger sourceGMTOffset = [destinationTimeZone secondsFromGMTForDate:[NSDate date]];///获取偏移秒数

        NSLog(@"offset = %zd",sourceGMTOffset/3600);///除以3600即可获取小时数,即为当前时区

    展开全文
  • iOS 时区获取问题

    2019-09-30 08:07:44
    时区缩写 UTC, CST, GMT, CEST 以及转换 UTC是协调世界时(Universal Time Coordinated)英文缩写,是由国际无线电咨询委员会规定和推荐,并由国际时间局(BIH)负责保持的以秒为基础的时间标度。UTC相当于本初子午...

      

    时区缩写 UTC, CST, GMT, CEST 以及转换

    UTC是协调世界时(Universal Time Coordinated)英文缩写,是由国际无线电咨询委员会规定和推荐,并由国际时间局(BIH)负责保持的以秒为基础的时间标度。UTC相当于本初子午线(即经度0度)上的平均太阳时,过去曾用格林威治平均时(GMT)来表示.北京时间比UTC时间早8小时,以1999年1月1日0000UTC为例,UTC时间是零点,北京时间为1999年1月1日早上8点整。

     

    GMT(Greenwich Mean Time)是格林尼治平时: 
    由于地球轨道并非圆形,其运行速度又随着地球与太阳的距离改变而出现变化,因此视太阳时欠缺均匀性。视太阳日的长度同时亦受到地球自转轴相对轨道面的倾斜度所影响。为着要纠正上述的不均匀性,天文学家计算地球非圆形轨迹与极轴倾斜对视太阳时的效应。平太阳时就是指经修订后的视太阳时。在格林尼治子午线上的平太阳时称为世界时(UT0),又叫格林尼治平时(GMT)。 为了确保协调世界时与世界时(UT1)相差不会超过0.9秒,有需要时便会在协调世界时内加上正或负闰秒。因此协调世界时与国际原子时(TAI)之间会出现若干整数秒的差别。位于巴黎的国际地球自转事务中央局(IERS)负责决定何时加入闰秒。

    也就是说,UTC 基本上等于GMT

     

    CET

    (英語:Central European Time,CET)欧洲中部时间是比世界标准时间(UTC)早一个小时的时区名称之一。它被大部分欧洲国家和部分北非国家采用。冬季时间为UTC+1,夏季欧洲夏令时为UTC+2

     

    CEST

    欧洲中部夏令时间(Central European Summer Time,简称CEST)比世界标准时间(UTC)早两个小时的时区名称之一。它被大部分欧洲国家和部分北非国家在夏天采用(UTC+2),冬季这些国家使用欧洲中部时间(UTC+1)

    时区在线转换工具网站  http://www.timebie.com/timezone/centraleuropeansummerbeijing.php 

     

     

    CST

    CST却同时可以代表如下 4 个不同的时区: 

    Central Standard Time (USA) UTC-6:00 

    Central Standard Time (Australia) UTC+9:30 
    China Standard Time UTC+8:00 
    Cuba Standard Time UTC-4:00 
    可见,CST可以同时表示美国,澳大利亚,中国,古巴四个国家的标准时间。 也就是说,这个需要根据使用的场景来确定使用的是哪个时区。

    ////////////////////////////////////////////////////////////////////

    ////////////////////////////////////////////////////////////////////

    1. 标准的获取时区的正确方法

      [NSTimeZone resetSystemTimeZone]; // 重置手机系统的时区

        NSInteger offset = [NSTimeZone localTimeZone].secondsFromGMT;

        offset = offset/3600;

        NSString *tzStr = [NSString stringWithFormat:@"%ld", (long)offset];

     获取的时区:(Asia/Shanghai (GMT+8) offset 28800)

    2.  截取 GMT 方法

        //获取当地的时区

        NSString *tzStr;

        NSTimeZone *localTimeZone = [NSTimeZone localTimeZone];

        NSArray *zoneArray = [[NSString stringWithFormat:@"%@", localTimeZone] componentsSeparatedByString:@"GMT"];

        NSString *tempTZ = [NSString stringWithFormat:@"%@", zoneArray.lastObject];

        // eg: +8 去掉"+", -8 传入全部, +0 / -0

        // - 1 ~ 12, + 1 ~ +12, 0

        if([tempTZ hasPrefix:@"+"]) {

            tzStr = [NSString stringWithFormat:@"%c", [tempTZ characterAtIndex:1]];

        }else  if([tempTZ hasPrefix:@"-"]){

            tzStr = [NSString stringWithFormat:@"%@", [tempTZ substringToIndex:2]];

        }else if([tempTZ hasPrefix:@"0"]) {

            tzStr = [NSString stringWithFormat:@"%@", [tempTZ substringToIndex:1]];

        }

    获取的时区: Europe/Berlin (CEST) offset 7200 (Daylight)

    鉴于有些时区非携带 GMT 格式吗故 "方法二 " 不可行, 采用 "方法一".

    根据距离 0 时区偏差的秒数算出时区. 

    转载于:https://www.cnblogs.com/lurenq/p/7109676.html

    展开全文
  • 前言 @interface NSTimeZone : NSObject &lt;NSCopying, ...NSTimeZone 表示时区信息。 1、NSTimeZone 时区的创建 NSTimeZone *zone1 = [[NSTimeZone alloc] init]; // 根据时区名称创建 ...
  • 某日发现 DateTools 的 weekday 方法在不同 iOS 上计算出的结果不一样的问题。具体表现为:在 iOS 10 上计算出的结果比 iOS 12 上的结果少一天。比如同样是 2019-09-23,iOS 10 上计算结果为 1,而 iOS 12 上计算...
  • NSDate * originalDate = [NSDate new]; NSTimeZone* sourceTimeZone = [NSTimeZone ...timeZoneWithAbbreviation:@"GMT"]; NSTimeZone* destinationTimeZone = [NSTimeZone localTimeZone]; NSInteger sourceGMT
  • 今天讲讲在签名的过程中我们需要向服务器传送一个Date值,格式要求是格林威治时间,也就是GMT时间! 格式要求是 22 Oct 2015 10:20:35 GMT 而我通过[NSDate Date]获取到的格式是2015-10-22 10:20:35 所以就上网...
  • 为什么80%的码农都做不了架构师?>>> ...
  • // // Common.h // TesTimeZone // // Created by li on 2018/1/13. // Copyright © 2018年 li. All rights reserved. //#import <Foundation/Foundation.h>@interface Common : NSObject+ (NSString *)dateToStri
  • ios设置时区转换

    2011-09-19 23:20:18
    有的时候为了在系统中统一时间,需要在服务器和客户端统一交换的时间时区,比如都用GMT。 iPhone上转换的代码如下: NSDate *now = [NSDate date]; NSLog(@”%@”,[now description]); NSTimeZone *...
  • ios 时间的比较&&获得系统本地时间指定时区 - (BOOL)isEqualToDate:(NSDate *)otherDate;   与otherDate比较,相同返回YES   - (NSDate *)earlierDate:(NSDate *)anotherDate;  与anotherDate比较,返回较...
  • //根据文件结束的时间转时间戳算出开始的时间。 NSDate *dates = _gatherRecord.gatherTime; //得到时间 NSTimeInterval ti = [dates timeIntervalSince1970]; //转时间戳 NSTimeInterval ends = ti - [_...
  • NSDate存储的是世界标准时(UTC),输出时需要根据时区转换为本地时间   Dates  NSDate类提供了创建date,比较date以及计算两个date之间间隔的功能。Date对象是不可改变的。  如果你要创建date对象并...
  • iOS开发过程中,服务端为了兼容国际化,返回给客户端的时间是带有时区的字符串格式(例如:“2020-02-25T06:02:44.000+0000”),我们需要把它转化成本地时区的时间(例如:2020-02-25 14:02:44)。 /** 将UTC日期...
  • GMT 0:00 格林威治标准时间;... CCD +08:00 中国标准时间 [来自百度百科iOS中的时区表示方法:GMT+0800 GMT-0800。(+:东区 -:西区 08:小时数 00:分钟数)。 GMT+0830就是指比GMT早8小时外加30
  • 在项目中碰到了这个问题,当我从后台获取到时间的字符串后,我需要在前段处理“两个时间的时间差”的计算事件。当我把两段时间转换为NSDate时发现,本该是2016-04-12 14:57:58 +0000的一段时间,在转换后变成了2016-...
1 2 3 4 5 ... 20
收藏数 1,088
精华内容 435
热门标签
关键字:

11 gmt ios 时区