我有以下代码(简化后专注于问题)。它使用SimpleDateFormat
模式打印时区信息。
你知道为什么z在不同的机器上被区别对待吗?如果有一种方法可以告诉Java在所有机器上统一处理它呢?
这个类在JavaMail中使用,这会导致我们的电子邮件头包含不符合RFC 2822的时间。
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
PDT
输出: Linux (CentOS Linux版本7.5.1804 (核心))/ubuntu14/ 18
GMT-07:00
发布于 2018-09-25 07:40:17
tl;dr
切勿使用Calendar
。请改用java.time类。
OffsetDateTime
.now( ZoneOffset.UTC )
.format( DateTimeFormatter.RFC_1123_DATE_TIME )
Mon,2018年9月24日23:45:21 GMT
要获取特定时区中当前的UTC偏移量,请执行以下操作:
ZoneId
.systemDefault()
.getRules()
.getOffset(
Instant.now()
)
.toString()
-07:00
避免Calendar
您正在使用可怕的旧date-time类,这些类几年前就被java.time取代了。永远不要使用那些遗留类;它们是一个糟糕的烂摊子。
您关于Calendar
行为的特定问题是模拟,因为再也不需要使用该类了。即使在与尚未更新到java.time的旧代码进行互操作时,也可以通过添加到旧类的新方法轻松地在遗留类和现代类之间进行转换。
ZonedDateTime zdt = myGregorianCalendar.toZonedDateTime() ;
…和…
GregorianCalendar gc = GregorianCalendar.from( zdt ) ;
java.time
显然,您需要当前默认时区的当前偏移量。
获取当前默认时区,即ZoneId
。
ZoneId z = ZoneId.systemDefault() ; // Or specify ZoneId.of( "Pacific/Auckland" ) or so on.
询问该时区的rules。
ZoneRules rules = z.getRules() ;
获取该区域在某一时刻的有效偏移量。我们将使用当前时刻,一个Instant
。
Instant now = Instant.now() ;
ZoneOffset offset = rules.getOffset( now ) ;
生成表示该UTC偏移量的文本。
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。
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.Date
、Calendar
和SimpleDateFormat
。
现在在maintenance mode中的项目建议迁移到java.time类。
要了解更多信息,请参阅。和搜索堆栈溢出,以获得许多示例和解释。规范为JSR 310。
您可以直接与数据库交换java.time对象。使用与JDBC 4.2或更高版本兼容的JDBC driver。不需要字符串,也不需要java.sql.*
类。
从哪里获取java.time类?
项目使用额外的类扩展了java.time。这个项目是未来可能添加到java.time中的试验场。您可能会在这里找到一些有用的类,如Interval
、YearWeek
、YearQuarter
和more。
https://stackoverflow.com/questions/52488141
复制相似问题