Last active
August 5, 2026 15:10
-
-
Save asdf913/39683cc7cfbcc6f99f1c73c7e9c7adf8 to your computer and use it in GitHub Desktop.
LocalGregorianCalendarReport.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import java.io.IOException; | |
| import java.io.InputStream; | |
| import java.lang.reflect.Proxy; | |
| import java.util.ArrayList; | |
| import java.util.Arrays; | |
| import java.util.Collection; | |
| import java.util.List; | |
| import java.util.Objects; | |
| import java.util.OptionalInt; | |
| import java.util.function.Predicate; | |
| import java.util.function.ToIntFunction; | |
| import java.util.stream.IntStream; | |
| import java.util.stream.Stream; | |
| import org.apache.bcel.classfile.ClassParser; | |
| import org.apache.bcel.classfile.Method; | |
| import org.apache.bcel.generic.ConstantPoolGen; | |
| import org.apache.bcel.generic.ICONST; | |
| import org.apache.bcel.generic.Instruction; | |
| import org.apache.bcel.generic.LDC; | |
| import org.apache.bcel.generic.LDC2_W; | |
| import org.apache.bcel.generic.MethodGen; | |
| import org.apache.bcel.generic.PUTSTATIC; | |
| import org.apache.commons.collections4.IterableUtils; | |
| import org.apache.commons.lang3.ArrayUtils; | |
| import org.apache.commons.lang3.ObjectUtils; | |
| import org.apache.commons.lang3.StringUtils; | |
| public class LocalGregorianCalendarReport { | |
| private static class Era { | |
| private String name, abbr; | |
| private Long since; | |
| private Boolean localTime; | |
| } | |
| public static void main(final String[] args) | |
| throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, IOException { | |
| // | |
| List<Era> list = null; | |
| // | |
| Era era = null; | |
| // | |
| try (final InputStream is = getResourceAsStream(Object.class, | |
| "/sun/util/calendar/LocalGregorianCalendar.class")) { | |
| // | |
| final List<Method> ms = toList(filter(Arrays.stream(new ClassParser(is, null).parse().getMethods()), | |
| m -> m != null ? Objects.equals(m.getName(), "<clinit>") : null)); | |
| // | |
| final int size = IterableUtils.size(ms); | |
| // | |
| if (size > 1) { | |
| // | |
| throw new IllegalStateException(); | |
| // | |
| } // if | |
| // | |
| final Method m = size == 1 ? IterableUtils.get(ms, 0) : null; | |
| // | |
| final Instruction[] ins = m != null ? new MethodGen(m, null, null).getInstructionList().getInstructions() | |
| : null; | |
| // | |
| final int length = ins != null ? ins.length : 0; | |
| // | |
| Integer index = null; | |
| // | |
| for (int i = 0; ins != null && i < length; i++) { | |
| // | |
| if (!(ArrayUtils.get(ins, i) instanceof PUTSTATIC)) { | |
| // | |
| continue; | |
| // | |
| } // if | |
| // | |
| if (index != null) { | |
| // | |
| throw new IllegalStateException(); | |
| // | |
| } // if | |
| // | |
| index = Integer.valueOf(i); | |
| // | |
| } // for | |
| // | |
| Instruction in = null; | |
| // | |
| ConstantPoolGen cpg = null; | |
| // | |
| Number number = null; | |
| // | |
| for (int i = 0; ins != null && i < Math.max(length, intValue(index, 0)); i++) { | |
| // | |
| if (cpg == null) { | |
| // | |
| cpg = new ConstantPoolGen(m.getConstantPool()); | |
| // | |
| } // if | |
| // | |
| if ((in = ArrayUtils.get(ins, i)) instanceof LDC ldc && ldc != null) { | |
| // | |
| if (i > 0 && ArrayUtils.get(ins, i - 1) instanceof LDC) { | |
| // | |
| if (era != null) { | |
| // | |
| era.abbr = Objects.toString(ldc.getValue(cpg)); | |
| // | |
| } // if | |
| // | |
| } else { | |
| // | |
| (era = new Era()).name = Objects.toString(ldc.getValue(cpg)); | |
| // | |
| add(list = ObjectUtils.getIfNull(list, ArrayList::new), era); | |
| // | |
| } // if | |
| // | |
| } else if (in instanceof LDC2_W ldc2w && ldc2w != null && era != null) { | |
| // | |
| era.since = (number = ldc2w.getValue(cpg)) != null ? Long.valueOf(number.longValue()) : null; | |
| // | |
| } else if (in instanceof ICONST iconst && iconst != null && i > 0 | |
| && ArrayUtils.get(ins, i - 1) instanceof LDC2_W && era != null) { | |
| // | |
| if (intValue(number = iconst.getValue(), -1) == 1) { | |
| // | |
| era.localTime = true; | |
| // | |
| } else { | |
| // | |
| throw new IllegalStateException(); | |
| // | |
| } // if | |
| // | |
| } // if | |
| // | |
| } // for | |
| // | |
| } // try | |
| // | |
| final int maxNameLength = orElse( | |
| max(mapToInt(stream(list), x -> StringUtils.length(x != null ? x.name : null))), 0); | |
| // | |
| final int maxSinceLength = orElse( | |
| max(mapToInt(stream(list), x -> StringUtils.length(Objects.toString(x != null ? x.since : null)))), 0); | |
| // | |
| for (int i = 0; i < IterableUtils.size(list); i++) { | |
| // | |
| if ((era = IterableUtils.get(list, i)) == null) { | |
| // | |
| continue; | |
| // | |
| } // if | |
| // | |
| System.out.println(StringUtils.joinWith(" ", StringUtils.rightPad(era.name, maxNameLength), era.abbr, | |
| StringUtils.leftPad(Objects.toString(era.since), maxSinceLength), era.localTime)); | |
| // | |
| } // for | |
| // | |
| } | |
| private static int orElse(final OptionalInt instance, final int other) { | |
| return instance != null ? instance.orElse(other) : other; | |
| } | |
| private static OptionalInt max(final IntStream instance) { | |
| return instance != null ? instance.max() : null; | |
| } | |
| private static <T> IntStream mapToInt(final Stream<T> instance, final ToIntFunction<? super T> mapper) { | |
| // | |
| return instance != null && (Proxy.isProxyClass(getClass(instance)) || mapper != null) | |
| ? instance.mapToInt(mapper) | |
| : null; | |
| // | |
| } | |
| private static Class<?> getClass(final Object instance) { | |
| return instance != null ? instance.getClass() : null; | |
| } | |
| private static <T> Stream<T> stream(final Collection<T> instance) { | |
| return instance != null ? instance.stream() : null; | |
| } | |
| private static <E> void add(final Collection<E> instance, final E item) { | |
| if (instance != null) { | |
| instance.add(item); | |
| } | |
| } | |
| private static int intValue(final Number instance, final int defaultValue) { | |
| return instance != null ? instance.intValue() : defaultValue; | |
| } | |
| private static <T> List<T> toList(final Stream<T> instance) { | |
| return instance != null ? instance.toList() : null; | |
| } | |
| private static <T> Stream<T> filter(final Stream<T> instance, final Predicate<? super T> predicate) { | |
| return instance != null ? instance.filter(predicate) : instance; | |
| } | |
| private static InputStream getResourceAsStream(final Class<?> instance, final String name) { | |
| return instance != null ? instance.getResourceAsStream(name) : null; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!-- https://mvnrepository.com/artifact/org.apache.bcel/bcel --> | |
| <dependency> | |
| <groupId>org.apache.bcel</groupId> | |
| <artifactId>bcel</artifactId> | |
| <version>6.12.0</version> | |
| </dependency> | |
| <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 --> | |
| <dependency> | |
| <groupId>org.apache.commons</groupId> | |
| <artifactId>commons-lang3</artifactId> | |
| <version>3.20.0</version> | |
| </dependency> | |
| <!--https://mvnrepository.com/artifact/org.apache.commons/commons-collections4 --> | |
| <dependency> | |
| <groupId>org.apache.commons</groupId> | |
| <artifactId>commons-collections4</artifactId> | |
| <version>4.5.0</version> | |
| </dependency> |
Author
Author
Sample Output
Meiji M -3218832000000 true
Taisho T -1812153600000 true
Showa S -1357603200000 true
Heisei H 600220800000 true
Reiwa R 1556668800000 true
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/sun/util/calendar/LocalGregorianCalendar.java#L39