一、簡介
最近馬三在工作中經常使用到了lua 中的 os.date( ) 和 os.time( )函數,不過使用的時候都是不得其解,一般都是看項目里面怎么用,然后我就模仿寫一下。今天正好稍微有點空閑時間就好好地收集了一下相關資料並學習了一下,並將學習結果記錄成此博客。
二、os.time和os.date函數說明
1.os.time()函數
os.time()的函數原型與Lua官方的解釋如下:

如果沒有任何參數,就會返回當前時間。如果參數一個table,並且table的域必須有 year, month, day, 可有也可以沒有 hour, min, sec, isdst,則會返回table所代表日期的時間,如果未定義后幾項,默認時間為當天正午(12:00:00)。 返回值是一個 number ,其值取決於你的系統。返回值通常被用於 os.date 和 os.difftime。
具體的用法可以看下面幾段代碼樣例:
print(os.time()) print(os.time({day=26,month=4,year=2018})) print(os.date("%y/%m/%d, %H:%M:%S",os.time({day=26,month=4,year=2018})))
其執行結果如下圖所示:

圖1:os.time樣例執行結果示意圖
os.time()函數的源碼如下,可以仔細研讀一下,對提高代碼水平有幫助:
1 static int os_time (lua_State *L) { 2 time_t t; 3 if (lua_isnoneornil(L, 1)) /* called without args? */ 4 t = time(NULL); /* get current time */ 5 else { 6 struct tm ts; 7 luaL_checktype(L, 1, LUA_TTABLE); 8 lua_settop(L, 1); /* make sure table is at the top */ 9 ts.tm_sec = getfield(L, "sec", 0); 10 ts.tm_min = getfield(L, "min", 0); 11 ts.tm_hour = getfield(L, "hour", 12); 12 ts.tm_mday = getfield(L, "day", -1); 13 ts.tm_mon = getfield(L, "month", -1) - 1; 14 ts.tm_year = getfield(L, "year", -1) - 1900; 15 ts.tm_isdst = getboolfield(L, "isdst"); 16 t = mktime(&ts); 17 } 18 if (t == (time_t)(-1)) 19 lua_pushnil(L); 20 else 21 lua_pushnumber(L, (lua_Number)t); 22 return 1; 23 }
2.os.date()函數
os.date()函數的原型與Lua官方解釋如下:

第一個參數是時間的格式化參數,如果設置了則會按照固定的格式來格式化時間。若設置time參數,則按time指定的時間格式化,否則按當前時間格式化。如果format 以 ! 開始, date 會被格式化成協調世界時(Coordinated Universal Time) 。 *t 將返一個帶year(4位), month(1-12), day (1--31), hour (0-23), min (0-59), sec (0-61), wday (星期幾, 星期天為1), yday (年內天數), isdst (是否為日光節約時間true/false)的表。若沒有*t則返回一個按C的strftime函數格式化的字符串 若不帶參數,則按當前系統的設置返回格式化的字符串 os.date() <=> os.date("%c")。
對於format參數,馬三在這里給大家提供了一個列表,分別列出了各種format參數和對應的含義:
%a - Abbreviated weekday name (eg. Wed) %A - Full weekday name (eg. Wednesday) %b - Abbreviated month name (eg. Sep) %B - Full month name (eg. September) %c - Date and time representation appropriate for locale (eg. 23/04/07 10:20:41) (Standard date and time string ) - see below for using os.setlocale to get the correct locale. %d - Day of month as decimal number (01 - 31) %H - Hour in 24-hour format (00 - 23) %I - Hour in 12-hour format (01 - 12) %j - Day of year as decimal number (001 - 366) %m - Month as decimal number (01 - 12) %M - Minute as decimal number (00 - 59) %p - Current locale’s A.M./P.M. indicator for 12-hour clock (eg. AM/PM) %S - Second as decimal number (00 - 59) %U - Week of year as decimal number, with Sunday as first day of week 1 (00 - 53) %w - Weekday as decimal number (0 - 6; Sunday is 0) %W - Week of year as decimal number, with Monday as first day of week 1 (00 - 53) %x - Date representation for current locale (Standard date string) %X - Time representation for current locale (Standard time string) %y - Year without century, as decimal number (00 - 99) (eg. 07) %Y - Year with century, as decimal number (eg. 2007) %Z - Time-zone name or abbreviation; no characters if time zone is unknown %% - Percent sign
具體的用法,我們依然可以參考下面的幾段代碼樣例:
1 print("=================os.date test===============") 2 print(os.date()) 3 print(os.date("%x",os.time())) 4 print(os.date("*t")) 5 print(os.date("*t").year) 6 print(os.date("*t").month) 7 print(os.date("*t").day) 8 print(os.date("*t").hour) 9 print(os.date("*t").wday) 10 -- 顯示當前年份 11 print(os.date("%Y")) 12 -- 顯示當前是一年中的第幾周 13 print(os.date("%U")) 14 -- 組合格式化時間 15 print(os.date("%Y-%m-%d, %H:%M:%S",os.time()))
其執行結果如下圖所示:

