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

Windows10下GlassFish与Tomcat创建服务后日期显示为问号问题

问题分析与解决方案

这个问题我之前也碰到过!核心原因就是Windows服务的运行环境和你交互式登录时的Locale(区域设置)不一致,导致Java程序无法正确获取日期格式化所需的Locale资源。

为什么会出现这种差异?

  • 当你直接运行GlassFish/Tomcat(非服务模式)时,程序是在你当前登录用户的会话下运行的,会继承该用户的Locale配置,所以SimpleDateFormat默认使用这个Locale就能正常格式化日期。
  • 但把它们做成Windows服务后,默认会以Local System账户运行,这个账户的Locale设置可能和你登录的用户完全不同,甚至是一个未正确配置的Locale。Java在找不到对应Locale的日期格式化资源时,就会输出??这类占位符,GlassFish日志的????-??-??T??:??:??.???+0530也是同样的道理。
  • 而当你显式传入Locale.XX参数时,Java不再依赖系统环境的Locale,直接使用你指定的Locale资源,所以日期显示就正常了。

几种可行的解决方案

1. 代码层面显式指定Locale(最推荐,不受环境影响)

不管部署环境怎么变,在使用日期格式化类时始终显式指定Locale,彻底避免依赖系统默认Locale。

比如把原来的代码:

String dateInString = new SimpleDateFormat(pattern).format(new Date());
out.println(dateInString);

修改为:

// 根据你的需求指定Locale,比如中文用Locale.CHINA,英文用Locale.US
String dateInString = new SimpleDateFormat(pattern, Locale.CHINA).format(new Date());
out.println(dateInString);

如果你用的是Java 8及以上版本,更推荐使用新的日期时间API,同样显式指定Locale:

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

// ...

DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern, Locale.CHINA);
String dateInString = LocalDateTime.now().format(formatter);
out.println(dateInString);

2. 修改服务的运行账户为你的登录用户

如果不想修改代码,可以让服务使用你平时登录Windows的用户账户运行,这样服务会继承该用户的Locale配置:

  • 按下Win + R,输入services.msc打开服务管理器
  • 找到GlassFish或Tomcat服务,右键选择「属性」
  • 切换到「登录」选项卡,选择「此账户」,输入你的用户名和密码,点击「确定」
  • 重启服务,之后日期格式化和日志显示应该都会恢复正常

3. 修改系统默认Locale(适合必须用Local System账户的场景)

如果必须使用Local System账户运行服务,可以修改系统级的Locale设置:

  • 打开「控制面板」→「区域」→「管理」选项卡
  • 点击「更改系统区域设置」,选择你需要的区域(比如「中文(中国)」)
  • 重启电脑后,服务的Locale会同步这个系统设置,问题即可解决

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:55:17