为何同一Windows环境下不同Shell调用Java/javac默认时区不同?
可能的Shell环境因素
Cygwin的
TZ变量解析兼容性问题
Cygwin的TZ遵循POSIX标准,而Windows原生Java程序依赖系统注册表的时区机制。旧版Cygwin可能存在IANA时区字符串(如America/Toronto)到Windows时区的映射bug,导致Java读取TZ时误识别为UTC,而非预期的东部时间。Shell环境变量的过滤/转换机制
Cygwin启动Windows原生程序时,会对环境变量做格式转换:比如将IANA风格的TZ转换为POSIX格式(如EST5EDT),而Java对POSIX格式TZ的支持不稳定,容易 fallback到UTC。而CMD直接继承Windows系统环境,Java会读取注册表中的时区设置,从而显示东部时间。Bash的locale配置干扰
Bash中LC_TIME等locale变量若被设置为C或POSIX,会覆盖TZ的优先级。此时Java会遵循locale的时区规则,默认使用UTC。而CMD默认使用Windows的locale设置,直接读取系统时区。Bash初始化脚本的隐性修改
检查~/.bashrc、~/.bash_profile或/etc/profile等初始化脚本,可能存在其他工具或脚本强制将TZ临时重置为UTC,且未在启动Java前恢复,导致实际生效的TZ与你查询到的不一致。Cygwin与Windows程序的环境隔离
Cygwin运行Windows原生程序时,会创建隔离的环境上下文,Java可能无法正常读取Windows注册表中的时区配置,只能依赖TZ变量;一旦TZ解析失败,就会默认使用UTC。而CMD中Java直接读取系统注册表,因此显示正确的东部时间。
内容的提问来源于stack exchange,提问作者user2153235

