Java 如何解析格式为yyyy-MM-ddTHH:MM:ss.SSS+ZZZZ的UTC时间戳
我的时间戳为2020-12-03T05:35:59.398+0000,为字符串格式,正在流式批处理中接收 我只想要2020-12-03 05:35:59作为java.sql.Timestamp实例,以便能够将其与其他Timestamp实例进行比较 使用Timestamp.valueOf函数获取以下错误:Java 如何解析格式为yyyy-MM-ddTHH:MM:ss.SSS+ZZZZ的UTC时间戳,java,scala,timestamp,utc,timestamp-with-timezone,Java,Scala,Timestamp,Utc,Timestamp With Timezone,我的时间戳为2020-12-03T05:35:59.398+0000,为字符串格式,正在流式批处理中接收 我只想要2020-12-03 05:35:59作为java.sql.Timestamp实例,以便能够将其与其他Timestamp实例进行比较 使用Timestamp.valueOf函数获取以下错误: Exception in thread "main" java.time.format.DateTimeParseException : Text '2020-12-03T0
Exception in thread "main" java.time.format.DateTimeParseException : Text '2020-12-03T05:35:59.398+0000' could not be parsed at index 23
我尝试了给出的答案,转换确实发生了,但时间改为2020-12-03 11:05:59
我曾尝试在给定的格式之间进行更改,但仍然没有解决方案
wierd+在398+0000之间是否有时间戳格式?对于非标准格式,您可以使用自定义日期格式化程序。下面是您的用例的工作示例
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import static java.time.temporal.ChronoField.*;
public class Main {
private static final DateTimeFormatter INPUT_NON_STANDARD_FORMAT;
static {
INPUT_NON_STANDARD_FORMAT =
new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.append(DateTimeFormatter.ISO_LOCAL_DATE)
.appendLiteral('T')
.appendValue(HOUR_OF_DAY, 2)
.appendLiteral(':')
.appendValue(MINUTE_OF_HOUR, 2)
.optionalStart()
.appendLiteral(':')
.appendValue(SECOND_OF_MINUTE, 2)
.optionalStart()
.appendLiteral('.')
.appendValue(MILLI_OF_SECOND, 3)
.appendLiteral("+0000")
.toFormatter();
}
public static void main(String[] args) {
String timestamp = "2020-12-03T05:35:59.398+0000";
final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("YYYY-MM-dd HH:mm:ss");
LocalDateTime localDateTime = LocalDateTime.parse(timestamp, INPUT_NON_STANDARD_FORMAT);
System.out.println(localDateTime.format(dateTimeFormatter));
}
}
输出
java.time
我建议您在日期和时间工作中使用java.time,即现代java日期和时间API
DateTimeFormatter isoFormatter = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSSxx");
DateTimeFormatter sqlTimestampFormatter = new DateTimeFormatterBuilder()
.append(DateTimeFormatter.ISO_LOCAL_DATE)
.appendLiteral(' ')
.append(DateTimeFormatter.ISO_LOCAL_TIME)
.toFormatter();
String aTimestampString = "2020-12-03T05:35:59.398+0000";
String anotherTimestampString = "2020-12-04 06:43:58.556385";
Instant anInstant = isoFormatter.parse(aTimestampString, Instant::from);
Instant anotherInstant = LocalDateTime.parse(anotherTimestampString, sqlTimestampFormatter)
.atOffset(ZoneOffset.UTC)
.toInstant();
if (anInstant.isBefore(anotherInstant)) {
System.out.println(aTimestampString + " is earlier");
} else {
System.out.println(anotherTimestampString + " is earlier");
}
此示例的输出为:
2020-12-03T05:35:59.398+0000更早
上面前一个字符串中的+0000是UTC的偏移量-00小时00分钟的偏移量。因为它是零,我们知道时间是UTC。我不知道另一个字符串的时区或UTC偏移量。你需要知道,否则你会得到不正确的结果。在上面的代码中,我假设另一个字符串也是UTC
不要使用时间戳
我尝试了这里给出的答案,转换确实发生了,但是时间到了
更改为2020-12-03 11:05:59
这就是Timestamp类的混乱程度。您获得了正确的时间戳值。打印Timestamp对象时发生的情况是隐式或显式地调用其toString方法。Timestamp.toString混淆地使用JVM的默认时区来呈现字符串。因此,如果您的时间戳等于2020-12-03T05:35:59.398 UTC,并且您的时区是(比如)亚洲/加尔各答,则时间将转换为亚洲/加尔各答时区,并返回和打印字符串2020-12-03 11:05:59
使用老式的java.sql.Timestamp类没有什么好处。它最初用于在SQL数据库之间传输带时区和不带时区的时间戳值。由于JDBC4.2,我们更喜欢OffsetDateTime、Instant和LocalDateTime。所以,忘了Timestamp类吧
链接
解释如何使用java.time
wierd+在398+0000之间的时间戳是否有格式
398部分是毫秒的分数,+0000部分是分区偏移部分
您可以使用格式模式uuu-MM dd'T'HH:MM:ss.SSSX将2020-12-03T05:35:59.398+0000解析为OffsetDateTime
演示:
输出:
检查以了解有关用于格式化的字母的详细信息
您可以使用OffsetDateTime的isBefore和isAfter函数来比较它的两个实例
演示:
输出:
了解有关现代日期时间API的更多信息,请访问。如果您正在为Android项目工作,并且您的Android API级别仍然不符合Java-8,请检查并确认
java.util的日期时间API及其格式化API SimpleDataFormat已经过时,并且容易出错。建议完全停止使用,并切换到。因为,建议也停止使用它。但是,出于任何原因,如果您仍然希望使用现代和传统日期时间API之间的转换,请使用作为桥接
import java.sql.Timestamp;
import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
public class Main {
public static void main(String[] args) {
String text = "2020-12-03T05:35:59.398+0000";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSSX");
OffsetDateTime odt = OffsetDateTime.parse(text, formatter);
Instant instant = odt.toInstant();
Timestamp timestamp = new Timestamp(instant.toEpochMilli());
System.out.println(timestamp);
}
}
输出:
欢迎对问题投反对票。请在编辑后立即检查。是否可以避免使用时间戳?那门课设计拙劣,令人困惑,而且早已过时。如果您告诉我们其他时间戳的来源,我们可能能够提供更好的替代方法,例如使用OffsetDateTIme替换或转换为类。听起来您有两个字符串类型的日期,您希望将它们转换为日期/时间类型,以便对其调用比较方法。对吗?如果是这样的话,我建议使用java.time库,不要使用java.sql.Timestamp,它是旧的和过时的java.util.Date的薄包装,但是时间被更改为2020-12-03 11:05:59。不,没有改变。它刚印在你的时区,可能是亚洲/加尔各答。注意格式样式字母的情况。大写的YYYY将在新年前后带给你惊喜。
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
public class Main {
public static void main(String[] args) {
String text = "2020-12-03T05:35:59.398+0000";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSSX");
OffsetDateTime odt = OffsetDateTime.parse(text, formatter);
System.out.println(odt);
}
}
2020-12-03T05:35:59.398Z
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
public class Main {
public static void main(String[] args) {
String text = "2020-12-03T05:35:59.398+0000";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSSX");
OffsetDateTime odt = OffsetDateTime.parse(text, formatter);
OffsetDateTime odtNow = OffsetDateTime.now();
System.out.println(odtNow.isBefore(odt));
System.out.println(odtNow.isAfter(odt));
}
}
false
true
import java.sql.Timestamp;
import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
public class Main {
public static void main(String[] args) {
String text = "2020-12-03T05:35:59.398+0000";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSSX");
OffsetDateTime odt = OffsetDateTime.parse(text, formatter);
Instant instant = odt.toInstant();
Timestamp timestamp = new Timestamp(instant.toEpochMilli());
System.out.println(timestamp);
}
}
2020-12-03 05:35:59.398