圖2:os.date()樣例函數執行結果示意圖
os.date( )函數源碼如下:
1 static int os_date (lua_State *L) { 2 size_t slen; 3 const char *s = luaL_optlstring(L, 1, "%c", &slen); 4 time_t t = luaL_opt(L, l_checktime, 2, time(NULL)); 5 const char *se = s + slen; /* 's' end */ 6 struct tm tmr, *stm; 7 if (*s == '!') { /* UTC? */ 8 stm = l_gmtime(&t, &tmr); 9 s++; /* skip '!' */ 10 } 11 else 12 stm = l_localtime(&t, &tmr); 13 if (stm == NULL) /* invalid date? */ 14 luaL_error(L, "time result cannot be represented in this installation"); 15 if (strcmp(s, "*t") == 0) { 16 lua_createtable(L, 0, 9); /* 9 = number of fields */ 17 setallfields(L, stm); 18 } 19 else { 20 char cc[4]; /* buffer for individual conversion specifiers */ 21 luaL_Buffer b; 22 cc[0] = '%'; 23 luaL_buffinit(L, &b); 24 while (s < se) { 25 if (*s != '%') /* not a conversion specifier? */ 26 luaL_addchar(&b, *s++); 27 else { 28 size_t reslen; 29 char *buff = luaL_prepbuffsize(&b, SIZETIMEFMT); 30 s++; /* skip '%' */ 31 s = checkoption(L, s, se - s, cc + 1); /* copy specifier to 'cc' */ 32 reslen = strftime(buff, SIZETIMEFMT, cc, stm); 33 luaL_addsize(&b, reslen); 34 } 35 } 36 luaL_pushresult(&b); 37 } 38 return 1; 39 }
3.計算時間差
在開發過程中我們經常遇到需要計算兩個時間t1,t2的時間差這種需求,我們可以直接使用os.difftime( )這個自帶的函數來完成,當然我們也可以自己實現一個符合自己要求的函數。例如,策划經常會在表格中配置一些活動/玩法的開啟時間等,樣式如下圖所示:

圖3:時間差數據表示意圖
然后我們就可以利用下面的代碼實現求時間差了,它會返回當前時間和配置時間相差的秒數:
1 Split = function(szFullString,szSeprator) 2 local nFindStartIndex = 1 3 local nSplitIndex = 1 4 local nSplitArray = {} 5 while true do 6 local nFindLastIndex = string.find(szFullString,szSeprator,nFindStartIndex) 7 if not nFindLastIndex then 8 nSplitArray[nSplitIndex] = string.sub(szFullString,nFindStartIndex,string.len(szFullString)) 9 break 10 end 11 nSplitArray[nSplitIndex] = string.sub(szFullString,nFindStartIndex,nFindLastIndex - 1) 12 nFindStartIndex = nFindLastIndex + string.len(szSeprator) 13 nSplitIndex = nSplitIndex + 1 14 end 15 return nSplitArray 16 end 17 18 formatTime = function( timeStr ) 19 local splited = Split(timeStr, ":") 20 local h = splited[1] 21 local m = splited[2] 22 return tonumber(h), tonumber(m) 23 end 24 25 getRemainTime = function(timeStr) 26 local h1, m1 = formatTime(timeStr) 27 local curTime = os.date("*t", os.time()) 28 local curH = curTime.hour 29 local curM = curTime.min 30 31 local remainH = h1 - curH 32 local remainM = m1 - curM 33 local totalRemainSeCond = remainH * 3600 + remainM * 60 34 return totalRemainSeCond 35 end
三、總結
對於一些lua中的源碼我們可以到這里去下載並查看學習:傳送門 。最近項目實在是太忙了,忙得暈頭轉向的,天天加班到深夜,真是嗶了狗了。今天好不容易擠出點時間更新點東西,真雞兒難受~
本篇博客中的代碼已經同步到Github:https://github.com/XINCGer/Unity3DTraining/tree/master/SomeTest/os_time 歡迎fork!
作者:馬三小伙兒
出處:http://www.cnblogs.com/msxh/p/8955150.html
請尊重別人的勞動成果,讓分享成為一種美德,歡迎轉載。另外,文章在表述和代碼方面如有不妥之處,歡迎批評指正。留下你的腳印,歡迎評論!
