Last active
April 1, 2024 06:26
-
-
Save asdf913/a8f23a0400a0edbc83939677987a2b65 to your computer and use it in GitHub Desktop.
This file contains 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.lang.reflect.InvocationHandler; | |
import java.lang.reflect.Method; | |
import java.text.DateFormat; | |
import java.text.SimpleDateFormat; | |
import java.time.LocalDate; | |
import java.time.LocalDateTime; | |
import java.time.Year; | |
import java.time.YearMonth; | |
import java.time.chrono.Era; | |
import java.time.chrono.JapaneseEra; | |
import java.time.format.TextStyle; | |
import java.util.Arrays; | |
import java.util.Calendar; | |
import java.util.Date; | |
import java.util.LinkedHashMap; | |
import java.util.Locale; | |
import java.util.Map; | |
import java.util.Map.Entry; | |
import java.util.Objects; | |
import java.util.SortedMap; | |
import java.util.TreeMap; | |
import java.util.stream.Collectors; | |
import org.apache.commons.lang3.ObjectUtils; | |
import org.apache.commons.lang3.StringUtils; | |
import org.apache.commons.lang3.tuple.Pair; | |
import com.google.common.reflect.Reflection; | |
public class JapaneseEraUtil { | |
private static Locale JAPANESE_LOCALE = null; | |
public static void main(final String[] args) { | |
// | |
// 平成30年 | |
// | |
System.out.println(2018 + " " + getJapaneseEraAndYearString(2018)); | |
// | |
// 令和元年 | |
// | |
System.out.println(2019 + " " + getJapaneseEraAndYearString(2019)); | |
// | |
// 令和2年 | |
// | |
System.out.println(2020 + " " + getJapaneseEraAndYearString(2020)); | |
// | |
System.out.println(StringUtils.leftPad("1", 4) + " " + getJapaneseEraAndYearString(1)); | |
// | |
System.out.println(1867 + " " + getJapaneseEraAndYearString(1867)); | |
// | |
System.out.println(1868 + " " + getJapaneseEraAndYearString(1868)); | |
// | |
final Date date = new Date(); | |
// | |
System.out.println("java.util.Date =" + date); | |
// | |
System.out.println(getJapaneseEraAndYearString(date)); | |
// | |
final LocalDate localDate = LocalDate.now(); | |
// | |
System.out.println("java.time.LocalDate =" + localDate); | |
// | |
System.out.println(getJapaneseEraAndYearString(localDate)); | |
// | |
final LocalDateTime localDateTime = LocalDateTime.now(); | |
// | |
System.out.println("java.time.LocalDateTime=" + localDateTime); | |
// | |
System.out.println(getJapaneseEraAndYearString(localDateTime)); | |
// | |
final Year year = Year.now(); | |
// | |
System.out.println("java.time.Year =" + year); | |
// | |
System.out.println(getJapaneseEraAndYearString(year)); | |
// | |
final YearMonth yearMonth = YearMonth.now(); | |
// | |
System.out.println("java.time.YearMonth =" + yearMonth); | |
// | |
System.out.println(getJapaneseEraAndYearString(yearMonth)); | |
// | |
} | |
private static String getJapaneseEraAndYearString(final YearMonth yearMonth) { | |
// | |
final Calendar c = Calendar.getInstance(); | |
// | |
if (c != null && yearMonth != null) { | |
// | |
c.set(Calendar.YEAR, yearMonth.getYear()); | |
// | |
} // if | |
// | |
return getJapaneseEraAndYearString(c); | |
// | |
} | |
private static String getJapaneseEraAndYearString(final Year year) { | |
// | |
final Calendar c = Calendar.getInstance(); | |
// | |
if (c != null && year != null) { | |
// | |
c.set(Calendar.YEAR, year.getValue()); | |
// | |
} // if | |
// | |
return getJapaneseEraAndYearString(c); | |
// | |
} | |
private static String getJapaneseEraAndYearString(final int year) { | |
// | |
final Calendar c = Calendar.getInstance(); | |
// | |
if (c != null) { | |
// | |
c.set(Calendar.YEAR, year); | |
// | |
} // if | |
// | |
return getJapaneseEraAndYearString(c); | |
// | |
} | |
private static String getJapaneseEraAndYearString(final LocalDateTime date) { | |
// | |
final Calendar c = Calendar.getInstance(); | |
// | |
if (c != null && date != null) { | |
// | |
c.set(Calendar.YEAR, date.getYear()); | |
// | |
} // if | |
// | |
return getJapaneseEraAndYearString(c); | |
// | |
} | |
private static String getJapaneseEraAndYearString(final LocalDate date) { | |
// | |
final Calendar c = Calendar.getInstance(); | |
// | |
if (c != null && date != null) { | |
// | |
c.set(Calendar.YEAR, date.getYear()); | |
// | |
} // if | |
// | |
return getJapaneseEraAndYearString(c); | |
// | |
} | |
private static String getJapaneseEraAndYearString(final Date date) { | |
// | |
final Calendar c = Calendar.getInstance(); | |
// | |
if (c != null && date != null) { | |
// | |
c.setTime(date); | |
// | |
} // if | |
// | |
return getJapaneseEraAndYearString(c); | |
// | |
} | |
private static String getJapaneseEraAndYearString(final Calendar calendar) { | |
// | |
final Calendar c = Calendar.getInstance(); | |
// | |
if (c != null) { | |
// | |
if (calendar != null) { | |
// | |
c.set(Calendar.YEAR, calendar.get(Calendar.YEAR)); | |
// | |
} // if | |
// | |
Arrays.stream(new int[] { Calendar.MONTH, Calendar.DAY_OF_MONTH, Calendar.HOUR_OF_DAY, Calendar.MINUTE, | |
Calendar.SECOND, Calendar.MILLISECOND }).forEachOrdered(x -> c.set(x, c.getMinimum(x))); | |
// | |
} // if | |
// | |
final JapaneseEraAndYear jey = toJapaneseEraAndYear(c); | |
// | |
final SortedMap<JapaneseEra, Entry<Integer, String>> japaneseEraYearMap = new TreeMap<>( | |
(a, b) -> Integer.compare(a.getValue(), b.getValue())); | |
// | |
if (jey.japaneseEraYearMap != null) { | |
// | |
japaneseEraYearMap.putAll(jey.japaneseEraYearMap); | |
// | |
} // if | |
// | |
final JapaneseEra lastKey = japaneseEraYearMap != null && !japaneseEraYearMap.isEmpty() | |
? japaneseEraYearMap.lastKey() | |
: null; | |
// | |
return Arrays | |
.asList(getDisplayName(lastKey, TextStyle.FULL, Locale.JAPAN), | |
getValue(japaneseEraYearMap.get(lastKey)), "年") | |
.stream().map(StringUtils::defaultString).collect(Collectors.joining("")); | |
// | |
} | |
private static <V> V getValue(final Entry<?, V> instance) { | |
return instance != null ? instance.getValue() : null; | |
} | |
private static Calendar getFirstDay(final int year) { | |
// | |
final Calendar c = Calendar.getInstance(); | |
// | |
if (c != null) { | |
// | |
c.set(Calendar.YEAR, year); | |
// | |
Arrays.stream(new int[] { Calendar.MONTH, Calendar.DAY_OF_MONTH, Calendar.HOUR_OF_DAY, Calendar.MINUTE, | |
Calendar.SECOND, Calendar.MILLISECOND }).forEachOrdered(x -> c.set(x, c.getMinimum(x))); | |
// | |
} // if | |
// | |
return c; | |
// | |
} | |
private static class JapaneseEraAndYear { | |
private Integer year = null; | |
private Map<JapaneseEra, Entry<Integer, String>> japaneseEraYearMap = null; | |
} | |
private static JapaneseEraUtil.JapaneseEraAndYear toJapaneseEraAndYear(final Calendar c) { | |
// | |
return c != null ? toJapaneseEraAndYear(c.get(Calendar.YEAR)) : null; | |
// | |
} | |
private static JapaneseEraAndYear toJapaneseEraAndYear(final int year) { | |
// | |
if (JAPANESE_ERA_AND_YEAR_MAP == null) { | |
// | |
JAPANESE_ERA_AND_YEAR_MAP = Reflection.newProxy(IntMap.class, new IH()); | |
// | |
} // if | |
// | |
return toJapaneseEraAndYear(JAPANESE_ERA_AND_YEAR_MAP, year); | |
// | |
} | |
private static class IH implements InvocationHandler { | |
private Map<Integer, Object> map = null; | |
private Map<Integer, Object> getMap() { | |
if (map == null) { | |
map = new LinkedHashMap<>(); | |
} | |
return map; | |
} | |
@Override | |
public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable { | |
// | |
final String methodName = method != null ? method.getName() : null; | |
// | |
if (proxy instanceof IntMap) { | |
// | |
if (Objects.equals(methodName, "containsKey") && args != null && args.length > 0) { | |
// | |
return getMap().containsKey(args[0]); | |
// | |
} else if (Objects.equals(methodName, "put") && args != null && args.length > 1) { | |
// | |
getMap().put((Integer) args[0], args[1]); | |
// | |
return null; | |
// | |
} else if (Objects.equals(methodName, "get") && args != null && args.length > 0) { | |
// | |
return getMap().get(args[0]); | |
// | |
} // if | |
// | |
} // if | |
// | |
throw new Throwable(methodName); | |
// | |
} | |
} | |
private static IntMap<JapaneseEraAndYear> JAPANESE_ERA_AND_YEAR_MAP = null; | |
private static interface IntMap<V> { | |
boolean containsKey(final int key); | |
V get(final int key); | |
void put(final int key, final V value); | |
} | |
private static JapaneseEraAndYear toJapaneseEraAndYear(final IntMap<JapaneseEraAndYear> intMap, final int year) { | |
// | |
if (intMap != null && intMap.containsKey(year)) { | |
// | |
return intMap.get(year); | |
// | |
} // if | |
// | |
final JapaneseEraAndYear japaneseEraAndYear = new JapaneseEraAndYear(); | |
// | |
japaneseEraAndYear.year = year; | |
// | |
japaneseEraAndYear.japaneseEraYearMap = getJapaneseEraYearMap(getFirstDay(year)); | |
// | |
if (intMap != null) { | |
// | |
intMap.put(year, japaneseEraAndYear); | |
// | |
} // if | |
// | |
return japaneseEraAndYear; | |
// | |
} | |
private static Map<JapaneseEra, Entry<Integer, String>> getJapaneseEraYearMap(final Calendar c) { | |
// | |
final Integer westernYear = c != null ? Integer.valueOf(c.get(Calendar.YEAR)) : null; | |
// | |
DateFormat df1 = null, df2 = null, df3 = null; | |
// | |
String nengo, japaneseYearText = null; | |
// | |
Integer japaneseYear = null; | |
// | |
JapaneseEra[] jes = null; | |
// | |
JapaneseEra je = null; | |
// | |
Date date = null; | |
// | |
Map<JapaneseEra, Entry<Integer, String>> map = null; | |
// | |
while (true) { | |
// | |
if (c.get(Calendar.YEAR) != westernYear.intValue()) { | |
// | |
break; | |
// | |
} // if | |
// | |
nengo = format(df1 = ObjectUtils.getIfNull(df1, () -> new SimpleDateFormat("G", getJapaneseLocale())), | |
date = c.getTime()); | |
// | |
japaneseYear = Integer.valueOf(format( | |
df2 = ObjectUtils.getIfNull(df2, () -> new SimpleDateFormat("y", getJapaneseLocale())), date)); | |
// | |
japaneseYearText = format( | |
df3 = ObjectUtils.getIfNull(df3, () -> new SimpleDateFormat("yyyy", getJapaneseLocale())), date); | |
// | |
for (int i = 0; (jes = ObjectUtils.getIfNull(jes, JapaneseEra::values)) != null && i < jes.length; i++) { | |
// | |
if (!Objects.equals(getDisplayName(je = jes[i], TextStyle.FULL, getJapaneseLocale()), nengo)) { | |
// | |
continue; | |
// | |
} // if | |
// | |
if (map == null) { | |
// | |
map = new LinkedHashMap<>(); | |
// | |
} // if | |
// | |
if (map.containsKey(je)) { | |
// | |
continue; | |
// | |
} // if | |
// | |
map.put(je, Pair.of(japaneseYear, japaneseYearText)); | |
// | |
} // for | |
// | |
c.add(Calendar.DATE, 1); | |
// | |
} // while | |
// | |
return map; | |
// | |
} | |
private static String getDisplayName(final Era instance, TextStyle style, Locale locale) { | |
return instance != null ? instance.getDisplayName(style, locale) : null; | |
} | |
private static String format(final DateFormat instance, final Date date) { | |
return instance != null ? instance.format(date) : null; | |
} | |
private static Locale getJapaneseLocale() { | |
if (JAPANESE_LOCALE == null) { | |
JAPANESE_LOCALE = new Locale("ja", "JP", "JP"); | |
} | |
return JAPANESE_LOCALE; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Purpose / 目的
Supported Data Type /
サポートされているデータ型