Java GregorianCalendar 时间偏移一个小时

4

我做了:

GregorianCalendar gc = new GregorianCalendar(Locale.French);

小时数有误,我得到了14:17而不是15:17。

我的第一个想法是夏令时,但我认为GregorianCalendar已经考虑到了这一点。

我的电脑时间设置正确。


我的错,我忘记了我必须使用时区而不是语言环境。 - jack
2
实际上,您需要使用TimeZone和Locale。否则,如果您的应用程序在具有与您不同的默认区域设置的系统上安装,则可能会严重破坏。 - sleske
3个回答

2

您使用的构造函数创建了一个具有默认时区的日历(javadoc),这可能不是给定地区的正确时区。至少,这是我从javadoc中读到的。尝试使用不同的构造函数并传递您的TZ。


我确认:“至少,这是我阅读Javadoc的方式。”-- 这就是我阅读源代码的方式;-) - Ralph

1

简述

如评论所述,您混淆了使用Locale对象和指定时区。Locale与时区没有任何关系,而且Locale不会影响日期时间值的含义。Locale仅影响用于呈现日期时间值的字符串的格式。

在捕获当前时刻时不需要Locale,但我们需要一个时区。

Instant.now().atZone( ZoneId.of( "America/Montreal" ) )

"…或者更短的版本…。"
ZonedDateTime.now( ZoneId.of( "America/Montreal" ) )

java.time

您正在使用麻烦的旧日期时间类,现在已被java.time类取代。

使用UTC

您的大部分业务逻辑、数据存储和数据交换都应该使用UTC。将UTC视为“唯一真正的时间”。

Instant类表示以UTC为基准的时间线上的一个时刻,精度为纳秒

Instant instant = Instant.now();

指定时区

正如您所了解的那样,您应该始终指定所需/期望的时区。对于任何给定的时刻,世界各地的日期和时间会因时区而异。

请以大陆/地区的格式指定正确的时区名称。永远不要使用3-4个字母的缩写,例如ESTIST,因为它们不是真正的时区,没有标准化,甚至不是唯一的(!)。

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

指定语言环境

请注意,时区和语言环境是正交的、完全独立的问题。

  • 时区决定日期时间的含义,即我们如何查看它的挂钟时间
  • 语言环境确定(a)翻译星期几、月份等名称的人类语言,以及(b)决定缩写、大写、标点等文化规范。

这意味着我们可以将任何时区与任何语言环境混合使用。我们可以在时区Europe/Paris中使用Locale.KOREA的语言环境来表示日期时间。或者在时区Pacific/Auckland中使用Locale.CANADA_FRENCH的语言环境。

因此,语言环境只影响日期时间的呈现方式,即我们如何生成日期时间的字符串表示形式。

您可以指定自定义格式模式来生成字符串。但最好让java.time自动本地化。

Locale l = Locale.CANADA_FRENCH ; 
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.FULL )
                                       .withLocale( l );
String output = zdt.format( f );

关于 java.time

java.time 框架内置于 Java 8 及以后版本。这些类替代了旧的 遗留 日期时间类,如 java.util.DateCalendarSimpleDateFormat

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

了解更多信息,请参阅Oracle教程。并在Stack Overflow上搜索许多示例和解释。规范是JSR 310

如何获取java.time类?

ThreeTen-Extra项目通过添加额外的类来扩展java.time。该项目是java.time可能未来增加的类的试验场。您可能会在这里找到一些有用的类,例如Interval, YearWeek, YearQuarter更多


0

我不确定你在尝试什么,但是GregorianCalendar(Locale)始终基于您的默认时区。也许你应该看一下GregorianCalendar(TimeZone zone, Locale aLocale)


正如我在第一条评论中所说,我确实交换了这两个。 - jack

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接