首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Java SimpleDateFormat在不同的操作系统上以不同的方式解释“z”

Java SimpleDateFormat在不同的操作系统上以不同的方式解释“z”
EN

Stack Overflow用户
提问于 2018-09-25 06:24:43
回答 1查看 281关注 0票数 8

我有以下代码(简化后专注于问题)。它使用SimpleDateFormat模式打印时区信息。

你知道为什么z在不同的机器上被区别对待吗?如果有一种方法可以告诉Java在所有机器上统一处理它呢?

这个类在JavaMail中使用,这会导致我们的电子邮件头包含不符合RFC 2822的时间。

代码语言:javascript
复制
import java.text.SimpleDateFormat;
import java.util.Calendar;

public class DateFormatTest {
    String PATTERN = "z";
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(this.PATTERN);

    public static void main(final String[] args) {
        new DateFormatTest().printTimezone();
    }

    public void printTimezone() {
        System.out.println(this.simpleDateFormat.format(Calendar.getInstance().getTime()));
    }

}

输出: Windows / Mac

代码语言:javascript
复制
PDT

输出: Linux (CentOS Linux版本7.5.1804 (核心))/ubuntu14/ 18

代码语言:javascript
复制
GMT-07:00
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-09-25 07:40:17

tl;dr

切勿使用Calendar。请改用java.time类。

对于RFC 1123 / RFC 822格式的字符串:

代码语言:javascript
复制
OffsetDateTime
.now( ZoneOffset.UTC )
.format( DateTimeFormatter.RFC_1123_DATE_TIME )

Mon,2018年9月24日23:45:21 GMT

要获取特定时区中当前的UTC偏移量,请执行以下操作:

代码语言:javascript
复制
ZoneId
.systemDefault()
.getRules()
.getOffset(
    Instant.now() 
)
.toString()

-07:00

避免Calendar

您正在使用可怕的旧date-time类,这些类几年前就被java.time取代了。永远不要使用那些遗留类;它们是一个糟糕的烂摊子。

您关于Calendar 行为的特定问题是模拟,因为再也不需要使用该类了。即使在与尚未更新到java.time的旧代码进行互操作时,也可以通过添加到旧类的新方法轻松地在遗留类和现代类之间进行转换。

代码语言:javascript
复制
ZonedDateTime zdt = myGregorianCalendar.toZonedDateTime() ;

…和…

代码语言:javascript
复制
GregorianCalendar gc = GregorianCalendar.from( zdt ) ; 

java.time

显然,您需要当前默认时区的当前偏移量。

获取当前默认时区,即ZoneId

代码语言:javascript
复制
ZoneId z = ZoneId.systemDefault() ;  // Or specify ZoneId.of( "Pacific/Auckland" ) or so on.

询问该时区的rules

代码语言:javascript
复制
ZoneRules rules = z.getRules() ;

获取该区域在某一时刻的有效偏移量。我们将使用当前时刻,一个Instant

代码语言:javascript
复制
Instant now = Instant.now() ;
ZoneOffset offset = rules.getOffset( now ) ;

生成表示该UTC偏移量的文本。

代码语言:javascript
复制
String output = "At " + now + " in zone " + z + " the offset is " + offset;

美国/洛杉矶地区2018-09-24T23:38:44.192642Z的

偏移量为-07:00

RFC 1123 / RFC 822

您提到了RFC,但没有指定。也许是RFC 1123 / 822?

java.time中内置了formatter for that

代码语言:javascript
复制
OffsetDateTime nowInUtc = OffsetDateTime.now( ZoneOffset.UTC ) ;
String output = nowInUtc.format( DateTimeFormatter.RFC_1123_DATE_TIME ) ;

Mon,2018年9月24日23:45:21 GMT

ISO 8601

仅供参考,RFC 1123 / RFC 822格式是一种糟糕的格式。它假定是英语。机器很难解析,人类也很难阅读。但我知道您可能需要它来处理过时的旧协议。

只需知道现代协议使用ISO 8601标准格式。在解析/生成字符串时,这些格式在java.time类中默认使用,这很方便。

关于java.time

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

现在在maintenance mode中的项目建议迁移到java.time类。

要了解更多信息,请参阅。和搜索堆栈溢出,以获得许多示例和解释。规范为JSR 310

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

从哪里获取java.time类?

  • ,implementation.
  • Java 、、和更高版本--作为标准Java API的一部分,捆绑的java.time 9添加了一些次要功能,并且在java.time类的捆绑实现的.
  • Later版本中,java.time功能的fixes.
  • Most被向后移植到Java6和7。请参阅.

项目使用额外的类扩展了java.time。这个项目是未来可能添加到java.time中的试验场。您可能会在这里找到一些有用的类,如IntervalYearWeekYearQuartermore

票数 10
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52488141

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档