iOS内部时钟

1.什么是内部时钟

     在我们做iOS开发的过程中,我们经常要与时间打交道,[NSDate date]是我们常用的取时间的一种方式,但是[NSDate date] 这种方式只能取系统的当前时间。也就是说:当前我们手机的时间是什么时间,取出来的值,就是多少。

如果用户把系统的时间改了呢?那么[NSDate date]取出来的值,还是我们想要的吗???在一些应用的开发中,我们在没有网络的状态下,不能取网络时间,依靠系统时间,是可以篡改的。所以这个时候,我们要自己要在程序的内部定制一个自己的内部时钟。

2.实现内部时钟的思路

    1.要有一个时间作为基本的参照点(一般应用都会与服务器打交道,所以发请求给服务器,取服务器的时间是比较合适的)

2.要有一个标记点(一般取待机时长)

3.在每次进入程序的时候,或者登录的时候,取服务器的时间存起来,然后再取当前的待机时间存起来,每次要获取当前时间的时候,再取待机时长跟之前的存储的待机时长比较,获得差值。将存储的服务器时间加上差值,就获得想要的当前时间。

3.具体实现步骤

0.用到的宏:

//开机时间
#define SWStartTime  @"startTime"

//服务器时间
#define SWServerTime @"serverTime"

//登录时的待机时长
#define SWSinceNow @"sinceNow"

1.获取待机时长

/**
 *  待机时间(从系统启动的那一刻开始获取的时间间隔)
 */
+ (time_t)uptime
{
    struct timeval boottime;

    int mib[2] = {CTL_KERN, KERN_BOOTTIME};

    size_t size = sizeof(boottime);

    time_t now;

    time_t uptime = -1;

    (void)time(&now);

    if (sysctl(mib, 2, &boottime, &size, NULL, 0) != -1 && boottime.tv_sec != 0)

    {

        uptime = now - boottime.tv_sec;

    }

    return uptime;

}

2.存储服务器时间及待机时长

/**
 *  存储服务器时间及待机时长
 *
 *  @param serverTime 服务器时间
 */
+ (void)firstTimeWithLogin:(NSString *)serverTime
{
        NSTimeInterval timer = (NSTimeInterval)[self uptime];
        NSString *sinceNow = [NSString stringWithFormat:@"%f",timer];

        NSUserDefaults *UserDefaults = [NSUserDefaults standardUserDefaults];
        //存储登录时获取的服务器时间
        [UserDefaults setObject:serverTime forKey:SWServerTime];
        //存储登录时获取的待机时长
        [UserDefaults setObject:sinceNow forKey:SWSinceNow];

}

3.获得当前的时间(以服务器时间为基准)

+ (NSDate *)dateOfNow
{
    NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
    [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];

    NSUserDefaults *UserDefaults = [NSUserDefaults standardUserDefaults];
    //取出登录时获取的服务器时间
    NSString * serverText = [UserDefaults objectForKey:SWServerTime];
    NSDate *FirstServer = [formatter dateFromString:serverText];

    NSString *firstText = [UserDefaults objectForKey:SWSinceNow];
    CGFloat first = firstText.floatValue;
    NSTimeInterval timer = (NSTimeInterval)[self uptime];

    CGFloat second = (CGFloat)timer;

    //差值
    CGFloat finaly = second - first;
    NSTimeInterval interval = (NSTimeInterval)finaly;

    //最后的时间
    NSDate *finalyDate = [FirstServer dateByAddingTimeInterval:interval];
    return finalyDate;
}

4.深度探讨

  • 为什么获取待机时间不用SystemUptime这种方法?

答案 :SystemUptime这种获取待机时间的方式在我们设备深度睡眠的时候,获取的值会有误差,而上面我所用的方法不会。亲测!!!

  •  如果我要获取手机的开机时间,怎么办?

答案 :

/**
 *  获得开机时间
 */
+ (NSString *)getUpTime{
    NSString * proc_useTiem;
    int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, 0};
    size_t miblen = 4;
    size_t size;
    //返回0,成功;返回-1,失败
    int st = sysctl(mib, miblen, NULL, &size, NULL, 0);

    struct kinfo_proc * process = NULL;
    struct kinfo_proc * newprocess = NULL;
    do
    {
        size += size / 10;
        newprocess = realloc(process, size);
        if (!newprocess)
        {
            if (process)
            {
                free(process);
                process = NULL;
            }
            return nil;
        }
        process = newprocess;
        st = sysctl(mib, miblen, process, &size, NULL, 0);

    }
    while (st == -1 && errno == ENOMEM);
    if (st == 0)
    {
        if (size % sizeof(struct kinfo_proc) == 0)
        {
            int nprocess = size / sizeof(struct kinfo_proc);
            if (nprocess)
            {
                for (int i = nprocess - 1; i >= 0; i--)
                {
                    @autoreleasepool{

                        //进程的时间
                        double t = process->kp_proc.p_un.__p_starttime.tv_sec;
                        double s = process->kp_proc.p_un.__p_starttime.tv_usec;
                        double finaly = t + s *0.000001;                        //将其转为具体时间
                        proc_useTiem = [self timeWithBoot:finaly];
                    }

                }
                free(process);
                process = NULL;
                return proc_useTiem;

            }
        }
    }
    return nil;
}
/**
 *  转为具体时间
 */
+ (NSString *)timeWithBoot:(double)interval
{
    NSDateFormatter *format = [[NSDateFormatter alloc]init];
    format.timeZone = [NSTimeZone timeZoneWithName:@"shanghai"];
    [format setDateStyle:NSDateFormatterMediumStyle];
    [format setTimeStyle:NSDateFormatterShortStyle];
    //注意先后顺序
    [format setDateFormat:@"yyyy-MM-dd HH:mm:ss.SSS"];
    NSDate *date = [NSDate dateWithTimeIntervalSince1970:interval];
    NSString *bootTime = [format stringFromDate:date];
    return bootTime;
}

