Skip to content

Instantly share code, notes, and snippets.

@asdf913
Last active April 1, 2024 06:26
Show Gist options
  • Save asdf913/a8f23a0400a0edbc83939677987a2b65 to your computer and use it in GitHub Desktop.
Save asdf913/a8f23a0400a0edbc83939677987a2b65 to your computer and use it in GitHub Desktop.
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;
}
}
@asdf913
Copy link
Author

asdf913 commented Mar 31, 2024

Output

2018 平成30年
2019 令和元年
2020 令和2年
   1 年
1867 年
1868 明治元年
java.util.Date         =Mon Apr 01 12:07:09 JST 2024
令和6年
java.time.LocalDate    =2024-04-01
令和6年
java.time.LocalDateTime=2024-04-01T12:07:09.293936200
令和6年
java.time.Year         =2024
令和6年
java.time.YearMonth    =2024-04
令和6年

@asdf913
Copy link
Author

asdf913 commented Apr 1, 2024

Purpose / 目的

Conversion of western date into Japanese date /
西暦から和暦への変換

Supported Data Type /
サポートされているデータ型

YearMonthDay of MonthHourMinuteSecondMillisecond
java.util.Date
java.util.Calendar
java.time.LocalDate
java.time.Year      
java.time.YearMonth     

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment