我做了:
GregorianCalendar gc = new GregorianCalendar(Locale.French);
小时数有误,我得到了14:17而不是15:17。
我的第一个想法是夏令时,但我认为GregorianCalendar已经考虑到了这一点。
我的电脑时间设置正确。
我做了:
GregorianCalendar gc = new GregorianCalendar(Locale.French);
小时数有误,我得到了14:17而不是15:17。
我的第一个想法是夏令时,但我认为GregorianCalendar已经考虑到了这一点。
我的电脑时间设置正确。
您使用的构造函数创建了一个具有默认时区的日历(javadoc),这可能不是给定地区的正确时区。至少,这是我从javadoc中读到的。尝试使用不同的构造函数并传递您的TZ。
如评论所述,您混淆了使用Locale
对象和指定时区。Locale与时区没有任何关系,而且Locale不会影响日期时间值的含义。Locale仅影响用于呈现日期时间值的字符串的格式。
在捕获当前时刻时不需要Locale,但我们需要一个时区。
Instant.now().atZone( ZoneId.of( "America/Montreal" ) )
ZonedDateTime.now( ZoneId.of( "America/Montreal" ) )
您正在使用麻烦的旧日期时间类,现在已被java.time类取代。
您的大部分业务逻辑、数据存储和数据交换都应该使用UTC。将UTC视为“唯一真正的时间”。
Instant
类表示以UTC为基准的时间线上的一个时刻,精度为纳秒。
Instant instant = Instant.now();
正如您所了解的那样,您应该始终指定所需/期望的时区。对于任何给定的时刻,世界各地的日期和时间会因时区而异。
请以大陆/地区
的格式指定正确的时区名称。永远不要使用3-4个字母的缩写,例如EST
或IST
,因为它们不是真正的时区,没有标准化,甚至不是唯一的(!)。
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( z );
请注意,时区和语言环境是正交的、完全独立的问题。
这意味着我们可以将任何时区与任何语言环境混合使用。我们可以在时区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 8 及以后版本。这些类替代了旧的 遗留 日期时间类,如 java.util.Date
、Calendar
和 SimpleDateFormat
。
Joda-Time项目现在处于维护模式,建议迁移到java.time类。
了解更多信息,请参阅Oracle教程。并在Stack Overflow上搜索许多示例和解释。规范是JSR 310。
如何获取java.time类?
ThreeTen-Extra项目通过添加额外的类来扩展java.time。该项目是java.time可能未来增加的类的试验场。您可能会在这里找到一些有用的类,例如Interval
, YearWeek
, YearQuarter
和更多。
我不确定你在尝试什么,但是GregorianCalendar(Locale)
始终基于您的默认时区。也许你应该看一下GregorianCalendar(TimeZone zone, Locale aLocale)