lua中的时区与时间

时间:2022-03-21 22:08:46

参考链接:1 2,请点击连接查看原文,尊重楼主版权。本文自己加了点总结和新手保护机制。

lua中的时间库


1. os.time()

原型:os.time ([table])
解释:按table的内容返回一个时间值(数字),若不带参数则使用当前时间(本时区此刻时间)作为table内容,其中table中可以包含的字段有:year, month, day, hour, min, sec, isdst,其他字段将会被忽略。

案例:

local nowtime = os.time();
print("nowtime = "..nowtime)
--nowtime = 1494833502

local exampletime = os.time({year=2008,month=8,day=8,hour=20,min=0,sec=0});
print("exampletime = "..exampletime)
--exampletime = 1218196800

local origintime = os.time({year=1970,month=1,day=1,hour=8,min=0,sec=0});
print("origintime = "..origintime)
--origintime = 0

-- 错误的时间
local errortime = os.time({year=1970,month=1,day=1,hour=0,min=0,sec=0});
print("errortime = "..(errortime or "nil"))
--errortime = nil

-- 完整日期
local testtime1 = os.time({year=2008,month=1,day=1,hour=8,min=0,sec=0,isdst=false});
print("testtime1 = "..testtime1)
--testtime1 = 1199145600

-- 去掉isdst
local testtime2 = os.time({year=2008,month=1,day=1,hour=8,min=0,sec= 0});
print("testtime2 = "..testtime2)
--testtime2 = 1199145600

-- 去掉sec
local testtime3 = os.time({year=2008,month=1,day=1,hour=8,min=0});
print("testtime3 = "..testtime3)
--testtime3 = 1199145600

-- 去掉min
local testtime4 = os.time({year=2015,month=1,day=1,hour=8});
print("testtime4 = "..testtime4)
--testtime4 = 1420070400

-- photo纪念日:年月日
local testtime5 = os.time({year=2016,month=7,day=17});
print("testtime5 = "..testtime5)
--testtime5 = 1468728000

-- 去掉day
--local testtime6 = os.time({year=2016,month=7});
--print("testtime6 = "..testtime6) --报错

总结:

-1- os.time()不加参数表示当前时间的时间戳,这个函数在任意时区下获取到结果一致,因为都表示格林尼治时间1970.01.01-00:00:00到现在这个点格林尼治时间经过的秒数。不管你的时区是什么,这个值是一个绝对的值。


-2- os.time(table)得到格林尼治时间为1970.01.01-00:00:00时本时区的时间(北京为8点)到本时区table时刻,经过的秒数。

--这个函数返回一个值意味着它依赖于你的操作系统,在POSIX ,Windows和一些其他的操作系统上,这个数字是记录了时间原点(1970-01-01)到指点时间的秒数,在个别的系统上结果未定义。


-3- 由origintime可以看出时间从原点到1970-1-1 08:00:00返回的时间居然是0,其实这是由于时区导致的,北京时间的1970-1-1 08:00:00恰好是0时区时间的1970-1-1 00:00:00,所以返回的时间是0;如果做运算的系统时区是0时区,则os.time({year=1970,month=1,day=1,hour=8,min=0,sec=0})将返回8*3600.


-4- 明白了origintime相信你就会知道errortime为什么会返回nil了,因为那个时间还没开始计时呢,理论上应该是负值。


-5- 从结果上来看,最后的一次调用造成了程序的出错,那是因为table的几个字段中year, month, day是必填的,而hour, min, sec, isdst是可选的。


-6- 还有一点hour, min, sec这几个值的范围不一定是正常的时间,甚至可以是负数,比如时间08:62:-10就代表了09:01:50。


2. os.date()

原型:os.date ([format [, time]])
解释:返回一个按format格式化日期、时间的字串或表。

参数格式:

简单理解:

没有"!":格林尼治时间0点时候的本地时间,加上第二个参数的秒数,得到的新的本地时间;如:os.date("*t", os.time())表示本地现在时间table

有"!":格林尼治时间0点,加上第二个参数的秒数的时间。如:os.date("!*t", os.time())表示此时格林尼治时间。

由原型可以看出可以省略第二个参数也可以省略两个参数,只省略第二个参数函数会使用当前时间(当前本地时间戳)作为第二个参数,如果两个参数都省略则按当前系统的设置返回格式化的字符串,做以下等价替换 os.date() <=> os.date("%c")。

如果format以“!”开头,则按格林尼治时间进行格式化。
如果format是一个“*t”,将返一个带year(4位),month(1-12), day (1--31), hour (0-23), min (0-59),sec (0-61),wday (星期几, 星期天为1), yday (年内天数)和isdst (是否为日光节约时间(夏令时)true/false)的带键名的表;

使用format "*t"返回的table中wday如果是1表示星期天,而使用通用格式时%w用0表示星期天。


