日期和时间在特定索引处显示解析错误
date and time show parse error at specific index
我正在从 JSON API URL 获取日期和时间,格式是这样的
'2021-03-05 09:18:07' which is in String form.
但是当我想以毫秒为单位转换它时,它给我一个索引 10 的错误。我不知道为什么会出现这个问题我检查了其他 Whosebug 答案但没有成功
DateTimeFormatter formatter ;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
formatter = DateTimeFormatter.ofPattern(
"yyyy-MM-dd'T'HH:mm:ss", Locale.ROOT);
String dates = object.getString("created_at");
long timeInMilliseconds = OffsetDateTime.parse(dates, formatter)
.toInstant()
.toEpochMilli();
System.out.println("Date in milli :: USING ThreeTenABP >>> " +
timeInMilliseconds);
}
String text = TimeAgo.using(timeInMilliseconds);
FeedModel.setDateSnap(text);
这里是错误
java.time.format.DateTimeParseException: Text '2021-03-05 09:18:07' could not be parsed: Unable
to obtain OffsetDateTime from TemporalAccessor: {},ISO resolved to 2021-03-05T09:18:07 of type
java.time.format.Parsed
at java.time.format.DateTimeFormatter.createError(DateTimeFormatter.java:1920)
at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1855)
at java.time.OffsetDateTime.parse(OffsetDateTime.java:396)
at com.example.wasigram.MainActivity.onResponse(MainActivity.java:91)
at com.androidnetworking.common.ANRequest.deliverSuccessResponse(ANRequest.java:729)
at com.androidnetworking.common.ANRequest.access00(ANRequest.java:80)
at com.androidnetworking.common.ANRequest.run(ANRequest.java:709)
at android.os.Handler.handleCallback(Handler.java:888)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:213)
at android.app.ActivityThread.main(ActivityThread.java:8178)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1101)
Caused by: java.time.DateTimeException: Unable to obtain OffsetDateTime from TemporalAccessor: {},ISO resolved to 2021-03-05T09:18:07 of type java.time.format.Parsed
你有两个问题:
- 您的格式模式字符串与 JSON 中的字符串不完全匹配。
- 您不能天真地将不包含 UTC 偏移量的字符串解析为
OffsetDateTime
。
格式模式字符串
字符串 2021-03-05 09:18:07
中的索引 10 是月份日期之后的 space 所在的位置。因此,让我们看看您的格式模式,看看预计在月份之后会出现什么。您的格式模式字符串是 yyyy-MM-dd'T'HH:mm:ss
,月份之后是 'T'
,表示文字 T
,即 T
不是模式字母。您的例外是因为 T
和 space 不相等。
解析问题的提示:当您看不出解析有什么问题时,请先尝试格式化。
String dates = "2021-03-05 09:18:07";
DateTimeFormatter formatter
= DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss", Locale.ROOT);
OffsetDateTime expectedResult
= OffsetDateTime.of(2021, 3, 5, 9, 18, 7, 0, ZoneOffset.ofHours(1));
System.out.println("Parsing: " + dates);
System.out.println("Formatted: " + expectedResult.format(formatter));
输出为:
Parsing: 2021-03-05 09:18:07
Formatted: 2021-03-05T09:18:07
我希望现在可以更容易地看出字符串中的 space 与格式化程序期望的字符串中的 T
之间的区别。
您可能已经找到了解决方案:在格式模式字符串中放置 space 而不是 'T'
(如果您愿意,可以将 space 放在单引号中,但这不是必需的)。
解析为 OffsetDateTime
此修复仍然失败:
// Put a space in the format pattern string
DateTimeFormatter formatter
= DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss", Locale.ROOT);
OffsetDateTime odt = OffsetDateTime.parse(dates, formatter);
Exception in thread "main" java.time.format.DateTimeParseException:
Text '2021-03-05 09:18:07' could not be parsed: Unable to obtain
OffsetDateTime from TemporalAccessor: {},ISO resolved to
2021-03-05T09:18:07 of type java.time.format.Parsed
有趣的是,这也是您问题中堆栈跟踪中的异常。
OffsetDateTime
必须包含与 UTC 的偏移量,而 Java 无法从中获取它。您知道从中获取字符串的 API 假定的时区吗?如果是这样,请使用它。我的建议是:
ZoneId zoneAssumedByApi = ZoneId.of("Antarctica/Troll");
long timeInMilliseconds = LocalDateTime.parse(dates, formatter)
.atZone(zoneAssumedByApi)
.toInstant()
.toEpochMilli();
System.out.println("Date in milli :: USING ThreeTenABP >>> "
+ timeInMilliseconds);
Date in milli :: USING ThreeTenABP >>> 1614935887000
您可以使用 DateTimeFormatter#withZone
获取指定区域的格式化程序。
此外,请使用正确的格式,yyyy-MM-dd HH:mm:ss
,其中没有您误放入模式中的 'T'
。事实上,我更喜欢使用 u
而不是 y
,如 .
中所述
演示:
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
String strDateTime = "2021-03-05 09:18:07";
DateTimeFormatter formatter = DateTimeFormatter
.ofPattern("uuuu-MM-dd HH:mm:ss", Locale.ENGLISH)
.withZone(ZoneOffset.UTC);
long millis = OffsetDateTime
.parse(strDateTime, formatter)
.toInstant()
.toEpochMilli();
System.out.println(millis);
}
}
输出:
1614935887000
了解有关现代日期时间的更多信息 API
import java.util.Locale;
import org.threeten.bp.LocalDateTime;
import org.threeten.bp.ZoneOffset;
import org.threeten.bp.format.DateTimeFormatter;
public class Main {
public static void main(String[] args) {
String strDateTime = "2021-03-05 09:18:07";
DateTimeFormatter formatter = DateTimeFormatter
.ofPattern("uuuu-MM-dd HH:mm:ss", Locale.ENGLISH);
long millis = LocalDateTime
.parse(strDateTime, formatter)
.toInstant(ZoneOffset.UTC)
.toEpochMilli();
System.out.println(millis);
}
}
输出:
1614935887000
我正在从 JSON API URL 获取日期和时间,格式是这样的
'2021-03-05 09:18:07' which is in String form.
但是当我想以毫秒为单位转换它时,它给我一个索引 10 的错误。我不知道为什么会出现这个问题我检查了其他 Whosebug 答案但没有成功
DateTimeFormatter formatter ;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
formatter = DateTimeFormatter.ofPattern(
"yyyy-MM-dd'T'HH:mm:ss", Locale.ROOT);
String dates = object.getString("created_at");
long timeInMilliseconds = OffsetDateTime.parse(dates, formatter)
.toInstant()
.toEpochMilli();
System.out.println("Date in milli :: USING ThreeTenABP >>> " +
timeInMilliseconds);
}
String text = TimeAgo.using(timeInMilliseconds);
FeedModel.setDateSnap(text);
这里是错误
java.time.format.DateTimeParseException: Text '2021-03-05 09:18:07' could not be parsed: Unable
to obtain OffsetDateTime from TemporalAccessor: {},ISO resolved to 2021-03-05T09:18:07 of type
java.time.format.Parsed
at java.time.format.DateTimeFormatter.createError(DateTimeFormatter.java:1920)
at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1855)
at java.time.OffsetDateTime.parse(OffsetDateTime.java:396)
at com.example.wasigram.MainActivity.onResponse(MainActivity.java:91)
at com.androidnetworking.common.ANRequest.deliverSuccessResponse(ANRequest.java:729)
at com.androidnetworking.common.ANRequest.access00(ANRequest.java:80)
at com.androidnetworking.common.ANRequest.run(ANRequest.java:709)
at android.os.Handler.handleCallback(Handler.java:888)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:213)
at android.app.ActivityThread.main(ActivityThread.java:8178)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1101)
Caused by: java.time.DateTimeException: Unable to obtain OffsetDateTime from TemporalAccessor: {},ISO resolved to 2021-03-05T09:18:07 of type java.time.format.Parsed
你有两个问题:
- 您的格式模式字符串与 JSON 中的字符串不完全匹配。
- 您不能天真地将不包含 UTC 偏移量的字符串解析为
OffsetDateTime
。
格式模式字符串
字符串 2021-03-05 09:18:07
中的索引 10 是月份日期之后的 space 所在的位置。因此,让我们看看您的格式模式,看看预计在月份之后会出现什么。您的格式模式字符串是 yyyy-MM-dd'T'HH:mm:ss
,月份之后是 'T'
,表示文字 T
,即 T
不是模式字母。您的例外是因为 T
和 space 不相等。
解析问题的提示:当您看不出解析有什么问题时,请先尝试格式化。
String dates = "2021-03-05 09:18:07";
DateTimeFormatter formatter
= DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss", Locale.ROOT);
OffsetDateTime expectedResult
= OffsetDateTime.of(2021, 3, 5, 9, 18, 7, 0, ZoneOffset.ofHours(1));
System.out.println("Parsing: " + dates);
System.out.println("Formatted: " + expectedResult.format(formatter));
输出为:
Parsing: 2021-03-05 09:18:07 Formatted: 2021-03-05T09:18:07
我希望现在可以更容易地看出字符串中的 space 与格式化程序期望的字符串中的 T
之间的区别。
您可能已经找到了解决方案:在格式模式字符串中放置 space 而不是 'T'
(如果您愿意,可以将 space 放在单引号中,但这不是必需的)。
解析为 OffsetDateTime
此修复仍然失败:
// Put a space in the format pattern string
DateTimeFormatter formatter
= DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss", Locale.ROOT);
OffsetDateTime odt = OffsetDateTime.parse(dates, formatter);
Exception in thread "main" java.time.format.DateTimeParseException: Text '2021-03-05 09:18:07' could not be parsed: Unable to obtain OffsetDateTime from TemporalAccessor: {},ISO resolved to 2021-03-05T09:18:07 of type java.time.format.Parsed
有趣的是,这也是您问题中堆栈跟踪中的异常。
OffsetDateTime
必须包含与 UTC 的偏移量,而 Java 无法从中获取它。您知道从中获取字符串的 API 假定的时区吗?如果是这样,请使用它。我的建议是:
ZoneId zoneAssumedByApi = ZoneId.of("Antarctica/Troll");
long timeInMilliseconds = LocalDateTime.parse(dates, formatter)
.atZone(zoneAssumedByApi)
.toInstant()
.toEpochMilli();
System.out.println("Date in milli :: USING ThreeTenABP >>> "
+ timeInMilliseconds);
Date in milli :: USING ThreeTenABP >>> 1614935887000
您可以使用 DateTimeFormatter#withZone
获取指定区域的格式化程序。
此外,请使用正确的格式,yyyy-MM-dd HH:mm:ss
,其中没有您误放入模式中的 'T'
。事实上,我更喜欢使用 u
而不是 y
,如
演示:
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
String strDateTime = "2021-03-05 09:18:07";
DateTimeFormatter formatter = DateTimeFormatter
.ofPattern("uuuu-MM-dd HH:mm:ss", Locale.ENGLISH)
.withZone(ZoneOffset.UTC);
long millis = OffsetDateTime
.parse(strDateTime, formatter)
.toInstant()
.toEpochMilli();
System.out.println(millis);
}
}
输出:
1614935887000
了解有关现代日期时间的更多信息 API
import java.util.Locale;
import org.threeten.bp.LocalDateTime;
import org.threeten.bp.ZoneOffset;
import org.threeten.bp.format.DateTimeFormatter;
public class Main {
public static void main(String[] args) {
String strDateTime = "2021-03-05 09:18:07";
DateTimeFormatter formatter = DateTimeFormatter
.ofPattern("uuuu-MM-dd HH:mm:ss", Locale.ENGLISH);
long millis = LocalDateTime
.parse(strDateTime, formatter)
.toInstant(ZoneOffset.UTC)
.toEpochMilli();
System.out.println(millis);
}
}
输出:
1614935887000