跳转至

47 os-操作系统基础功能

作者:王棚嶙 | 最后修改:2026-05-07

一、概述

os核心库提供了文件操作、时间日期处理、系统信息获取等核心功能。os 库提供的文件操作接口与 io 库、fatfs 库配合使用可以完成绝大多数文件级操作需求;

1.1 时间操作说明

os时间函数经常与 socket 核心库配合使用。通过网络 NTP 成功获取时间后,建议直接使用 os.date() 获取本地时间,而非 rtc.get()。

1.1.1 底层工作机制:

1、socket.sntp() 执行成功后,会通过 NTP_UPDATE 事件通知应用层;

2、os.date() 基于系统当前时间工作,自动处理时区转换和格式化输出;

3、rtc.get()/rtc.set() 直接操作硬件 RTC 寄存器,返回原始时间数据;

NTP 时间同步的完整流程

-- 方法1:使用网络时间设置 RTC,然后通过 os.date() 获取
local function ntp_time_handler()
    -- 获取网络时间戳(可选)
    local tm = socket.ntptm()


    -- 使用 os.date() 获取格式化本地时间
    log.info("本地时间", os.date("%Y-%m-%d %H:%M:%S"))
    local t = os.date("*t")
    log.info("时间详情", json.encode(t))
end
sys.subscribe("NTP_UPDATE", ntp_time_handler)

-- 方法2:直接使用 os.date() 获取当前系统时间
local function show_current_time()
    -- 适用于系统时间已同步的场景
    log.info("当前时间", os.date("%Y-%m-%d %H:%M:%S"))
end
show_current_time()

1.1.2 os.date 与 rtc.set/rtc.get 的核心区别

os.date:

1、基于系统时间戳,自动处理时区转换;

2、提供格式化输出,支持标准 C 库 strftime 格式;

3、默认返回本地时间,通过格式字符串前缀"!"可获取UTC时间;

rtc.set/rtc.get:

1、直接读写硬件 RTC 寄存器,返回原始时间数据;

2、重要:rtc.set() 只能设置UTC时间(0时区时间),不处理时区;

3、重要:rtc.get() 获取的也是UTC时间(0时区时间);

4、时区设置通过 rtc.timezone() 单独配置,不影响 rtc.get() 的返回值;

1.1.3 推荐使用 os.date 的原因

1、使用简单:一行代码获取格式化时间,如 os.date("%Y-%m-%d %H:%M:%S");

2、时区智能:自动应用系统时区设置,直接返回本地时间,无需关心 rtc.timezone() 配置;

3、格式丰富:支持完整的 strftime 格式规范,包括 %Y年、%m月、%d日等所有标准格式;

4、标准化:遵循 C 标准库规范,格式字符串与其他平台通用,代码可移植性强;

5、便于理解:提供直观的时间格式化输出,直接适合用户界面显示和日志记录;

1.1.4 UTC 时间与本地时间的详细说明

什么是 UTC 时间

1、UTC(协调世界时):全球统一的时间标准,不受任何时区影响,是国际标准时间;

2、特点:全球统一、无夏令时、常用于网络时间同步、日志记录等场景;

3、获取方式os.date("!*t")返回 UTC 时间的 table 格式,os.date("!%Y-%m-%d %H:%M:%S")返回 UTC 时间字符串;

什么是本地时间

1、本地时间:基于 UTC 时间加上当地时区偏移,反映用户所在地区的实际时间;

2、特点:包含时区信息、自动处理夏令时(如适用)、适合用户界面显示;

3、获取方式:os.date("*t")返回本地时间的 table 格式,os.date("%Y-%m-%d %H:%M:%S")返回本地时间字符串;

详细示例可见4.4部分;

二、核心示例

1、核心示例是指:使用本库文件提供的核心 API,开发的基础业务逻辑的演示代码;

2、核心示例的作用是:帮助开发者快速理解如何使用本库,所以核心示例的逻辑都比较简单;

3、更加完整和详细的 demo,请参考 LuatOS 仓库 中各个产品目录下的 demo/os;

