- Saved searches
- Use saved searches to filter your results more quickly
- java.time.temporal.UnsupportedTemporalTypeException: Unsupported field: YearOfEra #462
- java.time.temporal.UnsupportedTemporalTypeException: Unsupported field: YearOfEra #462
- Comments
- Java DateTimeFormatter can’t format its own parsed TemporalAccessor
- >Solution :
- How to format Instant to String in java
- Format Instant to String by associating time-zone to Instant
- Time Zone
- Generating String
- Solution 2
- Solution 3
- Solution 4
- Solution 5
Saved searches
Use saved searches to filter your results more quickly
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
java.time.temporal.UnsupportedTemporalTypeException: Unsupported field: YearOfEra #462
java.time.temporal.UnsupportedTemporalTypeException: Unsupported field: YearOfEra #462
status: accepted a confirmation that this is either an issue caused by us or something that should be added system: command type: bug Something isn’t working
Comments
Running /sponge heap results in the following error:
[15:02:35 ERROR] [Sponge]: Error occurred while executing command 'sponge heap' for source EntityPlayerMP['Minecrell'/173, l='SoS8', x=-274.05, y=99.50, z=-217.97]: Unsupported field: YearOfEra java.time.temporal.UnsupportedTemporalTypeException: Unsupported field: YearOfEra at java.time.Instant.getLong(Instant.java:603) ~[?:1.8.0_65] at java.time.format.DateTimePrintContext.getValue(DateTimePrintContext.java:298) ~[?:1.8.0_65] at java.time.format.DateTimeFormatterBuilder$NumberPrinterParser.format(DateTimeFormatterBuilder.java:2540) ~[?:1.8.0_65] at java.time.format.DateTimeFormatterBuilder$CompositePrinterParser.format(DateTimeFormatterBuilder.java:2179) ~[?:1.8.0_65] at java.time.format.DateTimeFormatter.formatTo(DateTimeFormatter.java:1746) ~[?:1.8.0_65] at java.time.format.DateTimeFormatter.format(DateTimeFormatter.java:1720) ~[?:1.8.0_65] at org.spongepowered.common.command.SpongeCommand.lambda$getHeapCommand$18(SpongeCommand.java:311) ~[SpongeCommand.class:1.8.9-3.1.0-BETA-225] at org.spongepowered.api.command.args.ChildCommandElementExecutor.execute(ChildCommandElementExecutor.java:177) ~[ChildCommandElementExecutor.class:1.8.9-3.1.0-BETA-225] at org.spongepowered.api.command.spec.CommandSpec.process(CommandSpec.java:332) ~[CommandSpec.class:1.8.9-3.1.0-BETA-225] at org.spongepowered.api.command.dispatcher.SimpleDispatcher.process(SimpleDispatcher.java:331) ~[SimpleDispatcher.class:1.8.9-3.1.0-BETA-225] at org.spongepowered.common.command.SpongeCommandManager.process(SpongeCommandManager.java:252) [SpongeCommandManager.class:1.8.9-3.1.0-BETA-225] at net.minecraft.command.ServerCommandManager.func_71556_a(SourceFile:83) [bd.class:?] at net.minecraft.network.NetHandlerPlayServer.func_147361_d(SourceFile:690) [lm.class:?] at net.minecraft.network.NetHandlerPlayServer.func_147354_a(SourceFile:677) [lm.class:?] at net.minecraft.network.play.client.C01PacketChatMessage.func_148833_a(SourceFile:37) [ie.class:?] at net.minecraft.network.play.client.C01PacketChatMessage.func_148833_a(SourceFile:9) [ie.class:?] at org.spongepowered.common.network.PacketUtil.onProcessPacket(PacketUtil.java:106) [PacketUtil.class:1.8.9-3.1.0-BETA-225] at net.minecraft.network.PacketThreadUtil$1.onProcessPacket(SourceFile:51) [fh$1.class:?] at net.minecraft.network.PacketThreadUtil$1.run(SourceFile:13) [fh$1.class:?] at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [?:1.8.0_65] at java.util.concurrent.FutureTask.run(FutureTask.java:266) [?:1.8.0_65] at net.minecraft.util.Util.func_181617_a(SourceFile:44) [g.class:?] at net.minecraft.server.MinecraftServer.func_71190_q(SourceFile:143) [MinecraftServer.class:?] at net.minecraft.server.dedicated.DedicatedServer.func_71190_q(SourceFile:299) [ko.class:?] at net.minecraft.server.MinecraftServer.func_71217_p(SourceFile:535) [MinecraftServer.class:?] at net.minecraft.server.MinecraftServer.run(SourceFile:451) [MinecraftServer.class:?] at java.lang.Thread.run(Thread.java:745) [?:1.8.0_65]
The text was updated successfully, but these errors were encountered:
Java DateTimeFormatter can’t format its own parsed TemporalAccessor
I’m creating a simply DateTimeFormatter, but it can’t seem to read it’s own output. The reason I need to use the DateTimeFormatter directly and not LocalDate.format or YearMonth.format is that the code needs to be generic enough to handle different instances of DateTimeFormatter with completely different fields. The code below fails with: java.time.temporal.UnsupportedTemporalTypeException: Unsupported field: YearOfEra
DateTimeFormatter yearMonthFormatter = DateTimeFormatter.ofPattern("yyyyMM"); TemporalAccessor yearMonthTemp = yearMonthFormatter.parse("200102"); String formatted = yearMonthFormatter.format(yearMonthTemp); //fails here trying to format its own output
Is there any way to accomplish the above without having to know the contents of the datetime pattern? i.e. the string «yyyyMM» is not static, it will be passed as a parameter.
>Solution :
What is happening here is that when you parse the string, an additional resolution phase happens, and turns the yyyy format specifier representing the «Year Of Era» temporal field into a «Year» temporal field in the returned TemporalAccessor , and you end up with ( yearMonthTemp.toString() ):
When you format, the yyyy format specifier expects to format a «Year Of Era» temporal field, but the temporal accessor doesn’t have it, as you can clearly see above.
If one needed to change the format of a Temporal without knowing the formats head of time, eg from yyyyMM to MMM-yyyy, you would need two different DateTimeFormatters. The formatters would be completely compatible in terms of the fields that they parse and the temporal objects they produce.
If all you want to do is changing formats, you can set the resolver style to STRICT (by default this is SMART ):
DateTimeFormatter.ofPattern("yyyyMM") .withResolverStyle(ResolverStyle.STRICT);
Though I cannot find documentation for this, I have found that this will prevent it from automatically changing «Year Of Era» to «Year» (which is typically denoted uuuu ). From my testing, every parsed temporal field will be present in the result. Assuming that you have the same format specifiers in the formatting DateFormatter , it will get the same temporal fields successfully.
Note that this also means that you cannot easily get something like a YearMonth from this DateTimeFormatter , because YearMonth.parse / YearMonth.from expects a «Year». not «Year Of Era».
// does not work System.out.println(YearMonth.from(yearMonthTemp));
How to format Instant to String in java
Format Instant to String by associating time-zone to Instant
Instant does not contain time zone information, it only have timestamp to milliseconds from UNIX epoch i.e 1 Jan 1970 from UTC,so DateTimeFormatter can not print date directly because date is always printed with time zone information.
In order to format Instant to String, we need to first associate timezone to formatter and it will work fine.
If you do not provide timezone information, then DateTimeFormatter will through an Exception.
Exception in thread “main” java.time.temporal.UnsupportedTemporalTypeException: Unsupported field: YearOfEra
at java.base/java.time.Instant.getLong(Instant.java:603)
at java.base/java.time.format.DateTimePrintContext.getValue(DateTimePrintContext.java:308)
at java.base/java.time.format.DateTimeFormatterBuilder$NumberPrinterParser.format(DateTimeFormatterBuilder.java:2704)
at java.base/java.time.format.DateTimeFormatterBuilder$CompositePrinterParser.format(DateTimeFormatterBuilder.java:2343)
at java.base/java.time.format.DateTimeFormatter.formatTo(DateTimeFormatter.java:1848)
at java.base/java.time.format.DateTimeFormatter.format(DateTimeFormatter.java:1822)
at org.arpit.java2blog.entry.FormatInstantToString.main(FormatInstantToString.java:15)
Time Zone
To format an Instant a time-zone is required. Without a time-zone, the formatter does not know how to convert the instant to human date-time fields, and therefore throws an exception.
The time-zone can be added directly to the formatter using withZone() .
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.SHORT ) .withLocale( Locale.UK ) .withZone( ZoneId.systemDefault() );
If you specifically want an ISO-8601 format with no explicit time-zone (as the OP asked), with the time-zone implicitly UTC, you need
DateTimeFormatter.ISO_LOCAL_DATE_TIME.withZone(ZoneId.from(ZoneOffset.UTC))
Generating String
Now use that formatter to generate the String representation of your Instant.
Instant instant = Instant.now(); String output = formatter.format( instant );
System.out.println("formatter: " + formatter + " with zone: " + formatter.getZone() + " and Locale: " + formatter.getLocale() ); System.out.println("instant: " + instant ); System.out.println("output: " + output );
formatter: Localized(SHORT,SHORT) with zone: US/Pacific and Locale: en_GB instant: 2015-06-02T21:34:33.616Z output: 02/06/15 14:34
Solution 2
public static void main(String[] args)
Solution 3
DateTimeFormatter.ISO_INSTANT.format(Instant.now())
This saves you from having to convert to UTC. However, some other language’s time frameworks may not support the milliseconds so you should do
DateTimeFormatter.ISO_INSTANT.format(Instant.now().truncatedTo(ChronoUnit.SECONDS))
Solution 4
The Instant class doesn’t contain Zone information, it only stores timestamp in milliseconds from UNIX epoch, i.e. 1 Jan 1070 from UTC. So, formatter can’t print a date because date always printed for concrete time zone. You should set time zone to formatter and all will be fine, like this :
Instant instant = Instant.ofEpochMilli(92554380000L); DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT).withLocale(Locale.UK).withZone(ZoneOffset.UTC); assert formatter.format(instant).equals("07/12/72 05:33"); assert instant.toString().equals("1972-12-07T05:33:00Z");
Solution 5
Instants are already in UTC and already have a default date format of yyyy-MM-dd. If you’re happy with that and don’t want to mess with time zones or formatting, you could also toString() it:
Instant instant = Instant.now(); instant.toString() output: 2020-02-06T18:01:55.648475Z
Don’t want the T and Z? (Z indicates this date is UTC. Z stands for «Zulu» aka «Zero hour offset» aka UTC):
instant.toString().replaceAll("[TZ]", " ") output: 2020-02-06 18:01:55.663763
Want milliseconds instead of nanoseconds? (So you can plop it into a sql query):
instant.truncatedTo(ChronoUnit.MILLIS).toString().replaceAll("[TZ]", " ") output: 2020-02-06 18:01:55.664