在以下代码段中,我想更改String.format()
long mls = System.currentTimeMillis();
String time = String.format("%tT %tZ", mls, mls);
System.out.println("TIME: " + time + " \n");
答案 0 :(得分:3)
如果您查看javadoc,您会看到Z
模式使用您的JVM default timezone:
'Z'表示时区缩写的字符串。此值将根据夏令时的需要进行调整。对于 long ,Long和Date,使用的时区是此Java虚拟机实例的默认时区。 Formatter的语言环境将取代参数的语言环境(如果有的话)。
因此,最简单的方法是使用java.util.TimeZone
类更改默认时区。一些随机时区的示例:
TimeZone.setDefault(TimeZone.getTimeZone("Europe/London"));
long mls = System.currentTimeMillis();
String time = String.format("%tT %tZ", mls, mls);
System.out.println("TIME: " + time + " \n");
输出:
时间:英国夏令时14:03:54
我认为这不是格式化日期的最佳方式,特别是因为它取决于系统的默认时区(可以在运行时更改并破坏您的代码),并且它使用旧的API({{1} } class)。
现在,Java有了一个新的API,可以让事情变得更容易。
如果您使用的是 Java 8 ,请考虑使用new java.time API。它更容易,less bugged and less error-prone than the old APIs。
如果您使用的是 Java< = 7 ,则可以使用ThreeTen Backport,这是Java 8新日期/时间类的绝佳后端。对于 Android ,有ThreeTenABP(更多关于如何使用它here)。
以下代码适用于两者。
唯一的区别是包名称(在Java 8中为TimeZone
,在ThreeTen Backport(或Android的ThreeTenABP)中为java.time
),但类和方法名称是相同的
如您只想要时间(小时/分钟/秒),您可以使用org.threeten.bp
类和LocalTime
来自定义输出格式。我还使用了DateTimeFormatter
类来指定时区:
ZoneId
输出结果为:
14时09分22秒
请注意,我使用// get current time in London
LocalTime now = LocalTime.now(ZoneId.of("Europe/London"));
// formatter for HH:mm:ss output
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("HH:mm:ss");
System.out.println(fmt.format(now)); // 14:09:22
作为时区。更喜欢使用这些长名称,因为短名称(如Europe/London
或CST
)是ambiguous and not standard。
您可以使用IST
获取所有可用时区的列表。
如果要输出时区短名称(如模式ZoneId.getAvailableZoneIds()
那样),则必须使用%tZ
类,因为ZonedDateTime
没有时区信息它:
LocalTime
在这种情况下,输出将是:
14:09:22 BST
您可以查看DateTimeFormatter
javadoc以查看所有可能的格式。
答案 1 :(得分:3)
在Java中使用时区格式化时间的方法有很多种,String.format()
是最不灵活的。
下面的所有6条建议都假设您有一个long
毫秒值(mls
),并且需要格式化该时间。所有6条建议的输出都是相同的。
如果坚持使用String.format()
,您可以通过各种方式控制时区:
由于long
,Long
或java.util.Date
参数将使用JVM的默认时区,您可以使用TimeZone.setDefault(TimeZone zone)
进行更改,但是通常是一个坏主意,所以我强烈反对你这样做。
由于Calendar
参数具有时区,因此您可以更改long
毫秒参数以使用该参数:
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("Pacific/Honolulu"));
cal.setTimeInMillis(mls);
String time = String.format("%tT %tZ", cal, cal);
在Java 8中,您还可以使用新的java.time
对象:
ZonedDateTime zdt = Instant.ofEpochMilli(mls).atZone(ZoneId.of("Pacific/Honolulu"));
String time = String.format("%tT %tZ", zdt, zdt);
如果您不必使用String.format()
,则应在Java 8中使用新的java.time
对象。如果在Java 6或7上,您可以添加ThreeTen Backport jar:< / p>
使用ZonedDateTime
指定时区:
ZonedDateTime zdt = Instant.ofEpochMilli(mls).atZone(ZoneId.of("Pacific/Honolulu"));
String time = zdt.format(DateTimeFormatter.ofPattern("HH:mm:ss z"));
在DateTimeFormatter
中指定时区:
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("HH:mm:ss z")
.withZone(ZoneId.of("Pacific/Honolulu"));
String time = fmt.format(Instant.ofEpochMilli(mls));
如果您使用的是Java 8之前的版本,并且不想为ThreeTen Backport添加额外的jar,则可以执行以下操作:
SimpleDateFormat fmt = new SimpleDateFormat("HH:mm:ss z");
fmt.setTimeZone(TimeZone.getTimeZone("Pacific/Honolulu"));
String time = fmt.format(mls);
注意:上面的所有代码都使用了檀香山时间,因为这是我想要所在的时区。
答案 2 :(得分:1)
Formatter
类,String.format()
和其他人使用的格式字符串接受日期和时间的丰富类型。例如:
ZonedDateTime zdt = ZonedDateTime.now(ZoneId.of("Europe/Lisbon"));
String time = String.format("%tT %<tZ", zdt);
System.out.println("TIME: " + time + " \n");
输出:
TIME: 18:33:05 WEST
我认为这是西欧夏令时的西部。
并不是说你真的想要输出四个字母的时区缩写,现在我们就是这样。这些缩写词往往含糊不清,不规范。对于时区,大写Z
我更倾向于使用小写z
作为UTC的偏移量。他们永远不会模棱两可。不幸的是,欧洲/里斯本这样的长时区名称似乎不是一个选择。为此,您可以使用DateTimeFormatter
。
来自文档:“日期/时间 - 可能会应用于能够对日期或时间进行编码的Java类型:long
,Long
,{{1 }},Calendar
和Date
“。最后一个是由大多数现代日期和时间类实现的界面,包括TemporalAccessor
,DayOfWeek
,HijrahDate
,HijrahEra
,Instant
,{{1} },IsoEra
,JapaneseDate
,JapaneseEra
,LocalDate
,LocalDateTime
,LocalTime
,MinguoDate
,MinguoEra
, Month
,MonthDay
,OffsetDateTime
,OffsetTime
,ThaiBuddhistDate
,ThaiBuddhistEra
,Year
和YearMonth
。
我在格式字符串中使用ZonedDateTime
再次使用相同的参数,因此我不必将ZoneOffset
两次传递给<
。