首页 / 资讯中心 / 文章详情

Godot 4 Time 单例完全指南:系统时间、Unix 时间戳与精确计时实战

Godot 4 Time 单例完全指南:系统时间、Unix 时间戳与精确计时实战 ★ FEATURED ARTICLE
文档教程游戏开发【免费下载链接】godot-docsGodot Engine official documentation项目地址https://gitcode.com/GitHub_Trending/go/godot-docs点击查看免费下载导读Time是 Godot 引擎内置的时间单例继承自Object负责在系统时间、Unix 时间戳、ISO 8601 字符串与日期字典等格式之间互相转换同时提供基于引擎内部时钟的精确计时能力。无论是做存档时间戳、排行榜日期、UI 倒计时还是性能剖析与音频同步Time都是 Godot 4 中处理时间的首选入口。读完本文你将掌握Time的全部 20 个方法的用途与参数细节并能正确区分系统时钟与单调时钟的使用场景写出可复用、可运行的 GDScript / C# 时间处理代码。Time 单例的设计原则根据 class_time.rst 的官方说明Time单例提供两类核心能力时间格式转换在系统时间、Unix 时间戳、ISO 8601 字符串和字典之间互相转换系统时间获取读取本地时区或 UTC 下的当前日期与时间。在开始使用之前必须先理解这个类的三个底层约定否则很容易写出有隐患的代码。ISO 8601 与 Proleptic Gregorian先验格里高利日历Time尽量遵循 ISO 8601 标准所有日期均按Proleptic Gregorian 历法先验格里高利历计算即把现行公历规则无限向过去外推1582-10-15的前一天是1582-10-14而不是历史上真实使用的儒略历日期1582-10-04公元 1 年1 AD的前一年记为年份0即 1 BC再往前一年是-12 BC依此类推。也就是说Time可以正确处理负数年份这在处理历史日期或天文场景时很有用但在常规业务中要注意它与你熟悉的公元纪年在公元前部分的计数差异。时区与闰秒Time 不帮你做的三件事Time的转换类方法有一个共同假设输入与输出处于同一时区。具体来说不自动做时区换算get_unix_time_from_datetime_dict()等转换方法不会把你给的本地时间转换成 UTC也不会处理夏令时DST偏移不处理闰秒闰秒需要你按需手动补偿不解析时区后缀像2024-01-01T12:00:00Z中结尾的Z表示 UTC不会被自动处理你需要手动剥离后再传入。因此在把外部系统如服务器返回的 API 时间传入Time之前必须先自行确认其时区语义并做好归一化。系统时钟与引擎时钟两条绝对不能混淆的时间线Time内部存在两条本质不同的时间来源官方文档用加粗字体特别强调了这一点Important:所有_from_system方法读取的是用户可以手动修改的系统时钟。永远不要用它做精确计时因为其结果会受到用户或操作系统自动校时的影响。始终使用get_ticks_usec()或get_ticks_msec()做精确计时它们保证单调递增即永远不会减小。简言之用途应使用方法时钟来源特性显示日期、生成时间戳、记录现在几点get_*_from_system()系列系统墙钟wall clock会被用户/系统校时影响可能回拨测量耗时、性能剖析、音频/动画同步get_ticks_usec()/get_ticks_msec()引擎内部单调时钟永不减小适合做差值计算这两条时间线的选择是本文贯穿始终的主线下文会分别展开。枚举常量Month 与 WeekdayTime提供两组枚举用于与字典转换结果中的month、weekday字段对照取值。Month 枚举112Month枚举的取值与公历月份一一对应注意它是1 起始的常量数值对应月份MONTH_JANUARY1一月MONTH_FEBRUARY2二月MONTH_MARCH3三月MONTH_APRIL4四月MONTH_MAY5五月MONTH_JUNE6六月MONTH_JULY7七月MONTH_AUGUST8八月MONTH_SEPTEMBER9九月MONTH_OCTOBER10十月MONTH_NOVEMBER11十一月MONTH_DECEMBER12十二月Weekday 枚举06Weekday枚举是0 起始的与月份恰好相反周日对应0常量数值对应星期WEEKDAY_SUNDAY0星期日WEEKDAY_MONDAY1星期一WEEKDAY_TUESDAY2星期二WEEKDAY_WEDNESDAY3星期三WEEKDAY_THURSDAY4星期四WEEKDAY_FRIDAY5星期五WEEKDAY_SATURDAY6星期六方法全景一张转换矩阵看懂 20 个方法Time的 20 个方法可以按数据形态分成三大类理解这张矩阵是高效使用它的关键形态一字典Dictionary日期时间被表示为字典按需包含以下键year、month、day、weekday、hour、minute、second、dst。方法输入 → 输出get_date_dict_from_system(utc)系统 →{year, month, day, weekday}get_date_dict_from_unix_time(unix)Unix 时间戳 →{year, month, day, weekday}get_datetime_dict_from_system(utc)系统 →{year, month, day, weekday, hour, minute, second, dst}get_datetime_dict_from_unix_time(unix)Unix 时间戳 →{year, month, day, weekday, hour, minute, second}get_datetime_dict_from_datetime_string(datetime, weekday)ISO 8601 字符串 → 上述字典get_time_dict_from_system(utc)系统 →{hour, minute, second}get_time_dict_from_unix_time(unix)Unix 时间戳 →{hour, minute, second}形态二字符串ISO 8601字符串形式的输出严格遵循 ISO 8601方法输出格式get_date_string_from_system(utc)YYYY-MM-DDget_date_string_from_unix_time(unix)YYYY-MM-DDget_time_string_from_system(utc)HH:MM:SSget_time_string_from_unix_time(unix)HH:MM:SSget_datetime_string_from_system(utc, use_space)YYYY-MM-DDTHH:MM:SSget_datetime_string_from_unix_time(unix, use_space)YYYY-MM-DDTHH:MM:SSget_datetime_string_from_datetime_dict(dict, use_space)字典 →YYYY-MM-DDTHH:MM:SS其中use_space参数为true时日期与时间之间的分隔符由字母T改为一个空格如2024-05-01 09:30:00便于人类阅读的日志输出。形态三Unix 时间戳方法说明get_unix_time_from_system()返回系统当前 Unix 时间戳float 类型保留亚秒精度get_unix_time_from_datetime_dict(dict)字典 → Unix 时间戳intget_unix_time_from_datetime_string(datetime)ISO 8601 字符串 → Unix 时间戳int注意get_unix_time_from_system()由操作系统实现始终返回 UTC即自 1970-01-01 00:00:00Unix epoch以来的秒数。与其它返回整数时间戳的方法不同它返回float因此可以用小数部分表示毫秒/微秒级精度。从系统获取当前时间读取系统当前时间是Time最常用的功能几乎所有方法都带一个utc布尔参数utc false默认返回系统本地时区的值utc true返回 UTC 协调世界时的值。唯一的例外是get_unix_time_from_system()它恒为 UTC。下面的例子演示如何在 GDScript 与 C# 中组合使用这些方法# 获取本地时区的当前日期与时间字典 var now Time.get_datetime_dict_from_system() print(now) # {year: 2026, month: 10, day: 13, weekday: 2, hour: 11, minute: 5, second: 48, dst: 0} # 获取 UTC 时区的当前日期字符串 var utc_date Time.get_date_string_from_system(true) print(utc_date) # 如 2026-10-13 # 获取本地时区的当前完整时间字符串用空格分隔 var local_dt Time.get_datetime_string_from_system(false, true) print(local_dt) # 如 2026-10-13 11:05:48 # 带亚秒精度的 Unix 时间戳 var now_unix: float Time.get_unix_time_from_system() print(now_unix) # 如 1786327548.123var now Time.GetDatetimeDictFromSystem(); GD.Print(now); // {year: 2026, month: 10, day: 13, weekday: 2, ...} var utcDate Time.GetDateStringFromSystem(utc: true); GD.Print(utcDate); var localDt Time.GetDatetimeStringFromSystem(useSpace: true); GD.Print(localDt); double nowUnix Time.GetUnixTimeFromSystem(); GD.Print(nowUnix);真实用例为 LineEdit 插入当前日期在 class_lineedit.rst 中官方给出了一个实际的编辑器扩展示例在LineEdit的右键菜单里加入Insert Date菜单项点击后把当前日期字符串直接插入光标处其核心就是一行Time.get_date_string_from_system()func _on_item_pressed(id): if id MENU_MAX 1: insert_text_at_caret(Time.get_date_string_from_system())这个模式非常适合文本编辑类工具、日志模板插入等功能。Unix 时间戳跨系统的通用时间语言Unix 时间戳自 1970-01-01 00:00:00 起的秒数是游戏存档、排行榜、聊天消息等跨系统数据交换的标准格式。Time提供了完整的时间戳 ⇄ 字典 ⇄ 字符串闭环。时间戳转字典与字符串var unix_time : 1786327548 # 时间戳 → 日期/时间字典 var date_dict Time.get_date_dict_from_unix_time(unix_time) var time_dict Time.get_time_dict_from_unix_time(unix_time) var dt_dict Time.get_datetime_dict_from_unix_time(unix_time) # 时间戳 → ISO 8601 字符串 print(Time.get_date_string_from_unix_time(unix_time)) # 2026-10-13 print(Time.get_time_string_from_unix_time(unix_time)) # 11:05:48 print(Time.get_datetime_string_from_unix_time(unix_time)) # 2026-10-13T11:05:48值得注意的细节get_datetime_dict_from_unix_time()返回的字典与get_datetime_dict_from_system()在当前时刻下取值完全一致唯一的例外是dst夏令时键——因为夏令时状态无法仅凭 epoch 时刻推算所以前者不包含dst。字典与字符串转回时间戳反向转换同样完整且不进行任何时区换算这一点官方文档特别提示Unix 时间戳通常指 UTC但这类方法只是原样把给定字典/字符串解释为时间戳因此结果的时区与输入数据一致。# 字符串 → 时间戳支持只有日期、只有时间、或两者都有的字符串 var ts1 Time.get_unix_time_from_datetime_string(2026-10-13T11:05:48) var ts2 Time.get_unix_time_from_datetime_string(2026-10-13) var ts3 Time.get_unix_time_from_datetime_string(11:05:48) # 字典 → 时间戳 var dict : {year: 2026, month: 10, day: 13, hour: 11, minute: 5, second: 48} var ts4 Time.get_unix_time_from_datetime_dict(dict) # 官方文档保证的可逆性字典转时间戳再转回字典结果一致 var rt Time.get_datetime_dict_from_unix_time(Time.get_unix_time_from_datetime_dict(dict)) print(rt dict) # true两个容易被忽略的默认值行为get_datetime_string_from_datetime_dict()与get_unix_time_from_datetime_dict()对残缺字典的处理规则相同传入空字典时返回0省略部分键时按 Unix epoch 时间戳 0 的对应值补齐即默认到1970-01-01 00:00:00字典中除year、month、day、hour、minute、second以外的其它键包括dst会被静默忽略。print(Time.get_unix_time_from_datetime_dict({})) # 0 print(Time.get_datetime_string_from_datetime_dict({})) # 0 print(Time.get_datetime_string_from_datetime_dict({year: 2026})) # 其余键按 1970-01-01 补齐字符串解析的两个细节get_datetime_dict_from_datetime_string()与get_unix_time_from_datetime_string()都会静默忽略时间字符串中的小数部分——例如2026-10-13T11:05:48.123会被当作2026-10-13T11:05:48处理。另外前者还有一个独立的weekday布尔参数当它为false时返回字典中会去掉weekday键因为该键的计算开销相对昂贵需要额外的星期推算不需要星期信息时应显式传false以提升性能。精确计时get_ticks_msec() 与 get_ticks_usec()这是Time中与墙上时钟完全隔离的另一条时间线专用于性能度量与游戏逻辑计时。两个方法都以引擎启动时刻为原点get_ticks_msec()返回引擎启动以来经过的毫秒数get_ticks_usec()返回引擎启动以来经过的微秒数1 毫秒 1000 微秒。二者均保证非负、单调递增永不回拨且使用64 位整数存储毫秒计数约 5 亿年后才会回绕微秒计数约 50 万年后回绕游戏生命周期内可视为不会溢出。实战一手动剖析函数性能官方在 cpu_optimization.rst 中给出了手动计时函数的推荐写法——用get_ticks_usec()包住待测代码取差值即可var time_start Time.get_ticks_usec() # 你要计时的函数 update_enemies() var time_end Time.get_ticks_usec() print(update_enemies() took %d microseconds % (time_end - time_start))该文档同时给出了一条重要的工程建议手动计时应多次运行1000 次以上取平均值因为定时器精度有限且 CPU 的任务调度具有随机性单次测量不如多次平均可靠。实战二复杂函数的逐段定位当函数整体性能差、但不知道瓶颈在哪一段时the_profiler.rst 展示了用 ticks 逐段计数的做法# 测量 worker_function() 的运行耗时 var start Time.get_ticks_usec() worker_function() var end Time.get_ticks_usec() var worker_time (end - start) / 1000000.0 # 测量遍历数组做计算的耗时 start Time.get_ticks_usec() for calc in calculations: result pow(2, calc.power) * calc.product end Time.get_ticks_usec() var loop_time (end - start) / 1000000.0 print(Worker time: %s\nLoop time: %s % [worker_time, loop_time])实战三音频同步的精确基准get_ticks_usec()的典型应用是音频播放同步。sync_with_audio.rst 中用它建立一个单调的时间基准再补偿音频系统的输出延迟var time_begin var time_delay func _ready(): time_begin Time.get_ticks_usec() time_delay AudioServer.get_time_to_next_mix() AudioServer.get_output_latency() $Player.play() func _process(delta): # 从 ticks 获得经过的时间单位秒 var time (Time.get_ticks_usec() - time_begin) / 1000000.0 # 补偿延迟 time - time_delay # 可能为负尚未开始播放 time max(0, time) print(Time is: , time)这个例子正是系统时钟不可靠、单调时钟才是时间差计算基准这一原则的完美诠释——音频延迟补偿要求时间线持续单调推进任何一次系统校时回拨都会破坏同步。时区信息读取与格式化get_time_zone_from_system()返回当前系统的时区信息字典包含两个键bias与 UTC 的偏差单位为分钟。注意不是所有时区都整小时偏移例如尼泊尔为 UTC5:45因此用分钟计更精确name根据当前用户操作系统区域设置locale得到的本地化时区名称。var tz Time.get_time_zone_from_system() print(tz) # 例如 {bias: 480, name: 中国标准时间}UTC8 时区bias 为正表示东八区 # 注意bias 的符号约定取决于具体系统实现东八区在部分平台上报告为 480在另一部分平台报告为 -480get_offset_string_from_offset_minutes()把以分钟计的时区偏移转换成 ISO 8601 风格的偏移字符串±HH:MM官方文档给出了三个基准例子print(Time.get_offset_string_from_offset_minutes(-480)) # -08:00 print(Time.get_offset_string_from_offset_minutes(345)) # 05:45 print(Time.get_offset_string_from_offset_minutes(0)) # 00:00该方法的典型用途是把get_time_zone_from_system()返回的bias渲染成人类可读的时区后缀例如与日期字符串拼接生成带时区偏移的完整时间标识。从 Godot 3 迁移OS 时间 API 的替代Time单例在 Godot 4 中接管了原先分散在OS上的时间功能。迁移指南 upgrading_to_godot_4.rst 明确列出了一条替代关系OS.get_system_time_secs()应转换为Time.get_time_dict_from_system()[second]。更完整地看Godot 3 中常见的OS时间调用在 Godot 4 中应迁移到Godot 3OS 上Godot 4Time 上OS.get_unix_time()Time.get_unix_time_from_system()OS.get_datetime(utc)Time.get_datetime_dict_from_system(utc)OS.get_date(utc)Time.get_date_dict_from_system(utc)OS.get_time(utc)Time.get_time_dict_from_system(utc)OS.get_system_time_secs()Time.get_time_dict_from_system()[second]OS.get_system_time_msecs()Time.get_ticks_msec()OS.get_ticks_msec()Time.get_ticks_msec()前五条对应关系可由 class_time.rst 中各方法的官方描述直接推导get_system_time_secs()的替代写法则由迁移指南明文给出。完整实战存档系统时间戳方案把本文介绍的能力组合起来可以得到一个完整的存档时间戳读写方案它涵盖了取系统时间 → 转 Unix 时间戳 → 存盘 → 读盘 → 转回可读字符串的全流程extends Node # 保存时生成带毫秒精度的 UTC 时间戳写入存档 func save_timestamp(): var now_unix: float Time.get_unix_time_from_system() save_data[timestamp] now_unix # 同时存一份人类可读的本地时间字符串便于调试 save_data[readable] Time.get_datetime_string_from_system(false, true) # 加载时把时间戳还原成可显示的日期字符串 func load_timestamp(): var ts: float save_data[timestamp] var ts_int: int int(ts) print(Time.get_datetime_string_from_unix_time(ts_int)) # 2026-10-13T11:05:48 # 对比两个存档谁更新直接比较时间戳勿用系统时间字符串做字典序比较以外的事 func is_newer(a: float, b: float) - bool: return a b几点工程建议存档时间戳统一用 UTC 的 Unix 时间戳避免玩家切换时区或系统时区设置导致本地时间比较错乱显示时再通过get_datetime_string_from_unix_time()转成目标格式只做一次方向转换把取时间与格式化显示分开不要在每帧都调用_from_system方法既浪费又容易引入不一致性能敏感循环里优先用字典缺省解析字符串时若不需要星期给get_datetime_dict_from_datetime_string()传weekday false省去昂贵的星期推算精确计时永远用 ticks任何涉及差值的测量帧耗时、音频同步、动画延迟都使用get_ticks_usec()它单调递增、不受用户校时影响详见 the_profiler.rst 与 cpu_optimization.rst 中的官方实践。总结Time 单例使用要点速查格式转换字典get_*_dict_*、字符串get_*_string_*、Unix 时间戳get_unix_time_*三形态之间可双向互转覆盖系统时间与任意给定时刻时区语义转换方法假设输入输出同处一时区不处理 DST、闰秒与Z后缀系统读取方法用utc参数切换本地/UTCget_unix_time_from_system()恒为 UTC两条时间线_from_system系列是用户可调的墙钟只能用于显示时间get_ticks_msec()/get_ticks_usec()是引擎单调时钟专用于耗时测量与同步数据细节月份枚举 1 起始、星期枚举 0 起始空字典转时间戳返回0缺失键按 1970-01-01 补齐字符串中的小数秒被静默忽略迁移Godot 3 中OS的时间 API 已全部由Time单例取代迁移写法见 upgrading_to_godot_4.rst。掌握Time的完整能力后你可以在 Godot 4 中自信地处理从日志时间戳到跨平台存档同步的所有时间需求。赞分享文档教程游戏开发【免费下载链接】godot-docsGodot Engine official documentation项目地址https://gitcode.com/GitHub_Trending/go/godot-docs点击查看免费下载相关推荐Naive UI Time 时间组件完整指南格式化、相对时间、时区与 Unix 时间戳Naive UI Time 时间组件完整指南格式化、相对时间、时区与 Unix 时间戳 Time 是 Naive UI 中一个轻量的时间格式化组件它的定位非前端UI组件Sway 智能合约时间库 std::time 完全指南Duration 时长、UNIX/TAI64 时间戳与链上区块时间Sway 智能合约时间库 std::time 完全指南Duration 时长、UNIX/TAI64 时间戳与链上区块时间 std::time 是 Sway 标编程语言编译器区块链如何用Duckling实现从明天8点到精确时间戳的终极时间解析指南如何用Duckling实现从明天8点到精确时间戳的终极时间解析指南 Duckling是一款强大的语言规则引擎能够将自然语言中的时间表达式如明天8点创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
阅读完成 · 觉得有帮助?
咨询建站