-- 文件删除
if os.remove("/sd/test.txt") then
    log.info("os.remove", "文件删除成功")
else
    log.error("os.remove", "文件删除失败")
end

-- 文件重命名
if os.rename("/sd/old.txt", "/sd/new.txt") then
    log.info("os.rename", "文件重命名成功")
else
    log.error("os.rename", "文件重命名失败")
end

三、常量详解

核心库常量,顾名思义是由合宙 LuatOS 内核固件中定义的、不可重新赋值或修改的固定值,在脚本代码中不需要声明,可直接调用;

每个常量对应的常量取值仅做日志打印时查询使用,不要将这个常量取值用做具体的业务逻辑判断,因为LuatOS内核固件可能会变更每个常量对应的常量取值;

如果用做具体的业务逻辑判断,一旦常量取值发生改变,业务逻辑就会出错;

os核心库无常量

四、函数详解

4.1 os.remove(path)

功能

删除文件;

注意事项

1、只能删除文件,不能删除目录;

2、只读文件系统中的文件(/luadb/,以及只读挂载的sd卡)无法删除;

参数

path

参数含义:要删除的文件路径;
数据类型:string
取值范围:有效的文件路径;
是否必选:是;
注意事项:文件必须存在;
参数示例:"/sd/test.txt"

返回值

local success, errmsg = os.remove(path)

有两个返回值

success

含义说明:删除操作结果;
数据类型:boolean
取值范围:true或false
注意事项:暂无;
返回示例:true

errmsg

含义说明:错误信息;
数据类型:string
取值范围:错误描述字符串;
注意事项:失败时返回错误原因;
返回示例:"No such file or directory"

错误码对照表

示例

local success, errmsg = os.remove("/sd/data.txt")
if success then
    log.info("os.remove", "删除成功")
else
    log.error("os.remove", "删除失败", errmsg)
end

4.2 os.rename(old_path, new_path)

功能

文件重命名;

注意事项

1、只能在同一个文件系统内操作;

2、需要源文件存在,且源文件不能是只读属性,如(/luadb/,以及只读挂载的sd卡);

3、目标文件不能已存在,目标文件所在的目录要存在;

参数

path

参数含义:原文件路径;
数据类型:string
取值范围:有效的文件路径;
是否必选:是;
注意事项:文件必须存在;
参数示例:"/sd/old.txt"

new_path

参数含义:目标文件路径;
数据类型:string
取值范围:有效的文件路径;
是否必选:是;
注意事项:路径必须在同一文件系统;
参数示例:"/sd/new.txt"

返回值

local success, errmsg = os.rename(old_path, new_path)

有两个返回值

success

含义说明:重命名操作结果;
数据类型:boolean
取值范围:true或false
注意事项:暂无;
返回示例:true

errmsg

含义说明:错误信息;
数据类型:string
取值范围:错误描述字符串;
注意事项:失败时返回错误原因;
返回示例:"No such file or directory"

错误码对照表

示例

local success, errmsg = os.rename("/sd/temp.txt", "/sd/backup.txt")
if success then
   log.info("os.rename", "重命名成功")
else
   log.error("os.rename", "重命名失败", errmsg)
end

4.3 os.date(fmt, time)

功能

将时间转换为指定格式的字符串或时间表

注意事项

1、若需要UTC时间,fmt的第一个字符写"!";

2、fmt的格式化遵循 C 函数 strftime;

3、当fmt为"*t"时返回table,否则返回string;

参数

fmt

参数含义:格式化字符串,可参考下方对照表;
数据类型:string或nil
取值范围:strftime格式字符串
是否必选:否;
注意事项:nil时返回默认格式字符串
参数示例:"%Y-%m-%d %H:%M:%S";

格式化符号对照表

含义 示例
%Y 4位数年份 2023
%y 2位数年份 23
%m 2位数月份 1
%d 2位数日期 31
%H 24小时制小时 14
%I 12小时制小时 12
%M 分钟 00-59
%S 秒钟 00-59
%p 上午/下午 AM/PM
%A 星期全名 Sunday
%a 星期缩写 Sun
%B 月份全名 January
%b 月份缩写 Jan
%c 默认格式 Thu Jan 1 00:00:00 1970
! UTC时间前缀 os.date("!%Y-%m-%d %H:%M:%S")

