时区的Java时间格式
我正在尝试以以下格式获取日期的输出(时区的Java时间格式,java,datetime,timezone,simpledateformat,datetime-format,Java,Datetime,Timezone,Simpledateformat,Datetime Format,我正在尝试以以下格式获取日期的输出(String): 20170801 123030 美国/洛杉矶 但使用此代码: SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd hhmmss Z", Locale.US); sdf.setTimeZone(TimeZone.getTimeZone("America/Los_Angeles")); System.out.println(sdf.format(new java.util.Date(
String
):
20170801 123030 美国/洛杉矶
但使用此代码:
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd hhmmss Z", Locale.US);
sdf.setTimeZone(TimeZone.getTimeZone("America/Los_Angeles"));
System.out.println(sdf.format(new java.util.Date()));
我得到的输出是(注意区域部分):
20174904 024908-0700
知道怎么修吗?我需要打印”美国/洛杉矶“
而不是”-0700“
看起来不支持您想要的
以下是可能的格式:
z Time zone General time zone Pacific Standard Time; PST; GMT-08:00
Z Time zone RFC 822 time zone -0800
X Time zone ISO 8601 time zone -08; -0800; -08:00
您只需在格式化日期后添加“America/Los_Angeles”:
TimeZone timeZone = TimeZone.getTimeZone("America/Los_Angeles");
DateFormat sdf = new SimpleDateFormat("yyyyMMdd hhmmss", Locale.US);
sdf.setTimeZone(timeZone);
System.out.println(sdf.format(new Date()) + " " + timeZone.getID());
DateFormat sdfWithTimeZone = new SimpleDateFormat("yyyyMMdd hhmmss zzzz", Locale.US);
sdfWithTimeZone.setTimeZone(timeZone);
System.out.println(sdfWithTimeZone.format(new Date()));
输出:
20171004 031611 America/Los_Angeles
20171004 031611 Pacific Daylight Time
如果可以使用Java 8,则可以使用及其符号
V
来显示区域ID:
Instant now = Instant.now();
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyyMMdd hhmmss VV")
.withLocale(Locale.US)
.withZone(ZoneId.of("America/Los_Angeles"));
System.out.println(fmt.format(now));
印刷品:
20171004 032552美国/洛杉矶
请注意,不支持中提到的此标志
如果您从java.util.Date
开始使用,但仍然可以使用java 8,那么您可以首先将其转换为即时
:
Instant now = new java.util.Date().toInstant();
...
正如所指出的,在SimpleDateFormat
中没有内置模式来打印时区ID。但是有一种方法可以覆盖它
首先,使用z
模式创建一个与时区短名称相对应的格式化程序。我不确定语言环境是否对这一点有影响(我知道它会影响长名称,不确定短名称,但无论如何我会保留它)
然后我从格式化程序中获取java.text.DateFormatSymbols
,并覆盖与短名称对应的字符串:
// use "z" (short timezone name)
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd hhmmss z", Locale.US);
sdf.setTimeZone(TimeZone.getTimeZone("America/Los_Angeles"));
// get the java.text.DateFormatSymbols
DateFormatSymbols symbols = sdf.getDateFormatSymbols();
// get the zones names
String[][] zones = symbols.getZoneStrings();
// overwrite zone short names
for (int i = 0; i < zones.length; i++) {
String zoneId = zones[i][0];
if ("America/Los_Angeles".equals(zoneId)) {
zones[i][2] = zoneId; // short name for standard time
zones[i][4] = zoneId; // short name for Daylight Saving Time
}
}
// update the symbols in the formatter
symbols.setZoneStrings(zones);
sdf.setDateFormatSymbols(symbols);
System.out.println(sdf.format(new java.util.Date()));
这些日期是:
2017-10-05T05:04:31.253-07:00[美国/洛杉矶]2017-10-05T21:04:31.253+09:00[亚洲/东京] 现在让我们看看区别。设置格式化程序中的时区。这意味着在格式化时,所有日期都将转换为特定的时区(我刚刚稍微修改了代码,以直接设置区域设置,而不是使用
with locale
,但生成的格式化程序是等效的):
由于在格式化程序中设置了时区,两个日期都将转换为此时区(包括日期和时间值):
20171005 050431美国/洛杉矶20171005 050431美国/洛杉矶 在中时,格式化程序没有设置时区,这意味着它将保留
ZonedDateTime
对象中使用的时区:
// formatter without a timezone set
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyyMMdd hhmmss VV", Locale.US);
// it keeps the timezone set in the date
System.out.println(nowLA.format(fmt)); // 20171005 050431 America/Los_Angeles
System.out.println(nowTokyo.format(fmt)); // 20171005 090431 Asia/Tokyo
现在保留时区(以及日期和时间值):
20171005 050431美国/洛杉矶20171005 090431亚洲/东京 这是一个微妙的区别,你必须选择最适合你的情况的方法。请注意,关于
hh
与hh
的相同问题也适用于这里:变量nowtoko
的值相当于21:04:31(东京的9:04:31PM),但格式为090431
——没有AM/PM指示符,这一次是不明确的,因此在我看来,模式应该使用hh
(因此输出将是210431
)。但这取决于您的决定
您可以查看所有可用模式的详细信息。。小写字母“m”表示分钟为什么不手动删除
Z
和concat名称?您使用的是现在遗留的、麻烦的旧日期时间类,被java.time类取代。嗨,帕蒂,建议的答案对您的需求有帮助吗?在这种情况下,它会很好如果您接受了其中一个。如果不接受,请告诉我们为什么这不起作用,以便我们可以提供额外的帮助。您使用的旧日期时间类现在已经过时,被java.time类取代。我怀疑那些hh
应该是大写的hh
。我认为我们可以假设24小时时钟,因为没有am/pm标记tor.事实上@Patty,请注意上面提到的hh
vshh
问题,以及在格式化程序中设置时区与未按中所述设置时区之间的细微差异。这些差异取决于您的要求。
// set the timezone in the formatter
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyyMMdd hhmmss VV", Locale.US)
// use Los Angeles timezone
.withZone(ZoneId.of("America/Los_Angeles"));
// it converts all dates to Los Angeles timezone
System.out.println(nowLA.format(fmt)); // 20171005 050431 America/Los_Angeles
System.out.println(nowTokyo.format(fmt)); // 20171005 050431 America/Los_Angeles
// formatter without a timezone set
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyyMMdd hhmmss VV", Locale.US);
// it keeps the timezone set in the date
System.out.println(nowLA.format(fmt)); // 20171005 050431 America/Los_Angeles
System.out.println(nowTokyo.format(fmt)); // 20171005 090431 Asia/Tokyo