Unity Android不同SDK编译版本UTC偏移不一致问题求助
同一设备运行同版本Unity的Android应用,分别用SDK 33和SDK 30编译,代码逻辑完全相同,但在西班牙夏令时(UTC偏移应为+2)环境下,SDK 33版本转换本地时间到UTC时返回错误的+1偏移,SDK 30版本返回正确的+2偏移。代码用于调度通知的时间转换,已确认设备时区设置正确。
转换代码
private void saveNotification(DateTime selected_day, Serializables.Shedule_data[] shedule_data) { ... TimeSpan tspan = TimeSpan.Parse(shedule_data[i].inicio); DateTime localTime = new DateTime(selected_day.Year, selected_day.Month, selected_day.Day, tspan.Hours, tspan.Minutes, 0, DateTimeKind.Local); DateTime utcTime = TimeZoneInfo.ConvertTimeToUtc(localTime); LogManager.Instance.log($"Saved notification at -> Local({TimeZoneInfo.Local.GetUtcOffset(DateTime.Now)}): {localTime:dd/MM/yyy - HH:mm} | {TimeZoneInfo.Utc.DisplayName}: {utcTime:dd/MM/yyy - HH:mm}"); }
已执行的排查步骤
- 确认设备时区设置为西班牙夏令时(UTC偏移+2)
- 核对两个版本的转换代码,逻辑完全一致
- 多次测试SDK 30版本,结果始终正确
排查及解决建议
对比时区数据细节
在两个版本中分别打印TimeZoneInfo.Local.Id、TimeZoneInfo.Local.BaseUtcOffset,以及针对目标时间localTime而非DateTime.Now获取偏移:TimeZoneInfo.Local.GetUtcOffset(localTime)。SDK 33可能使用了Android 13+更新的时区数据源,导致夏令时规则识别偏差。显式指定时区转换
避免依赖DateTimeKind.Local的隐式处理,直接指定西班牙时区进行转换:TimeSpan tspan = TimeSpan.Parse(shedule_data[i].inicio); DateTime localTime = new DateTime(selected_day.Year, selected_day.Month, selected_day.Day, tspan.Hours, tspan.Minutes, 0); TimeZoneInfo spainZone = TimeZoneInfo.FindSystemTimeZoneById("Romance Standard Time"); DateTime utcTime = TimeZoneInfo.ConvertTimeToUtc(localTime, spainZone);硬编码时区ID可规避系统时区数据源差异带来的问题。
核对.NET运行时版本
检查两个编译版本是否使用相同的.NET运行时(如IL2CPP、.NET Framework)。SDK 33可能触发了不同的运行时行为,导致时区处理逻辑变化。跨时间段测试验证
测试非夏令时时间段(如1月)的转换结果,判断SDK 33版本是夏令时规则识别错误,还是整体时区偏移错误。检查设备时区更新状态
确认设备是否开启时区自动更新,SDK 33可能更依赖系统最新时区数据,若系统时区数据未更新,可能导致夏令时规则失效,可手动更新后重试。
内容的提问来源于stack exchange,提问作者Alejandro Rey Muñoz

