Windows环境下Godot 3.6如何计算指定日期的ISO周数?
问题:Godot 3.6(Windows)下ISO周数计算优化及年月周数列表获取
现状与痛点
- 需实现两个核心功能:计算指定日期的ISO周数、获取指定年月包含的所有ISO周数
- 当前通过调用Windows PowerShell实现日期转ISO周数,结果准确但多次调用时执行效率极低
- 已尝试的无效途径:
- Godot内置
Time类无直接计算ISO周数的方法 - Ivan Skodje的Godot 3.2.3日历按钮插件无相关实现
- ChatGPT给出的方案均不适配Godot 3.6版本
- Godot内置
现有PowerShell调用代码
# Executes the [ script ] in Windows PowerShell static func execute(script, open_console: bool = false, freeze_loop: bool = true) -> Array: if OS.get_name() != "Windows": return [] var output: Array = [] var arguments: PoolStringArray = PoolStringArray([]) match typeof(script): TYPE_STRING: arguments.append(script as String) TYPE_ARRAY, TYPE_STRING_ARRAY: for line in script: arguments.append("\n%s" % line) _: return [] OS.execute("powershell.exe", arguments, freeze_loop, output, false, open_console) return output # Returns the ISO week number of the specified date static func get_iso_week(day: int, month: int, year: int) -> int: var script: PoolStringArray = PoolStringArray([ "$date = [DateTime] '%d-%d-%d'" % [year, month, day], ("(Get-Culture).Calendar.GetWeekOfYear(($date).AddDays(-[Int]" + "(($date).AddDays(-1)).DayOfWeek+3), 2, 1)") ]) var result: Array = execute(script) if result.empty(): return 0 return result[0].to_int()
纯GDScript解决方案
1. 直接计算ISO周数(替代PowerShell调用,大幅提升速度)
基于ISO 8601规则(每周从周一开始,第1周为包含当年第一个周四的周),纯GDScript实现无需外部进程调用:
# 计算指定日期的ISO周数(兼容Godot 3.6) static func get_iso_week_gd(day: int, month: int, year: int) -> int: # 将日期转换为Unix时间戳(秒) var timestamp = Time.get_timestamp_from_datetime({"year": year, "month": month, "day": day}) if timestamp == -1: return 0 # 转换Godot星期格式为ISO标准:Godot周日=0 → ISO周日=7,其余周一到周六对应1-6 var weekday = Time.get_day_of_week(timestamp) weekday = weekday if weekday != 0 else 7 # 计算当前日期所在周的周四时间戳(ISO周的判定基准) var thursday_timestamp = timestamp + (4 - weekday) * 86400 # 获取周四所在年份及该年1月1日的时间戳 var thursday_year = Time.get_datetime_from_timestamp(thursday_timestamp)["year"] var year_start_timestamp = Time.get_timestamp_from_datetime({"year": thursday_year, "month": 1, "day": 1}) # 计算周数:天数差除以7后加1(从第1周开始计数) var days_diff = (thursday_timestamp - year_start_timestamp) / 86400 return int(days_diff / 7) + 1
2. 获取指定年月包含的所有ISO周数
遍历当月所有日期,计算周数并去重,返回有序周数列表:
# 获取指定年月包含的所有ISO周数 static func get_iso_weeks_of_month(year: int, month: int) -> Array: var week_set = {} # 获取当月总天数 var days_in_month = Time.get_days_in_month(year, month) if days_in_month == 0: return [] # 遍历每一天计算周数,用字典去重 for day in range(1, days_in_month + 1): var week_num = get_iso_week_gd(day, month, year) if week_num > 0: week_set[week_num] = true # 转换为有序数组返回 var week_list = [] for week in week_set: week_list.append(week) week_list.sort() return week_list
使用说明
get_iso_week_gd可完全替代原get_iso_week方法,无外部进程开销,多次调用时效率提升明显get_iso_weeks_of_month传入年、月参数,直接返回该月覆盖的所有ISO周数有序数组
内容的提问来源于stack exchange,提问作者KanaszM
相关产品推荐
相关产品推荐

