改了区域设置后powershell或c#仍显示英文日期,因程序默认继承启动时线程cultureinfo而非实时用户设置;excel text函数受安装语言限制,非系统区域;winforms控件需清缓存并预设线程culture。
windows 系统的日期格式和区域语言设置不是纯界面选项,改了控制面板里的“区域”设置,get-date、tostring()、excel 公式、甚至某些.net 应用仍可能不生效——根本原因是 windows 用两套机制管理:用户级区域策略 + 系统级 lcid / unicode 本地化环境,且部分程序会绕过用户设置直接读注册表或继承父进程 culture。
为什么改了“区域设置”后 PowerShell 或 C# 代码还是显示英文日期?
PowerShell 默认使用当前线程的 CultureInfo,而该 culture 在启动时继承自系统默认(非当前用户设置),尤其在非交互式会话(如计划任务、VS Code 终端重启后)容易卡在 en-US。C# 程序若未显式指定 culture,也会 fallback 到 Thread.CurrentThread.CurrentCulture,它不一定同步控制面板改动。
- 检查当前 culture:
[System.Globalization.CultureInfo]::CurrentCulture.Name(PowerShell) - 临时覆盖(仅当前会话):
[System.Threading.Thread]::CurrentThread.CurrentCulture = [System.Globalization.CultureInfo]::GetCultureInfo("zh-CN") - 永久生效需改注册表键
HKEY_CURRENT_USER\Control Panel\International下的sShortDate、sLongDate、LocaleName,并注销重登 - 注意:.NET 6+ 默认启用
DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=false才支持非 invariant culture,否则强制走英文
如何让 Excel 公式(如 TEXT(NOW(),"yyyy年m月d日"))按中文习惯显示?
Excel 的日期格式字符串解析依赖于工作簿所在系统的 Application.International 设置,而非单元格语言。即使系统设为中文,若 Excel 安装包是英文版,TEXT() 函数仍按英文 culture 解析月份/星期名,导致显示 “January” 而非 “一月”。
- 验证方式:在 Excel 中输入
=TEXT(TODAY(),"dddd"),看返回英文还是中文 - 解决路径一(推荐):重装中文语言包版 Excel,或在文件 > 选项 > 语言 中添加并设为“编辑语言”首选项
- 解决路径二(兼容旧版):避免用
"yyyy年m月d日"这类含中文字符的格式串,改用TEXT(NOW(),"yyyy/m/d")+ 单元格自定义格式yyyy"年"m"月"d"日" - 关键点:单元格自定义格式(Format Cells → Number → Custom)走的是 OS 区域设置,不受 Excel 安装语言限制
修改注册表后日期控件(如 WinForms DateTimePicker)仍不更新怎么办?
WinForms 的 DateTimePicker 默认使用 Control.DefaultFont 和 CultureInfo.CurrentCulture 渲染,但某些老版本 .NET Framework(如 4.5)存在缓存 bug:即使注册表已改,控件首次加载仍读取旧 LCID,尤其在多显示器或远程桌面环境下更明显。
- 强制刷新 culture 缓存:
System.Globalization.CultureInfo.ClearCachedData()(需在 Application.Run() 前调用) - 确保控件初始化前设置线程 culture:
Thread.CurrentThread.CurrentCulture = new CultureInfo("zh-CN"); - 注册表必须同时修改两个位置:
HKEY_CURRENT_USER\Control Panel\International(用户级)和HKEY_USERS\.DEFAULT\Control Panel\International(默认用户,影响服务类进程) - 改完注册表后,务必执行
control intl.cpl打开区域设置面板,点一次“其他设置…”再点“确定”——这会触发系统重载所有国际化资源
真正起效的临界点往往不在“改哪里”,而在“谁在读、何时读、从哪读”。比如一个后台服务进程可能永远看不到你刚在控制面板里点的“中文(简体)”,因为它启动时就读了一次注册表,之后就缓存了。别只盯着界面改,得盯住具体程序的加载时机和 culture 继承链。