如果format不是“*t”,os.date会将日期(2参数没有则为本地时间)格式化为一个字符串,具体如下:

lua中的时区与时间

print(os.date("today is %c, in %A"))         --today is 05/16/17 11:43:16, in Tuesday
print(os.date("1060004s is %x", 1060004)) --1060004s is 01/13/70


3. os.difftime()

原型:os.difftime (t2, t1)

解释:返回以秒计算的时刻t1到 t2 的差值。 在Windows,和其它一些系统中,这个值就等于 t2-t1。

-- 奥运会的时间
local tab = {year=2008, month=8, day=8, hour=20}
local pretime = os.time(tab)
print(os.date("08 Olympic Games time is %x", pretime))
--08 Olympic Games time is 08/08/08

-- 现在的时间
local timetable = os.date("*t");
local nowtime = os.time(timetable)
print(os.date("now time is %c", nowtime))
--now time is 05/16/17 13:33:13

local difft = os.difftime(nowtime, pretime);
print("from 08 Olympic Games to now cost time "..difft.."s");
--from 08 Olympic Games to now cost time 276715993s


4.常用方法:

1/ 获取客户端当前时间戳、时间table: os.time()  、 os.date("*t",os.time())


2/ 获取格林尼治此刻时间table :  os.date("!*t", os.time()) 


3/ 获取客户端当前时区:os.difftime(now, os.time(os.date("!*t", os.time())))/3600