PS:如有问题请留言或关注我的新浪微博http://weibo.com/3216725234私信我!!!!

 

时间: 2024-10-12 19:10:34

iOS内部时钟的相关文章

腾讯ios内部视频,什么垃圾视频

前几天朋友在网上花钱买了个,腾讯ios内部视频,我也跟着下载了, 看着这列表,我感觉没什么东西,一看就是基础的东西,完全没有实战的内容,就像培训机构骗学生的东西啊,讲些毛理论,结果一到实战了,问个ScrollView布局都不会,还装两三年,什么傻逼,还想混日子,面试的时候,全是一些所谓的两三年. 结果所谓的腾讯内部视频,操,什么垃圾玩意啊 八点钟学院,以为技术好屌,讲些垃圾基础的东西,还没讲几分钟就打自己的广告,收费,操

STM32内部时钟设置-寄存器版

STM32寄存器版本--内部时钟设置 同时要记得把延时初始化函数设置好 1 //系统时钟初始化函数 2 //pll:选择的倍频数,从2开始,最大值为16 3 //pll:选择的倍频数,这里使用内部时钟,PLL为4就是4分频 4 void Stm32_Clock_Init(u8 PLL) 5 { 6 unsigned char temp=0; 7 MYRCC_DeInit(); //复位并配置向量表 8 // RCC->CR|=0x00010000; //外部高速时钟使能HSEON 9 RCC->

iOS内部跳转问题

//打开地图       NSString*addressText = @" "; //@"1Infinite Loop, Cupertino, CA 95014";        addressText =[addressText stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding];        NSString*urlText = [NSString stringWithFormat

iOS平台内存使用原则

2 iOS平台内存使用原则 2.1 对象的所有权与销毁 2.1.1 谁创建,谁释放: 如果是以alloc,new或者copy,mutableCopy创建的对象,则必须调用release或者autorelease方法释放内存: 如果没有释放,则导致内存泄漏! 2.1.2 谁retain,谁释放: 如果对一个对象发送 retain消息,其引用计数会+1,则使用完必须发送release或者autorelease方法释放内存或恢复引用计数: 如果没有释放,则导致内存泄漏! 2.1.3 没创建且没reta

数字设计中的时钟与约束

最近做完了synopsys的DC workshop,涉及到时钟的建模/约束,这里就来聊聊数字中的时钟(与建模)吧.主要内容如下所示: ·同步电路与异步电路: ·时钟/时钟树的属性:偏移(skew)与时钟的抖动(jitter).延时(latency).转换(transition)时间: ·内部时钟: ·多路复用时钟: ·门控时钟: ·行波时钟: ·双沿时钟: ·Design Compiler中的时钟约束. 1.同步电路与异步电路 首先来谈谈同步电路与异步电路.那么首先就要知道什么是同步电路.什么是

STM32中的几个时钟SysTick、FCLK、SYSCLK、HCLK

用时钟源来产生时钟! 在STM32中,有五个时钟源,为HSI.HSE.LSI.LSE.PLL.①.HSI是高速内部时钟,RC振荡器,频率为8MHz.②.HSE是高速外部时钟,可接石英/陶瓷谐振器,或者接外部时钟源,频率范围为4MHz~16MHz.③.LSI是低速内部时钟,RC振荡器,频率为40kHz.④.LSE是低速外部时钟,接频率为32.768kHz的石英晶体.⑤.PLL为锁相环倍频输出,其时钟输入源可选择为HSI/2.HSE或者HSE/2.倍频可选择为2~16倍,但是其输出频率最大不得超过7

[转] STM32各种时钟的区别

[原创]:http://m.oschina.net/blog/129357 我在原创的基础又从另一位博主处引用了一些内容. 时钟系统是处理器的核心,所以在学习STM32所有外设之前,认真学习时钟系统是必要的,有助于深入理解STM32.     下面是从网上找的一个STM32时钟框图,比<STM32中文参考手册>里面的是中途看起来清晰一些:         重要的时钟:   PLLCLK,SYSCLK,HCKL,PCLK1,PCLK2 之间的关系要弄清楚; 1.HSI:高速内部时钟信号 stm3

认识STM32的系统时钟

STM32共有五个时钟源,分别是: HSI是高速内部时钟.RC振荡器,频率为8MHz: HSE是高速外部时钟,频率范围为4~6MHz; (可接石英/陶瓷谐振器或者接外部时钟源) LSI是低速内部时钟,频率40kHz; (独立看门狗时钟源.可作RTC时钟源) LSE是低速外部时钟,频率为32.768kHz石英晶体; (主要RTC时钟源) PLL是锁相环倍频输出,频率可选择为HSI/2.HSE或者HSE/2.倍频可选择2~16倍,但其输出频率最大不超过72MHz: 此处重点介绍系统时钟,一般其他所有

【转】FPGA中的建立时间和保持时间的关系以及影响时钟的因素

时钟是整个电路最重要.最特殊的信号,系统内大部分器件的动作都是在时钟的跳变沿上进行, 这就要求时钟信号时延差要非常小, 否则就可能造成时序逻辑状态出错:因而明确FPGA设计中决定系统时钟的因素,尽量较小时钟的延时对保证设计的稳定性有非常重要的意义. 1.1 建立时间与保持时间 建立时间(Tsu:set up time)是指在时钟沿到来之前数据从不稳定到稳定所需的时间,如果建立的时间不满足要求那么数据将不能在这个时钟上升沿被稳定的打入触发器:保持时间(Th:hold time)是指数据稳定后保持的