转换Java时间戳字符串为Java时间戳对象



我有以下时间戳字符串"2021010112:12:12.10:00",我想将其转换为java.time.Instant

通过DateTimeFormatter解析字符串的问题是由于最后4位数字之前没有时区符号。逻辑上是yyyyMMddHH:mm:ss.,10:00是时区偏移量,例如UTC+10:00,但问题是它没有符号。

我如何解析这个字符串到Instant对象?

不是很优雅,但是您可以通过一个点来split输入。这样可以将日期时间部分从偏移量中分离出来,并且可以将所需的(和必需的)符号与值连接起来。

这需要你知道应用哪个标志!

可以写一个方法,输入String和一个符号作为参数。

由于似乎无法解析偏移量的无符号String表示,因此您需要以下内容:

public static void main(String[] args) {
String timestamp = "2021010112:12:12.10:00";
// provide a formatter that parses the datetime (the part before the dot)
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuuMMddHH:mm:ss");
// split the timestamp String by the dot to separate datetime from offset
String[] split = timestamp.split("\.");
// parse the datetime part using the formatter defined above
LocalDateTime ldt = LocalDateTime.parse(split[0], dtf);
// and build up an offset using offset part adding a plus sign
ZoneOffset zoneOffset = ZoneOffset.of("+" + split[1]);
// then create an OffsetDateTime from the LocalDateTime and the ZoneOffset
OffsetDateTime result = OffsetDateTime.of(ldt, zoneOffset);
// finally get an Instant from it
Instant instant = result.toInstant();  // <--- INSTANT HERE
// and print the values
System.out.println(result + " = " + instant.toEpochMilli());
}

这个输出

2021-01-01T12:12:12+10:00 = 1609467132000

解析位置

已经有两个很好的答案了。这是我的建议。

String timestampString = "2021010112:12:12.10:00";

ParsePosition position = new ParsePosition(0);
TemporalAccessor parsed = PARSER.parse(timestampString, position);
LocalDateTime dateTime = LocalDateTime.from(parsed);

String offsetString = timestampString.substring(position.getIndex());
if (Character.isDigit(offsetString.charAt(0))) { // no sign
offsetString = "+" + offsetString;
}
ZoneOffset offset = ZoneOffset.of(offsetString);

Instant timestamp = dateTime.atOffset(offset).toInstant();

System.out.println(timestamp);

输出:

2021 - 01 - 01 - t02:12:12z

缺点是使用TemporalAccessor接口,这是一个我们通常不应该在应用程序代码中使用的低级接口。其优点包括代码接受在偏移量前带和不带符号的字符串,并且我们不需要任何分割操作或正则表达式的其他应用程序。如果UTC偏移量为负,则符号必须在那里,否则我们无法判断。我们再试一下:

String timestampString = "2021010112:12:12.-10:00";

2021 - 01 - 01 - t22:12:12z

我相信ParsePosition类是在java中重用的旧java.text包中唯一的类。我个人觉得很奇怪。

deHaar的答案是正确的。这个答案显示了解决这个问题的一个更简单的方法。

您可以使用regex,(.)(d{1,2}:d{1,2}).(regex中的组#1)替换为+(regex中的组#2)之前的时区偏移部分

演示:

import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
String strDateTime = "2021010112:12:12.10:00";
strDateTime = strDateTime.replaceFirst("(\.)(\d{1,2}:\d{1,2})", "+$2");
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuuMMddHH:mm:ssXXX", Locale.ENGLISH);
Instant instant = OffsetDateTime.parse(strDateTime, dtf).toInstant();
System.out.println(instant);
}
}

输出:

2021-01-01T02:12:12Z
<<p>

在线演示/kbd>或者,您可以使用regex、.(d{1,2}:d{1,2})和在组#1前面加上+符号。请注意,DateTimeFormatter需要进行相应的调整。

import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
String strDateTime = "2021010112:12:12.10:00";
strDateTime = strDateTime.replaceFirst("\.(\d{1,2}:\d{1,2})", ".+$1");
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuuMMddHH:mm:ss.XXX", Locale.ENGLISH);
Instant instant = OffsetDateTime.parse(strDateTime, dtf).toInstant();
System.out.println(instant);
}
}
<<p>

在线演示/kbd>使用这种替代解决方案的好处如下Ole v.v.的评论所述:

只是猜测,如果是a,可能会出现一个负号负UTC偏移量。如果是这样,也许可以使用strDateTime.replaceFirst("\.(\d{1,2}:\d{1,2})", ".+$1")获取2021010112:12:12。+10:00在正偏移情况下,之后可以解析正负偏移量(和零)。

最新更新