cocos2d-x獲取系統時間

歡迎轉載,本帖地址: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;    
}  


上面兩種實現應該都是沒有問題的~~~之前獲取時間的主要作用是給隨機函數做種子,或者計算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了,至於其他平臺上有沒有問題,要測試下~

歡迎轉載,本帖地址:http://blog.csdn.net/jinjian2009/article/details/9449585

發佈了37 篇原創文章 · 獲贊 15 · 訪問量 21萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章