当函数 os.date
创建日期时间表时,该表的所有字段均在有效的范围内。当我们给函数 os.time
传入一个日期表时,其中的字段并不需要归一化。这个特性对于日期和时间的处理非常重要。
举一个简单的例子,假设想知道从当前向后数 40
天的日期,那么可以使用如下的代码进行计算:
t = os.date("*t") -- 获取当前时间 print(os.date("%Y/%m/%d", os.time(t))) -- 2022/03/18 t.day = t.day + 40 print(os.date("%Y/%m/%d", os.time(t))) -- 2022/04/27
如果我们把数字表示的时间转换成日期表,那么就能得到日期和时间的归一化形式:
t = os.date("*t") print(t.day, t.month) -- 18 3 t.day = t.day - 40 print(t.day, t.month) -- -22 3 t = os.date("*t", os.time(t)) print(t.day, t.month) -- 6 2
在大多数系统中,也可以对数字形式的时间增加或减少 3456000
( 40
天对应的秒数)。不过,由于标准C并不要求数值表示的时间是从纪元开始的,因此标准C并不保证这种操作的正确性。此外,如果我们想增加的是月份而非天数,由于不同的月份具有不同的天数,那么直接操作秒数就会有问题。而以归一化的方式处理则没有这些问题。
t = os.date("*t") print(os.date("%Y/%m/%d", os.time(t))) -- 2022/03/18 t.month = t.month + 6 print(os.date("%Y/%m/%d", os.time(t))) -- 2022/039/18
在操作日期时,我们必须要小心。虽然归一化是以显而易见的方式进行,但是也可能会有一些不明显的后果。例如,如果计算 March 31
之后的一个月,将会得到 April 31
,而实际上应该被归一化成 May 1
( April 30
之后的一天)。尽管这听上去很自然,但实际上如果从结果( May 1
)中减去一个月,得到的却是 April 1
而不是原来的 March 31
。
提示
这种不一致是日历机制导致的结果,与 Lua
语言无关。
os.difftime
函数 os.difftime
用来计算两个时间之间的差值,该函数以秒为单位返回两个指定数字形式表示的时间的差值。对于大多数系统而言,这个差值就是一个时间相对于另一个时间的减法结果。但是,与减法不同,函数 os.difftime
的行为在任何系统中都是确定的。以下示例计算了 Lua5.2
和 Lua5.3
发布时间之间间隔的天数:
local t5_3 = os.time({year = 2015, month = 1, day = 12}) local t5_2 = os.time({year = 2011, month = 12, day = 16}) local d = os.difftime(t5_3, t5_2) print(d // (24 * 3600)) --> 1123
使用函数 difftime
可以获取指定日期相对任意时刻的秒数:
> myepoch = os.time{year = 2000, month = 1, day = 1, hour = 0} > now = os.time{year = 2014, month = 11, day = 20} > os.difftime(now, myepoch) --> 501336000.0点击复制复制失败已复制
通过归一化,可以很容易地将用秒表示的时间转换为合法的数字形式表示的时间,即我们可以创建一个带有开始时刻的日期表并将日期表中的秒数设置为想要转换的数字,例如:
> T = {year = 2000, month = 1, day = 1, hour = 0} > T.sec = 501336000 > os.date("%d/%m/%Y", os.time(T)) --> 20/11/2015点击复制复制失败已复制
os.clock
我们还可以使用函数 os.difftime
来计算一段代码的执行时间。不过,对于这个需求,更好的方式是使用函数 os.clock
,该函数会返回程序消耗的 CPU
时间(单位是秒)。函数 os.clock
在性能测试中的典型用法形如:
local x = os.clock() local s = 0 for i = 1, 100000 do s = s + 1 end print(string.format("elapsed time: %.2f\n", os.clock() -x))
与函数 os.time
不同,函数 os.clock
通常具有比秒更高的精度,因此其返回值为一个浮点数。具体的精度与平台相关,在 POSIX
系统中通常是1毫秒。