简单日期格式没有 Java 中的时区偏移量 (GMT+00:00) 用于自定义时区避免 3-4 个字母的区域代码避免设置默认时区java.time关于 java.time

2022-09-04 02:54:33

是否可以在 Java 中使用 SimpleDateFormat 类来设置日期时间的格式,以给出日期的时区部分,而不在其后显示 +0000。

编辑

我们正在更改Java中的默认时区,如下所示:

SimpleTimeZone tz = new SimpleTimeZone(0, "Out Timezone");        
TimeZone.setDefault(tz);

不幸的是,我无法删除此代码。我会冒险猜测整个系统停止工作。我认为最初的作者将此用于解决有朝一日的节光问题。

考虑到这一点,我想将日期格式化为:

2011-12-27 09:00 GMT

2011-12-27 09:00 BST

我只能让SimpleDateFormat输出为:

2011-12-27 09:00:00 GMT+00:00

它使用格式字符串 yyyy-MM-dd HH:mm:ss z

我无法在任何地方看到简单时区对冬季时间(GMT)ID或夏令时ID(BST)有任何引用。


答案 1

这个问题和答案现在已经过时了。它们使用旧的日期时间类,这些类被 Java 8 及更高版本中内置的 java.time 框架所过时。旧的课程设计拙劣,令人困惑,麻烦;避免它们

避免 3-4 个字母的区域代码

避免使用 3-4 个字母的代码,例如 .它们既不标准化,也不是唯一的。它们实际上并不代表时区。它们为夏令时(DST)的问题增添了更多的混乱。BST

相反,请使用正确的时区。大多数是欧洲/伦敦等格式。continent/region

避免设置默认时区

调用java.util.TimeZone.setDefault应该只在最极端的情况下进行。此调用在运行时会立即影响在 JVM 内所有应用的所有线程中运行的所有代码。

相反,在所有日期时间代码中,指定所需/预期的时区。如果省略,Java 会通过隐式依赖 JVM 的当前缺省时区来回退。如上所述,此默认值可以在运行时的任何时刻更改!相反,请显式指定。如果您将所需/预期的时区指定为常规传递的参数,则当前的默认时区是没有意义的,无关紧要的。

java.time

java.time 框架内置于 Java 8 及更高版本中。请参阅教程。由 JSR 310 定义。灵感来自非常成功的Joda-Time图书馆。

Instant

An 是 UTC 时间轴上的一个时刻。Instant

下面的示例演示了 java.time 类在默认情况下如何解析/生成字符串(如果采用标准 ISO 8601 格式),而无需指定解析模式。使用类指定其他非标准模式。DateTimeFormatter

Instant instant = Instant.parse( "2011-12-27T09:00:00Z" );

ZonedDateTime

根据需要应用时区,生成 ZonedDateTime

ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( zoneId );

生成字符串

您可以使用 .您可以指定自定义模式。或者,正如我所建议的那样,让java.time为您本地化。DateTimeFormatter

DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.MEDIUM );

最好指定所需/预期的区域设置,原因与时区相同...JVM 的当前缺省值可以随时由在 JVM 中运行的任何应用程序的任何线程中的任何代码更改。它决定了(a)用于日和月名称的人类语言,以及(b)文化规范,如逗号与句点,以及月份,日或年的顺序。Locale

formatter = formatter.withLocale( Locale.CANADA_FRENCH );
String output = zdt.format( formatter );

关于 java.time

java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧日期时间类,如java.util.DateCalendarSimpleDateFormat

Joda-Time 项目现在处于维护模式,建议迁移到 java.time 类。

要了解更多信息,请参阅 Oracle 教程。搜索 Stack Overflow 以获取许多示例和解释。规格是JSR 310

您可以直接与数据库交换 java.time 对象。使用符合 JDBC 4.2 或更高版本的 JDBC 驱动程序。不需要字符串,不需要类。java.sql.*

从哪里获取 java.time 类?

ThreeTen-Extra 项目通过其他类扩展了 java.time。这个项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如IntervalYearWeekYearQuarter


答案 2

我认为您正在使用正确的模式来满足您的要求,但是JDK不知道您的时区名称,因此它切换到使用GMT偏移值

当我使用您的模式格式化日期时,我得到“GMT”作为时区部分。

能给你什么?对我来说,我得到了“格林威治标准时间”。TimeZone.getDefault().getDisplayName()


推荐