time

参数含义:Unix时间戳
数据类型:number
取值范围:有效的Unix时间戳
是否必选:否,默认为当前时间;
注意事项:如果需要传入自定义时间,建议先通过 os.time() 转换;
参数示例:"os.time()";

返回值

local result = os.date(fmt, time)

有一个返回值

result

含义说明:格式化后的日期时间字符串或日期时间table,fmt为"*t"或者"!*t"时,返回table
         格式为{year, month, day, hour, min, sec, wday, yday,isdst},说明如下;
         {
          -- 参数含义:年份;
         -- 数据类型:number;
         -- 取值范围:为4位整数,如2023;
         -- 注意事项:暂无;
         -- 返回示例:2023
         year = ,

        -- 参数含义:月份;
        -- 数据类型:number;
        -- 取值范围:1-12(1代表一月);
        -- 注意事项:无;
        -- 返回示例:1
        month = ,

        -- 参数含义:日期;
        -- 数据类型:number;
        -- 取值范围:1-31(取决于月份和闰年);
        -- 注意事项:无;
        -- 返回示例:1
        day = ,

        -- 参数含义:小时;
        -- 数据类型:number;
        -- 取值范围:0-23;
        -- 注意事项:默认值为12;
        -- 返回示例:0
        hour = , 

        -- 参数含义:分钟;
        -- 数据类型:number;
        -- 取值范围:0-59;
        -- 注意事项:默认值为0;
        -- 返回示例:0
        min = ,

        -- 参数含义:秒钟;
        -- 数据类型:number;
        -- 取值范围:0-59;
        -- 注意事项:默认值为0;
        -- 返回示例:0
        sec = ,

        -- 参数含义:星期几;
        -- 数据类型:number;
        -- 取值范围:1-7(1代表星期天,2代表星期一,依此类推);
        -- 注意事项:通常由os.date返回,不是os.time的输入字段;
        -- 返回示例:2
        wday = ,

        -- 参数含义:年份中的第几天;
        -- 数据类型:number;
        -- 取值范围:1-366(取决于闰年);
        -- 注意事项:通常由os.date返回,不是os.time的输入字段;
        -- 参数示例:15
        yday = ,

        -- 参数含义:夏令时标志;
        -- 数据类型:boolean;
        -- 取值范围:true或false;
        -- 注意事项:默认值为nil,表示不使用夏令时;
        -- 参数示例:false
        isdst = ,          
        }
数据类型:string/table
取值范围:格式化字符串或包含日期时间字段的table
注意事项:当fmt为"*t"或者"!*t"时返回table,否则返回string
返回示例:字符串示例:"2024-01-15 14:30:45"
         table示例{year=2024, month=1, day=15, hour=14, min=30, sec=45, wday=2, yday=15,          isdst=false}

示例

-- 获取本地时间字符串
-- 本地时间字符串 Tue Sep 30 00:22:21 2025
log.info("本地时间字符串", os.date())

-- 获取UTC时间字符串  
-- UTC时间字符串 month Sep 29 16:22:21 2025
log.info("UTC时间字符串", os.date("!%c"))

-- 格式化本地时间字符串
-- 本地时间字符串 2025-09-30 00:22:21
log.info("本地时间字符串", os.date("%Y-%m-%d %H:%M:%S"))

-- 格式化UTC时间字符串
-- UTC时间字符串 2025-09-29 16:22:21
log.info("UTC时间字符串", os.date("!%Y-%m-%d %H:%M:%S"))

-- 格式化指定时间
local custom_time = os.time({year=2000, month=1, day=1, hour=0, min=0, sec=0})
-- 自定义时间的字符串 1999-12-31 16:00:00
log.info("自定义时间的字符串", os.date("!%Y-%m-%d %H:%M:%S", custom_time))

