Julia中GlobalEnergyGIS的FixedTimeZone转VariableTimeZone方法错误求助
问题:Julia GlobalEnergyGIS模型运行时的TimeZone类型转换错误
我在使用Julia的GlobalEnergyGIS模型时,遇到了以下错误:
MethodError: Cannot
convertan 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
相关产品推荐
相关产品推荐