解释: os.time(os.date("!*t", os.time())表示先记下这个格林尼治时间,返回本时区是这个时间table的时候的时间戳。
os.difftime(now, os.time(os.date("!*t", os.time()))) --前面减去后面表示当前时区时间比格林尼治时间大的秒数;
--除以3600就是大的小时数,1时区1小时,所以表示比0时区大的时区数.


4/ 获取服务器目前时间table:

local cur_time=os.time()+3600*(服务器时区-客户端时区)

--本时区目前时间table
 local now_time_table=os.date("*t",cur_time)


5/ 夏令时:夏令时,又称“日光节约时制”和“夏令时间”,是一种为节约能源而人为规定地方时间的制度,在这一制度实行期间所采用的统一时间称为“夏令时间”。

夏令时 一种法定的时间。夏天太阳升起得比较早,白天时间很长。为了节约能源和充分利用白天的宝贵时间,世界上不少国家都采用法律规定的形式,每到夏天就将这个国家使用的时间提前一小时,也有提前半小时或几小时的;到了冬季,又将拨快的时间拨回来。这样的时间就是“夏令时”,是一种法定时间。我国曾于1986年到1991年每年从四月的第二个星期天早上2点钟,到九月的第二个星期天早上2点钟,在这段时期内,全国都将时间拨快1小时,实行夏令时。从九月的第二个星期天早上2点钟起,又将拨快的时间重新拨回来,直到第二年四月的第二个星期天早上2点钟。现在中国已取消夏令时,有些国家还在用。

返回客户端是否夏令时:local now_time_table=os.date("*t",os.time());   return now_time_table.isdst;

如果是夏令时,则计算时间时可以client_time_zone=client_time_zone+1以后一个时区时间计算,否则client_time_zone=client_time_zone。


6/ 传入活动结束时间的时间戳,显示时间(根据客户端时区不同,会显示不同)

function get_format_time(time)   --根据时间戳获取时间,排布
    local format = os.date("*t", time) --获取当时本地时间
    local format_time = string.format("%d/%d/%d %02d:%02d:%02d",format.year,format.month,format.day,format.hour,format.min,format.sec)
         return format_time
end


--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------



一、时间的三种格式

1、用数值表示时间值 (时间戳)
用数字值来表示时间值,
实际上时间值的本质就是一个数字值。
例如:
d = 1131286477 
这里的 1131286477 是一个以秒为单位的 格林威志时间(gmt),注意不同时区的时差

关于时间戳:

时间戳是指格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总秒数。

2、用字符串表示时间 (string)
用字符串来来表示时间。
例如:
d = "2005-11-06 22:18:30" --2005年11月6日 22点18分30秒
d = "11/06/2005 22:18:30" --即2005年11月6日 22点18分30秒


3、时间的列表格式 (table)
用table对象来表示时间
例如:
d = {year=2005, month=11, day=6, hour=22,min=18,sec=30,isdst=false}
--同样表示2005年11月6日 22点18分30秒,其中isdst=false表示不使用夏令时
--夏时制,夏时令(Daylight Saving Time:DST),又称“日光节约时制”和“夏令时间”,是一种为节约能源而人为规定地方时间的制度,在这一制度实行期间所采用的统一时间称为“夏令时间”。一般在天亮早的夏季人为将时间提前一小时,可以使人早起早睡,减少照明量,以充分利用光照资源,从而节约照明用电。各个采纳夏时制的国家具体规定不同。目前全世界有近110个国家每年要实行夏令时。
我们可以这样访问时间列表 d.year = 2005;


二、取得数值(number)格式的时间值 (转换为时间戳)
time = os.time()返回一个标准的number(数值)格式的时间值,这也是最原始的时间值
os.time()返回的时间是以秒为单位的。

1、获取当前时间数值
time = os.time(); 
--如果没有指定任何参数,则返回当前时间

2、通过table参数指定时间,获取指定的时间数值
time = os.time(tab);通过一个table参数,指定一个时间,返回时间的数值格式.
例如:
local tab = {year=2005, month=11, day=6, hour=22,min=18,sec=30,isdst=false}
--year表示年,month表示月,day表示日期,hour表示小时,min表示分钟,sec表示秒,isdst表示是否夏令时 
time = os.time(tab) -->返回值为1131286710

三、取得列表(table)格式的时间(时间戳转换为table)
tab = os.date("*t",time)
可以将一个数值格式的时间转换为字符串或者列表
其中第一个参数指定返回的格式,如果第一个参数指定为"*t" 则返回一个table格式的时间。
第二个参数指定一个时间数值时间戳(以秒为单位)

1、获取当前时间的table格式
tab = os.date("*t") 如果不指定os.date的第二个参数,则返回当前时间的table表示格式

2、通过时间数值,获取指定时间的table格式
tab = os.date("*t", time)通过os.date函数的第二个参数指定一个时间数值。
例如:
local tab = os.date("*t", 1131286710);
--返回值 tab 的数据 {year=2005, month=11, day=6, hour=22,min=18,sec=30}
--year表示年,month表示月,day表示日期,hour表示小时,min表示分钟,sec表示秒,isdst表示是否夏令时 
--tab成包括一些其他的成员 tab.yday 表示一年中的第几天 tab.wday 表示星期几(星期天为1)
time = os.time(tab) -->返回值为1131286710
二、取得数值(number)格式的时间值 (转换为时间戳)
time = os.time()返回一个标准的number(数值)格式的时间值,这也是最原始的时间值
os.time()返回的时间是以秒为单位的。
四、取得时间的字符串(string)格式
tab = os.date(format,time)
实际上与取得table格式的时间一样,同样是使用os.date参数,不同的是第一个参数
如果第一个参数不是"*t" os.date返回字符串

os.date 的用法与 string.ftime 完全相同
例如:
win.consoleOpen()
print(  os.date("today is %A, in %B")  )
print(  os.date("%x", 906000490)  )
--输出类似这样的字符串 09/16/1998
1、获取当前时间的字符串(string)格式
如果不指定os.date的第二个参数,则返回当前时间的table表示格式
例如:
str= os.date("*x")

2、通过时间数值,获取指定时间的(string)格式
通过os.date函数的第二个参数指定一个时间数值。
例如:
str= os.date("*x",1131286710)

3、获取时间的指定部份的(string)格式
例如:
str = os.date("%M") --返回当前时间分钟部份的字符串格式

五、时间数值与字符串之间的转换
请参考:string.time string.ftime 函数用法

六、计算时间值间隔
int = os.difftime(t2,t1);

t2,t1都是数值格式的时间值,返回值也是一个数值表示间隔的时间。


参数以及返回的时间值都是以秒为单位的数值格式。
local tab = {year=2005, month=11, day=6, hour=22,min=18,sec=30,isdst=false}
t1 = os.time(tab)
tab.day = tab.day +1;--前进一天
t2 = os.time(tab)
int = os.difftime(t2,t1);
win.messageBox(int.."秒","时间差"

七、系统时钟
int = os.tick();
读取系统时钟,以毫秒为单位。表示从系统启动到当前时刻所过去的毫秒数。
int = os.clock()
读取系统时钟,以秒为单位。表示从系统启动到当前时刻所过去的秒数。
注意 :
因为内部实现的差异,os.tick 与 os.clock()的返回值并不完全一致。


local getTime = os.date(“%c”);

其中的%c可以是以下的一种:(注意大小写)


%a abbreviated weekday name (e.g., Wed)
%A full weekday name (e.g., Wednesday)
%b abbreviated month name (e.g., Sep)
%B full month name (e.g., September)
%c date and time (e.g., 09/16/98 23:48:10)
%d day of the month (16) [01-31]
%H hour, using a 24-hour clock (23) [00-23]
%I hour, using a 12-hour clock (11) [01-12]
%M minute (48) [00-59]
%m month (09) [01-12]
%p either “am” or “pm” (pm)
%S second (10) [00-61]
%w weekday (3) [0-6 = Sunday-Saturday]
%x date (e.g., 09/16/98)
%X time (e.g., 23:48:10)
%Y full year (1998)
%y two-digit year (98) [00-99]
%% the character ‘%’
如获取当前年月日时分秒:local date=os.date(“%Y-%m-%d %H:%M:%S”);

os.time()
获取当前秒