px普贤教程PuXian
普贤教程 › 进阶教程

时间与日期

PuXian 的时间底层就是整数时间戳。这里有一个必须提前知道的事实:time_format 按 UTC 输出,要本地时间得再换算一次。

拿时间

px
print(str(now_sec() > 1700000000))
print(str(now_ms() > 1700000000000))
print(now())
text
true
true
2026-11-05 17:06:52
函数返回时区
now_sec()秒级时间戳(int)—
now_ms()毫秒级时间戳(int)—
now()格式化字符串 %Y-%m-%d %H:%M:%S本地
time_format(sec, fmt)按格式串输出UTC

时区:最容易出错的地方

px
print(now())                                       # 本地
print(time_format(now_sec(), "%Y-%m-%d %H:%M:%S")) # UTC
text
2026-11-05 17:06:52
2026-11-05 09:06:52

同一时刻,两个函数差 8 小时。time_format 固定按 UTC 解释时间戳,不受 TZ 环境变量影响。要本地时间,三条路:

做法写法
直接取现成字符串now()
时间戳 + 时区偏移格式化dt_to_timezone(sec, 8 * 3600)
用 Go 风格格式化import std.time_go → go_date_time(sec)
px
import std.time_go

print(go_date_time(now_sec()))
print(go_rfc3339(now_sec()))
text
2026-11-05 17:06:52
2026-11-05T17:06:52+08:00
写日志时想清楚用哪个日志用 UTC 便于跨机器对齐,展示给用户用本地。混用会造成"日志里是 09:06,用户说是 17:06 出的问题"这种排查灾难。建议:日志统一 UTC 并标注 Z。

格式化符

格式含义
%Y %m %d年(4 位)/ 月 / 日
%H %M %S时 / 分 / 秒(24 小时制)
%Y-%m-%d2026-11-05
%H:%M17:06

日期运算

时间戳是整数,加减就是算术。一天固定 86400 秒:

px
var t = now_sec()
var day = 86400
print(time_format(t + day, "%m-%d"))
print(time_format(t - 7 * day, "%m-%d"))
text
11-06
10-29

更规范的做法是用 datetime 包,它把"加天数、算差值、判闰年"都封好了:

sh
pxpkg add datetime@0.2.0 && pxpkg install
px
import datetime

var t = dt_now_sec()
print(dt_format(t, "%Y-%m-%d"))                    # UTC
print(dt_to_timezone(t, 8 * 3600))                 # 本地
print(dt_format(dt_add_days(t, 30), "%Y-%m-%d"))
print(str(dt_days_between(t, dt_add_days(t, 30))))
print(dt_humane(t, t - 180))
text
2026-11-05
2026-11-05 17:06:52
2026-12-05
30
3分钟前
函数作用
dt_now_sec()当前秒级时间戳(dt_now() 返回的是字符串,别混)
dt_format(sec, fmt)格式化(UTC)
dt_to_timezone(sec, off_sec)按偏移格式化,如 8 * 3600
dt_parse(s, fmt) / dt_iso_parse(s)解析字符串
dt_add_days(sec, n) / dt_add(sec, delta)加减
dt_days_between(a, b) / dt_diff差值
dt_weekday(y, m, d) / dt_week_of_year / dt_quarter星期 / 周数 / 季度
dt_is_leap_year / dt_days_in_month闰年、月天数
dt_humane(now, then)"3分钟前"这类相对描述
dt_duration_parse("1h30m") / dt_duration_format(sec)时长解析与格式化

测耗时

px
var t0 = now_ms()
var sum = 0
for i in range(0, 100000):
    sum += i
print("耗时 " + str(now_ms() - t0) + " ms")
text
耗时 5374 ms
同一个程序编译后是 11 ms上面这段在解释轨跑 5 秒多(三次 5182–5928 ms),px build 出来的二进制 10–12 毫秒(默认 VM 字节码轨;--c 的 C 轨 4–5 ms)。测性能前先确认自己跑的是哪条轨。

常见坑

现象原因
时间差 8 小时time_format 是 UTC;要本地用 now() 或 dt_to_timezone
年份 5 万多把毫秒时间戳传给了按秒的函数
dt_now() 传给 dt_format 报"无法转为 int"dt_now() 返回字符串,应该用 dt_now_sec()
跨月天数算错用 30 天近似;改用 dt_days_between