You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Julia中GlobalEnergyGIS的FixedTimeZone转VariableTimeZone方法错误求助

问题:Julia GlobalEnergyGIS模型运行时的TimeZone类型转换错误

我在使用Julia的GlobalEnergyGIS模型时,遇到了以下错误:

MethodError: Cannot convert an object of type TimeZones.FixedTimeZone to an object of type TimeZones.VariableTimeZone

相关函数代码

function regional_timezone_offsets_Jan1(; gisregion="Europe8", scenarioyear="ssp2_2050", era_year=2018)
    println("
Calculating population-weighted regional time zone offsets...")
    regions, offshoreregions, regionlist, lonrange, latrange = loadregions(gisregion)
    tzindices, tznames = loadtimezones(lonrange, latrange)
    popscale = 1e5
    pop = JLD.load(in_datafolder("population_$scenarioyear.jld"), "population")[lonrange,latrange] ./ popscale   # scale down for better precision
    numreg = length(regionlist)
    numhours = 24*daysinyear(era_year)
    offsets = zeros(numreg)
    population = zeros(numreg)
    zone_maxpop = fill(TimeZone("Europe/London"), numreg)
    updateprogress = Progress(numreg, 1)
    for r = 1:numreg
        reg = (regions .== r)
        regindices = tzindices[reg]
        regpop = pop[reg]
        zoneindices = unique(regindices)
        weightedoffset = 0.0
        zones = TimeZone[]
        pops = Float64[]
        for idx in zoneindices
            tzname = tznames[idx]
            zone = tzname[1:3] == "Etc" ? TimeZone(tzname, TimeZones.Class(:LEGACY)) : TimeZone(tzname)
            push!(zones, zone)
            firsthour = ZonedDateTime(DateTime(era_year,1,1,0), zone)
            hours = firsthour : Hour(1) : firsthour + Hour(numhours-1)
            offset = tzoffset(hours[1])
            localpop = sum(regpop[regindices.==idx])
            push!(pops, localpop)
            weightedoffset += localpop * offset
        end
        _, i = findmax(pops)    # find time zone with the most population
        zone_maxpop[r] = zones[i]
        population[r] = sum(pops) * popscale    # scale up again
        offsets[r] = weightedoffset / sum(pops)
        next!(updateprogress)
    end

    return offsets, zone_maxpop, population
end

报错栈信息

julia> show(err)
1-element ExceptionStack:
MethodError: Cannot `convert` an object of type TimeZones.FixedTimeZone to an object of type TimeZones.VariableTimeZone

Closest candidates are:
  convert(::Type{T}, ::T) where T
   @ Base Base.jl:84

Stacktrace:
 [1] setindex!(A::Vector{TimeZones.VariableTimeZone}, x::TimeZones.FixedTimeZone, i1::Int64)
   @ Base ./array.jl:1021
 [2] regional_timezone_offsets_Jan1(; gisregion::String, scenarioyear::String, era_year::Int64)
   @ GlobalEnergyGIS ~/Documents/MPhil_Energy_Technologies/Dissertation_Project/GlobalEnergyGIS/GlobalEnergyGIS/src/syntheticdemand_inputdata.jl:248
 [3] regional_timezone_offsets_Jan1
   @ ~/Documents/MPhil_Energy_Technologies/Dissertation_Project/GlobalEnergyGIS/GlobalEnergyGIS/src/syntheticdemand_inputdata.jl:216 [inlined]
 [4] buildtrainingdata(; gisregion::String, sspscenario::String, sspyear::Int64, era_year::Int64, numcenters::Int64, mindist::Float64)
   @ GlobalEnergyGIS ~/Documents/MPhil_Energy_Technologies/Dissertation_Project/GlobalEnergyGIS/GlobalEnergyGIS/src/syntheticdemand_inputdata.jl:151
 [5] buildtrainingdata
   @ ~/Documents/MPhil_Energy_Technologies/Dissertation_Project/GlobalEnergyGIS/GlobalEnergyGIS/src/syntheticdemand_inputdata.jl:145 [inlined]
 [6] predictdemand(; variables::Vector{Symbol}, gisregion::String, sspscenario::String, sspyear::Int64, era_year::Int64, numcenters::Int64, mindist::Float64, nrounds::Int64, max_depth::Int64, eta::Float64, subsample::Float64, metrics::Vector{String}, more_xgoptions::@Kwargs{})
   @ GlobalEnergyGIS ~/Documents/MPhil_Energy_Technologies/Dissertation_Project/GlobalEnergyGIS/GlobalEnergyGIS/src/syntheticdemand_training.jl:11
 [7] top-level scope
   @ REPL[17]:1

错误原因

错误触发在zone_maxpop[r] = zones[i]行:
初始化zone_maxpop时用fill(TimeZone("Europe/London"), numreg),而Europe/London属于VariableTimeZone(带夏令时切换的时区);但处理Etc/XXX类时区时,得到的是FixedTimeZone(无夏令时的固定偏移时区)。Julia不允许将FixedTimeZone对象直接存入VariableTimeZone类型的数组,因此抛出类型转换错误。


修复方案

方案一:将数组类型改为抽象的TimeZone

修改zone_maxpop的初始化代码,让数组可以容纳任意TimeZone子类:

# 替换原来的fill(TimeZone("Europe/London"), numreg)
zone_maxpop = Vector{TimeZone}(undef, numreg)
# 或者更简洁的写法
zone_maxpop = TimeZone[]
resize!(zone_maxpop, numreg)

方案二:统一转换为FixedTimeZone(无需夏令时特性时)

如果业务场景不需要时区的夏令时切换逻辑,可将所有时区转为FixedTimeZone类型:
在创建zone对象后添加转换代码:

zone = tzname[1:3] == "Etc" ? TimeZone(tzname, TimeZones.Class(:LEGACY)) : TimeZone(tzname)
# 添加这一行,将时区转换为FixedTimeZone
zone = FixedTimeZone(zone.name, tzoffset(ZonedDateTime(DateTime(era_year,1,1,0), zone)))

内容的提问来源于stack exchange,提问作者user25481963

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 17:27:02