将 java 时间戳字符串转换为 java 时间戳对象
convert java timestamp string to java timestamp object
我有以下时间戳字符串 "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
是正确的。此答案显示了解决此问题的更简单方法。
您可以使用 regex、(\.)(\d{1,2}:\d{1,2})
将时区偏移部分(正则表达式中的组#2)之前的 .
(正则表达式中的组#1)替换为+
.
演示:
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})", "+");
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
或者,您可以使用 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})", ".+");
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuuMMddHH:mm:ss.XXX", Locale.ENGLISH);
Instant instant = OffsetDateTime.parse(strDateTime, dtf).toInstant();
System.out.println(instant);
}
}
使用此替代解决方案的好处如 Ole V.V 的以下评论所述:
Just speculating, maybe a minus sign would be present in case of a
negative UTC offset. If so, maybe use
strDateTime.replaceFirst("\.(\d{1,2}:\d{1,2})", ".+")
to obtain
2021010112:12:12.+10:00 in the positive offset case, after which both
positive and negative offset (and zero) could be parsed.
解析位置
已经有两个很好的答案了。这是我的建议。
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-01T02:12:12Z
缺点是 TemporalAccessor
接口的使用,这是我们通常不应在应用程序代码中使用的低级接口。好处包括代码在偏移量之前接受带符号和不带符号的字符串,我们不需要任何拆分操作或其他正则表达式的应用。如果 UTC 偏移量为负,则符号必须存在,否则我们无法分辨。我们也试试这个:
String timestampString = "2021010112:12:12.-10:00";
2021-01-01T22:12:12Z
我相信 ParsePosition
class 是旧 java.text
包中唯一在 java.time 中重复使用的 class,我个人认为好奇。
我有以下时间戳字符串 "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
您可以使用 regex、(\.)(\d{1,2}:\d{1,2})
将时区偏移部分(正则表达式中的组#2)之前的 .
(正则表达式中的组#1)替换为+
.
演示:
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})", "+");
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
或者,您可以使用 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})", ".+");
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuuMMddHH:mm:ss.XXX", Locale.ENGLISH);
Instant instant = OffsetDateTime.parse(strDateTime, dtf).toInstant();
System.out.println(instant);
}
}
使用此替代解决方案的好处如 Ole V.V 的以下评论所述:
Just speculating, maybe a minus sign would be present in case of a negative UTC offset. If so, maybe use
strDateTime.replaceFirst("\.(\d{1,2}:\d{1,2})", ".+")
to obtain 2021010112:12:12.+10:00 in the positive offset case, after which both positive and negative offset (and zero) could be parsed.
解析位置
已经有两个很好的答案了。这是我的建议。
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-01T02:12:12Z
缺点是 TemporalAccessor
接口的使用,这是我们通常不应在应用程序代码中使用的低级接口。好处包括代码在偏移量之前接受带符号和不带符号的字符串,我们不需要任何拆分操作或其他正则表达式的应用。如果 UTC 偏移量为负,则符号必须存在,否则我们无法分辨。我们也试试这个:
String timestampString = "2021010112:12:12.-10:00";
2021-01-01T22:12:12Z
我相信 ParsePosition
class 是旧 java.text
包中唯一在 java.time 中重复使用的 class,我个人认为好奇。