zoukankan      html  css  js  c++  java
  • 【转】cocos2d-x获取系统时间——2013-08-25 10

    欢迎转载,本帖地址:http://blog.csdn.net/jinjian2009/article/details/9449585

    之前使用过cocos2d-x获取系统时间,毫秒级的

    long getCurrentTime()     
    {      
    struct timeval tv;      
        gettimeofday(&tv,NULL);      
    return tv.tv_sec * 1000 + tv.tv_usec / 1000;      
    }  

    或者这样写

    long getCurrentTime()    
    {      
    struct cc_timeval tv;      
        CCTime::gettimeofdayCocos2d(&tv, NULL);   
    return tv.tv_sec * 1000 + tv.tv_usec / 1000; 
    //tv_sec:秒   tv_usec:微妙  
    } 

    上面两种实现应该都是没有问题的~~~之前获取时间的主要作用是给随机函数做种子,或者计算FPS,或者作为自己的定时器使用~这些都没有问题

    后来有项目需要获取年月日等时间,这些怎么来计算呢?

    void GetTime()  
    {  
    struct cc_timeval now;   
        CCTime::gettimeofdayCocos2d(&now, NULL);   
    
    struct tm *tm;  
    time_t timep = now.tv_sec;  
    tm = localtime(&timep);  
    int year = tm->tm_year + 1900;  
    int month = tm->tm_mon + 1;  
    int day = tm->tm_mday;  
    int hour=tm->tm_hour;  
    int min=tm->tm_min;  
    int second=tm->tm_sec;  
    }

    这样可以获取年月日时分秒

    但是本人在win32上获取的年月日是1970-1-1,时分秒也是不对的,本人使用的是cocos2d-x2.1.3版本

    debug发现CCTime::gettimeofdayCocos2d(&now, NULL); 该方法获取的now.tv_sec数据很短,转换下也就几个小时,

    找到CCTime::gettimeofdayCocos2d方法的实现,发现也是调用了gettimeofday这个方法

    继续找,发现win32平台下的该方法的实现

    int gettimeofday(struct timeval * val, struct timezone *)  
    {  
    if (val)  
        {  
            LARGE_INTEGER liTime, liFreq;  
            QueryPerformanceFrequency( &liFreq );  
            QueryPerformanceCounter( &liTime );  
            val->tv_sec     = (long)( liTime.QuadPart / liFreq.QuadPart );  
            val->tv_usec    = (long)( liTime.QuadPart * 1000000.0 / liFreq.QuadPart - val->tv_sec * 1000000.0 );  
        }  
    return 0;  
    }  

    网上搜了下,原来是cocos2d-x官方论坛里有人修改过该方法,帖子地址:http://www.cocos2d-x.org/boards/6/topics/8191

    代码如下

    @@ -30,20 +30,11 @@ int CC_DLL gettimeofday(struct timeval * val, struct timezone *)
     {
         if (val)
         {
    -        SYSTEMTIME wtm;
    -        GetLocalTime(&wtm);
    -
    -        struct tm tTm;
    -        tTm.tm_year     = wtm.wYear - 1900;
    -        tTm.tm_mon      = wtm.wMonth - 1;
    -        tTm.tm_mday     = wtm.wDay;
    -        tTm.tm_hour     = wtm.wHour;
    -        tTm.tm_min      = wtm.wMinute;
    -        tTm.tm_sec      = wtm.wSecond;
    -        tTm.tm_isdst    = -1;
    -
    -        val->tv_sec     = (long)mktime(&tTm);       // time_t is 64-bit on win32
    -        val->tv_usec    = wtm.wMilliseconds * 1000;
    +        LARGE_INTEGER liTime, liFreq;
    +        QueryPerformanceFrequency( &liFreq );
    +        QueryPerformanceCounter( &liTime );
    +        val->tv_sec     = (long)( liTime.QuadPart / liFreq.QuadPart );
    +        val->tv_usec    = (long)( liTime.QuadPart * 1000000.0 / liFreq.QuadPart - val->tv_sec * 1000000.0 );
         }
         return 0;
     }

    可以发现以前该方法的实现是使用了GetLocalTime来获取本地时间,然后进行计算的,如果按照这样的实现方法,本人之前写的GetTime()方法应该能获取到正确的年月日时分秒,但是上述代码为了使获取的时间更为精确,使用了

    QueryPerformanceFrequency( &liFreq );
    QueryPerformanceCounter( &liTime );

    两个方法,QueryPerformanceCounter( &liTime );这个方法,是计算CPU运行到现在的时间,所以很明显本人获取的时间是开机到现在的时间,本人计算了下,还真是差不多~

    所以可以理解,win32下gettimeofday方法的实现被官方这么修改过之后是不能获取到准确的年月日时分秒的

    如果要获取准确的数据,可以使用以下方法

    void GetTime(int level)  
    {  
    struct tm *tm;  
    time_t timep;  
    #if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
        time(&timep);  
    #else
    struct cc_timeval now;   
        CCTime::gettimeofdayCocos2d(&now, NULL);   
        timep = now.tv_sec;  
    #endif
    
    
    tm = localtime(&timep);  
    int year = tm->tm_year + 1900;  
    int month = tm->tm_mon + 1;  
    int day = tm->tm_mday;  
    int hour=tm->tm_hour;  
    int min=tm->tm_min;  
    int second=tm->tm_sec;  
    } 

    这回win32平台上OK了,至于其他平台上有没有问题,要测试下~

    总结了一下上面的转载:

    //cocos2d-x获取系统时间,毫秒级的;
    long MenuLayer::currentTimeInMS() {
        struct cc_timeval now;
        CCTime::gettimeofdayCocos2d(&now, NULL);
        return (now.tv_sec * 1000 + now.tv_usec /1000.0)/10;
    }
    //cocos2d-x获取系统时间,包括年月日
    void MenuLayer::GetTime() {
        struct tm *tm;  
        time_t timep;  
    #if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)  
        time(&timep);  
    #else  
        struct cc_timeval now;   
        CCTime::gettimeofdayCocos2d(&now, NULL);   
        timep = now.tv_sec;  
    #endif  
        tm = localtime(&timep);  
        int year = tm->tm_year + 1900;  
        int month = tm->tm_mon + 1;  
        int day = tm->tm_mday;  
        int hour=tm->tm_hour;  
        int min=tm->tm_min;  
        int second=tm->tm_sec;
    }
  • 相关阅读:
    day25 初始面向对象
    JavaScript中的apply()和call()
    JavaScript中的arguments详解
    测试使用MarkDown在博客园发布博客
    《Spring实战》 1-2
    总结: 《jQuery基础教程》 5-完结
    总结: 《jQuery基础教程》 1-4章
    做个计划
    Nginx与tomcat组合的简单使用
    利用 Dijit 组件框架打造丰富的用户界面
  • 原文地址:https://www.cnblogs.com/yssgyw/p/3280502.html
Copyright © 2011-2022 走看看