-- 获取本地时间的table
-- 本地时间table {"wday":3,"min":22,"yday":273,"hour":0,"isdst":false,"year":2025,"month":9,"sec":21,"day":30}
log.info("本地时间table", json.encode(os.date("*t")))

-- 获取UTC时间的table  
-- UTC时间table {"wday":2,"min":22,"yday":272,"hour":16,"isdst":false,"year":2025,"month":9,"sec":21,"day":29}
log.info("UTC时间table", json.encode(os.date("!*t")))

4.4 os.time(mytime)

功能

将时间表转换为时间戳;

注意事项

暂无;

参数

mytime

参数含义:时间表;
数据类型:table,当mytime为table时的格式为{year, month, day, hour, min, sec}说明如下;
{
-- 参数含义:年份;
-- 数据类型:number;
-- 取值范围:为4位整数,如2023;
-- 是否必选:是;
-- 注意事项:使用4位数年份以避免歧义;
-- 参数示例:2023
参数名称: mytime.year

-- 参数含义:月份;
-- 数据类型:number;
-- 取值范围:1-12(1代表一月);
-- 是否必选:是;
-- 注意事项:无;
-- 参数示例:1
参数名称: mytime.month -- 参数含义:日期;
-- 数据类型:number;
-- 取值范围:1-31(取决于月份和闰年);
-- 是否必选:是;
-- 注意事项:无;
-- 参数示例:1
参数名称: mytime.day

-- 参数含义:小时;
-- 数据类型:number;
-- 取值范围:0-23;
-- 是否必选:否; -- 注意事项:默认值为12;
-- 参数示例:0
参数名称: mytime.hour

-- 参数含义:分钟;
-- 数据类型:number;
-- 取值范围:0-59;
-- 是否必选:否;
-- 注意事项:默认值为0;
-- 参数示例:0
参数名称: mytime.min

-- 参数含义:秒钟;
-- 数据类型:number;
-- 取值范围:0-59;
-- 是否必选:否;
-- 注意事项:默认值为0;
-- 参数示例:0
参数名称: mytime.sec }

取值范围:包含时间字段的表;
是否必选:否;
注意事项:nil时表示使用当前时间;
参数示例:{year=2023, month=1, day=1, hour=0, min=0, sec=0}

返回值

local timestamp = os.time(mytime)

有一个返回值

timestamp

含义说明:Unix时间戳
数据类型:number
取值范围:≥0的整数;
注意事项:暂无;
返回示例:946656000

示例

local timestamp_a =  os.time({year=2000, month=1, day=1, hour=0, min=0, sec=0})
-- 自定义时间戳 946656000
log.info("自定义时间戳", timestamp_a)

local timestamp_b = os.time()
-- UTC时间戳 1759161153
log.info("UTC时间戳", timestamp_b)

4.5 os.difftime(timeA, timeB)

功能

计算两个时间戳的差值;

注意事项

1、返回timeA - timeB的差值;

2、支持负数结果;

参数

timeA

参数含义:时间戳A
数据类型:number
取值范围:Unix时间戳
是否必选:是;
注意事项:暂无;
参数示例:os.time()

timeB

参数含义:时间戳B
数据类型:number
取值范围:Unix时间戳
是否必选:是;
注意事项:暂无;
参数示例:os.time({year=2023, month=1, day=1})

返回值

local difference = os.difftime(timeA, timeB)

有一个返回值

difference

含义说明:时间差值;
数据类型:number
取值范围:整数;
注意事项:单位是秒,time_a - time_b
返回示例:-812504729

示例

local a =  os.time({year=2000, month=1, day=1, hour=0, min=0, sec=0})
-- 自定义时间戳 946656000
log.info("自定义时间戳", a)

local b = os.time()
-- UTC时间戳 1759161153
log.info("UTC时间戳", b)

local difference = os.difftime(a, b)
-- -812504729
log.info("自定义时间戳差值-UTC时间戳", difference)

五、产品支持说明

支持 LuatOS 开发的所有产品都支持os核心库。