将带有 +0000 的字符串日期时间转换为即时
Converting string date time with +0000 To instant
如何将作为字符串 2018-08-10T18:25:00.000+0000 传递的日期时间转换为 Instant?我尝试了以下方法,但没有用。
public static Instant toInstant(final String timeStr) {
if (StringUtils.isBlank(timeStr)) {
throw new IllegalArgumentException("Invalid date time value passed [" + timeStr + "]");
}
try {
return LocalDate.parse(timeStr).atStartOfDay().toInstant(ZoneOffset.UTC);
} catch (Exception e) {
try {
return LocalDateTime.parse(timeStr).toInstant(ZoneOffset.UTC);
} catch (Exception e1) {
try {
return ZonedDateTime.parse(timeStr).toInstant();
} catch (Exception e2) {
try {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
return LocalDateTime.parse(timeStr, formatter).toInstant(ZoneOffset.UTC);
} catch (Exception e3) {
try {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
return LocalDateTime.parse(timeStr, formatter).toInstant(ZoneOffset.UTC);
} catch (Exception e4) {
try {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSSS");
return LocalDateTime.parse(timeStr, formatter).toInstant(ZoneOffset.UTC);
} catch (Exception e5) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
return LocalDateTime.parse(timeStr, formatter).toInstant(ZoneOffset.UTC);
} finally {
throw new IllegalArgumentException("Incorrect date time value passed [" + timeStr + "]");
}
}
}
}
}
}
}
您可以将 OffsetDateTime
与 DateTimeFormatter
一起使用。像这样,
public static Instant toInstant(final String timeStr) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
OffsetDateTime dateTime = OffsetDateTime.parse(timeStr, formatter);
return dateTime.toInstant();
}
您的字符串 2018-08-10T18:25:00.000+0000
的时区偏移量为 +0000
小时,因此,您应该将其解析为 OffsetDateTime
,后者可以转换为 Instant
。
演示:
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[]) {
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSSZ", Locale.ENGLISH);
OffsetDateTime odt = OffsetDateTime.parse("2018-08-10T18:25:00.000+0000", dtf);
Instant instant = odt.toInstant();
System.out.println(instant);
}
}
输出:
2018-08-10T18:25:00Z
上述解决方案中使用的 DateTimeFormatter
仅适用于模式中指定的固定数量的数字,例如秒中只有 3 位数字。可以使用 DateTimeFormatterBuilder
构建更好的 DateTimeFormatter
,如以下演示所示:
import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.util.Locale;
public class Main {
public static void main(String args[]) {
DateTimeFormatter dtf = new DateTimeFormatterBuilder()
.append(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
.appendPattern("Z")
.toFormatter(Locale.ENGLISH);
OffsetDateTime odt = OffsetDateTime.parse("2018-08-10T18:25:00.000+0000", dtf);
Instant instant = odt.toInstant();
System.out.println(instant);
}
}
输出:
2018-08-10T18:25:00Z
了解有关 modern Date-Time API* from Trail: Date Time 的更多信息。
* 如果您正在为 Android 项目工作,并且您的 Android API 级别仍然不符合 Java-8,请检查Java 8+ APIs available through desugaring. Note that Android 8.0 Oreo already provides support for java.time
。
你的麻烦在这里:
} finally {
throw new IllegalArgumentException("Incorrect date time value passed [" + timeStr + "]");
}
您在这些行中的解析是成功的(但可能给出不正确的结果):
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
return LocalDateTime.parse(timeStr, formatter).toInstant(ZoneOffset.UTC);
成功解析字符串后,在 finally
块中抛出异常。所以调用者没有收到结果,而是得到一个异常,将不得不认为解析或转换失败。
结果不正确?您对 LocalDateTime
的解析会丢弃字符串 +0000
中的 UTC 偏移量。接下来,您对 Instant
的转换采用 UTC,在本例中恰好与字符串一致。如果字符串中的偏移量不是 +0000
(例如 +0100
),您将得到不正确的 Instant
.
其他答案显示了将字符串转换为 Instant
的正确方法。
如何将作为字符串 2018-08-10T18:25:00.000+0000 传递的日期时间转换为 Instant?我尝试了以下方法,但没有用。
public static Instant toInstant(final String timeStr) {
if (StringUtils.isBlank(timeStr)) {
throw new IllegalArgumentException("Invalid date time value passed [" + timeStr + "]");
}
try {
return LocalDate.parse(timeStr).atStartOfDay().toInstant(ZoneOffset.UTC);
} catch (Exception e) {
try {
return LocalDateTime.parse(timeStr).toInstant(ZoneOffset.UTC);
} catch (Exception e1) {
try {
return ZonedDateTime.parse(timeStr).toInstant();
} catch (Exception e2) {
try {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
return LocalDateTime.parse(timeStr, formatter).toInstant(ZoneOffset.UTC);
} catch (Exception e3) {
try {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
return LocalDateTime.parse(timeStr, formatter).toInstant(ZoneOffset.UTC);
} catch (Exception e4) {
try {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSSS");
return LocalDateTime.parse(timeStr, formatter).toInstant(ZoneOffset.UTC);
} catch (Exception e5) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
return LocalDateTime.parse(timeStr, formatter).toInstant(ZoneOffset.UTC);
} finally {
throw new IllegalArgumentException("Incorrect date time value passed [" + timeStr + "]");
}
}
}
}
}
}
}
您可以将 OffsetDateTime
与 DateTimeFormatter
一起使用。像这样,
public static Instant toInstant(final String timeStr) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
OffsetDateTime dateTime = OffsetDateTime.parse(timeStr, formatter);
return dateTime.toInstant();
}
您的字符串 2018-08-10T18:25:00.000+0000
的时区偏移量为 +0000
小时,因此,您应该将其解析为 OffsetDateTime
,后者可以转换为 Instant
。
演示:
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[]) {
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSSZ", Locale.ENGLISH);
OffsetDateTime odt = OffsetDateTime.parse("2018-08-10T18:25:00.000+0000", dtf);
Instant instant = odt.toInstant();
System.out.println(instant);
}
}
输出:
2018-08-10T18:25:00Z
上述解决方案中使用的 DateTimeFormatter
仅适用于模式中指定的固定数量的数字,例如秒中只有 3 位数字。可以使用 DateTimeFormatterBuilder
构建更好的 DateTimeFormatter
,如以下演示所示:
import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.util.Locale;
public class Main {
public static void main(String args[]) {
DateTimeFormatter dtf = new DateTimeFormatterBuilder()
.append(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
.appendPattern("Z")
.toFormatter(Locale.ENGLISH);
OffsetDateTime odt = OffsetDateTime.parse("2018-08-10T18:25:00.000+0000", dtf);
Instant instant = odt.toInstant();
System.out.println(instant);
}
}
输出:
2018-08-10T18:25:00Z
了解有关 modern Date-Time API* from Trail: Date Time 的更多信息。
* 如果您正在为 Android 项目工作,并且您的 Android API 级别仍然不符合 Java-8,请检查Java 8+ APIs available through desugaring. Note that Android 8.0 Oreo already provides support for java.time
。
你的麻烦在这里:
} finally {
throw new IllegalArgumentException("Incorrect date time value passed [" + timeStr + "]");
}
您在这些行中的解析是成功的(但可能给出不正确的结果):
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
return LocalDateTime.parse(timeStr, formatter).toInstant(ZoneOffset.UTC);
成功解析字符串后,在 finally
块中抛出异常。所以调用者没有收到结果,而是得到一个异常,将不得不认为解析或转换失败。
结果不正确?您对 LocalDateTime
的解析会丢弃字符串 +0000
中的 UTC 偏移量。接下来,您对 Instant
的转换采用 UTC,在本例中恰好与字符串一致。如果字符串中的偏移量不是 +0000
(例如 +0100
),您将得到不正确的 Instant
.
其他答案显示了将字符串转换为 Instant
的正确方法。