ZonedDateTime 格式显示当前时间,偏移量已经包含
ZonedDateTime format to display current time with offset already included
我一直在寻找这个答案,但我可能弄错了如何实现它。我有一个 ZonedDateTime 变量,目前如果我要打印它,它将打印例如 2017-12-03T10:15:30+01:00。有没有办法打印已经添加或减去偏移量的时间?例如我想看看上面的例子 16:30。感谢您的帮助!
看看这个:
public Date parseDateTime(String input) throws java.text.ParseException {
//NOTE: SimpleDateFormat uses GMT[-+]hh:mm for the TZ which breaks
//things a bit. Before we go on we have to repair this.
SimpleDateFormat df = new SimpleDateFormat( "yyyy-MM-dd'T'HH:mm:ssz" );
//this is zero time so we need to add that TZ indicator for
if ( input.endsWith( "Z" ) ) {
input = input.substring( 0, input.length() - 1) + "GMT-00:00";
} else {
int inset = 6;
String s0 = input.substring( 0, input.length() - inset );
String s1 = input.substring( input.length() - inset, input.length() );
input = s0 + "GMT" + s1;
}
return df.parse( input );
}
只需稍作改动即可满足您的需要。你应该能够毫不费力地做到这一点。然后在你有 Date 对象之后你添加你想要的偏移量:
int myNumHours = 4; //Any number of hours you want
myDateObject.add(Calendar.HOUR,myNumHours);
//Adds myNumHours to the Hour slot and processes all carrys if needed be.
现在打印它:
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String myDateString = df.format(myDateObject);
//Now just use your myDateString wherever you want.
tl;dr
yourZonedDateTime.atZone(ZoneOffset.UTC).withZoneSameInstant(ZoneId.systemDefault())
或者在我的情况下:
serverSeconds.toLocalDateTime(ZonedDateTime.now().offset) // extension below
fun Long.toLocalDateTime(zoneOffset: ZoneOffset = ZoneOffset.UTC): LocalDateTime {
return LocalDateTime.ofEpochSecond(this / 1000L, 0, zoneOffset)
}
历史
我在尝试正确格式化从服务器收到的 date-time 时偶然发现了这个问题。我做了这些简单的步骤:
- 服务器给了我这个:
1597752329121
,这是 date-time 秒。
- 将它转换为 LocalDateTime 给了我这个:
2020-08-18T12:05:29
.
- 将它转换为 ZonedDateTime 给了我这个:
2020-08-18T12:05:29+03:00[Europe/Kiev]
这很完美,因为我需要像 15:05, 18 August 2020
一样显示它,简单吧?但是以任何方式格式化它都在嘲笑我 12:05, 18 August 2020
。那么蠢。我开始搜索我做错了什么,结果只找到“聪明”的评论,比如“时间已经在给定的时区内”。你应该只得到它。
但是如果 ZonedDateTime 以任何方式给你 12:05 而不是 15:05 怎么可能?!
无论如何,我终于找到了这个答案 (),它实际上并没有解决我的问题,但给出了一些关于如何解决它的想法。所以最后我试过了:
val localDate = serverSeconds.toLocalDateTime() //an extension, see below
val zonedUTC = localDate.atZone(ZoneOffset.UTC)
val zoned = zonedUTC.withZoneSameInstant(ZoneId.systemDefault())
fun Long.toLocalDateTime(): LocalDateTime {
return LocalDateTime.ofEpochSecond(this / 1000L, 0, ZoneOffset.UTC)
}
最后格式化 zoned
给了我所需的 15:05, 18 August 2020
。
我将其改进为您可以在上面 tl;dr.
中看到的代码
ZonedDateTime#withZoneSameInstant
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
public class Main {
public static void main(String[] args) {
String dateTimeStr = "2017-12-03T10:15:30+01:00";
ZonedDateTime zdtGiven = ZonedDateTime.parse(dateTimeStr);
System.out.println(zdtGiven);
// Date-time adjusted with Zone-Offset (i.e. date-time at UTC)
ZonedDateTime zdtAtUTC = zdtGiven.withZoneSameInstant(ZoneId.of("Etc/UTC"));
System.out.println(zdtAtUTC);
// Alternatively,
OffsetDateTime odtAtUTC = zdtGiven.toOffsetDateTime().withOffsetSameInstant(ZoneOffset.UTC);
System.out.println(odtAtUTC);
// Custom format
String formattedDateTimeStr = zdtAtUTC.format(DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss"));
System.out.println(formattedDateTimeStr);
}
}
输出:
2017-12-03T10:15:30+01:00
2017-12-03T09:15:30Z[Etc/UTC]
2017-12-03T09:15:30Z
2017-12-03T09:15:30
你理解上的差距:
date-time字符串中的+01:00
,2017-12-03T10:15:30+01:00
表示字符串中的日期&时间已经调整,在日期&上加上+01:00
小时时间 UTC
。这意味着如果你想从中删除 +01:00
,需要从 2017-12-03T10:15:30
中减去 +01:00
小时,即它将变成 2017-12-03T09:15:30
代表 [=16] 的日期和时间=].
我一直在寻找这个答案,但我可能弄错了如何实现它。我有一个 ZonedDateTime 变量,目前如果我要打印它,它将打印例如 2017-12-03T10:15:30+01:00。有没有办法打印已经添加或减去偏移量的时间?例如我想看看上面的例子 16:30。感谢您的帮助!
看看这个:
public Date parseDateTime(String input) throws java.text.ParseException {
//NOTE: SimpleDateFormat uses GMT[-+]hh:mm for the TZ which breaks
//things a bit. Before we go on we have to repair this.
SimpleDateFormat df = new SimpleDateFormat( "yyyy-MM-dd'T'HH:mm:ssz" );
//this is zero time so we need to add that TZ indicator for
if ( input.endsWith( "Z" ) ) {
input = input.substring( 0, input.length() - 1) + "GMT-00:00";
} else {
int inset = 6;
String s0 = input.substring( 0, input.length() - inset );
String s1 = input.substring( input.length() - inset, input.length() );
input = s0 + "GMT" + s1;
}
return df.parse( input );
}
只需稍作改动即可满足您的需要。你应该能够毫不费力地做到这一点。然后在你有 Date 对象之后你添加你想要的偏移量:
int myNumHours = 4; //Any number of hours you want
myDateObject.add(Calendar.HOUR,myNumHours);
//Adds myNumHours to the Hour slot and processes all carrys if needed be.
现在打印它:
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String myDateString = df.format(myDateObject);
//Now just use your myDateString wherever you want.
tl;dr
yourZonedDateTime.atZone(ZoneOffset.UTC).withZoneSameInstant(ZoneId.systemDefault())
或者在我的情况下:
serverSeconds.toLocalDateTime(ZonedDateTime.now().offset) // extension below
fun Long.toLocalDateTime(zoneOffset: ZoneOffset = ZoneOffset.UTC): LocalDateTime {
return LocalDateTime.ofEpochSecond(this / 1000L, 0, zoneOffset)
}
历史
我在尝试正确格式化从服务器收到的 date-time 时偶然发现了这个问题。我做了这些简单的步骤:
- 服务器给了我这个:
1597752329121
,这是 date-time 秒。 - 将它转换为 LocalDateTime 给了我这个:
2020-08-18T12:05:29
. - 将它转换为 ZonedDateTime 给了我这个:
2020-08-18T12:05:29+03:00[Europe/Kiev]
这很完美,因为我需要像 15:05, 18 August 2020
一样显示它,简单吧?但是以任何方式格式化它都在嘲笑我 12:05, 18 August 2020
。那么蠢。我开始搜索我做错了什么,结果只找到“聪明”的评论,比如“时间已经在给定的时区内”。你应该只得到它。
但是如果 ZonedDateTime 以任何方式给你 12:05 而不是 15:05 怎么可能?!
无论如何,我终于找到了这个答案 (),它实际上并没有解决我的问题,但给出了一些关于如何解决它的想法。所以最后我试过了:
val localDate = serverSeconds.toLocalDateTime() //an extension, see below
val zonedUTC = localDate.atZone(ZoneOffset.UTC)
val zoned = zonedUTC.withZoneSameInstant(ZoneId.systemDefault())
fun Long.toLocalDateTime(): LocalDateTime {
return LocalDateTime.ofEpochSecond(this / 1000L, 0, ZoneOffset.UTC)
}
最后格式化 zoned
给了我所需的 15:05, 18 August 2020
。
我将其改进为您可以在上面 tl;dr.
ZonedDateTime#withZoneSameInstant
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
public class Main {
public static void main(String[] args) {
String dateTimeStr = "2017-12-03T10:15:30+01:00";
ZonedDateTime zdtGiven = ZonedDateTime.parse(dateTimeStr);
System.out.println(zdtGiven);
// Date-time adjusted with Zone-Offset (i.e. date-time at UTC)
ZonedDateTime zdtAtUTC = zdtGiven.withZoneSameInstant(ZoneId.of("Etc/UTC"));
System.out.println(zdtAtUTC);
// Alternatively,
OffsetDateTime odtAtUTC = zdtGiven.toOffsetDateTime().withOffsetSameInstant(ZoneOffset.UTC);
System.out.println(odtAtUTC);
// Custom format
String formattedDateTimeStr = zdtAtUTC.format(DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss"));
System.out.println(formattedDateTimeStr);
}
}
输出:
2017-12-03T10:15:30+01:00
2017-12-03T09:15:30Z[Etc/UTC]
2017-12-03T09:15:30Z
2017-12-03T09:15:30
你理解上的差距:
date-time字符串中的+01:00
,2017-12-03T10:15:30+01:00
表示字符串中的日期&时间已经调整,在日期&上加上+01:00
小时时间 UTC
。这意味着如果你想从中删除 +01:00
,需要从 2017-12-03T10:15:30
中减去 +01:00
小时,即它将变成 2017-12-03T09:15:30
代表 [=16] 的日期和时间=].