日本华人论坛 程序编写2



日本 - package jp.co.ji.jbaas.util.common;

import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.TimeZone;
import java.util.regex.Pattern;
import java.util.stream.Stream;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import com.fasterxml.jackson.core.type.TypeReference;

import jp.co.ji.jbaas.Config;
import jp.co.ji.jbaas.LogicMap;
import jp.co.ji.jbaas.annotation.LogicKey;
import jp.co.ji.jbaas.common.MapKeyConst;
import jp.co.ji.jbaas.common.bean.HokenKikanBean;
import jp.co.ji.jbaas.context.RequestContext;
import jp.co.ji.jbaas.logic.ILogic;
import jp.co.ji.jbaas.logic.database.basic.UDCM00820B01Logic;
import jp.co.ji.jbaas.logic.database.custom.UDCM00410C02Logic;
import jp.co.ji.jbaas.util.mst.fusss.common.CodeMstUtil;
import jp.co.ji.model.fusss.common.MCdmst;
import jp.co.ji.model.fusss.common.MSystemmst;

/**
* 日付に関するユーティリティ。
* @author  NSD
* @version 0.5
* @since   2012/1/15
*/
public final class DateUtil extends Date {

    /**
     * 日付変換用フォーマット(YYYY/MM/DD)
     */
    public static final String YYYYMMDD_2 = "yyyy/MM/dd";
    /**
     * 日付変換用フォーマット(YYYY/M/D)
     */
    public static final String YYYYMMDD_3 = "yyyy/M/d";
    /**
     * 日付変換用フォーマット(YYYY-MM-DD)
     */
    public static final String YYYYMMDD_4 = "yyyy-MM-dd";

    /**
     * 日付変換用フォーマット(YYYY/MM)
     */
    public static final String YYYYMM_2 = "yyyy/MM";
    /**
     * 日付変換用フォーマット(YYMM)
     */
    public static final String YYMM_2 = "yy/MM";
    /**
     * 日付変換用フォーマット(MM/DD)
     */
    public static final String MMDD_2 = "MM/dd";
    /**
     * 日付変換用フォーマット(YYYYMMDD)
     */
    public static final String YYYYMMDD = "yyyyMMdd";
    /**
     * 日付変換用フォーマット(YYMDD)
     */
    public static final String YYMMDD = "yyMMdd";
    /**
     * 日付変換用フォーマット(MMDDYY)
     */
    public static final String MMDDYY = "MMddyy";
    /**
     * 日付変換用フォーマット(YYYY_MM_DD)
     */
    public static final String YYYY_MM_DD = "yyyy_MM_dd";
    /**
     * 日付変換用フォーマット(yyyy-MM-dd)
     */
    public static final String YYYYMMDD_WITH_HYPHEN = "yyyy-MM-dd";
    /**
     * 日付変換用フォーマット(YYYYMM)
     */
    public static final String YYYYMM = "yyyyMM";
    /**
     * 日付変換用フォーマット(YYMM)
     */
    public static final String YYMM = "yyMM";
    /**
     * 日付変換用フォーマット(yyyy年mm月dd日)
     */
    public static final String YYYYMMDD_KANJI = "yyyy年MM月dd日";
    /**
     * 日付変換用フォーマット(yyyy年m月d日)
     */
    public static final String YYYYMD_KANJI = "yyyy年M月d日";
    /**
     * 日付変換用フォーマット(yyyy年m月dd日)
     */
    public static final String YYYYMDD_KANJI = "yyyy年M月dd日";
    /**
     * 日付変換用フォーマット(yyyy年m月)
     */
    public static final String YYYYM_KANJI = "yyyy年M月";
    /**
     * 日付変換用フォーマット(yyyy年mm月)
     */
    public static final String YYYYMM_KANJI = "yyyy年MM月";
    /**
     * 日付変換用フォーマット(yy.MM.dd)
     */
    public static final String YYMMDD_DOT = "yy.MM.dd";
    /**
     * 日付変換用フォーマット(yyyy年M月d日 H時m分)
     */
    public static final String YYYYMDHM_KANJI = "yyyy年M月d日 H時m分";
    /**
     * 日付変換用フォーマット(yyyy年MM月dd日hh時mm分)
     */
    public static final String YYYYMMDDHHMM_KANJI = "yyyy年MM月dd日HH時mm分";
    /**
     * 日付変換用フォーマット(yyyy年MM月dd日 hh:mm)
     */
    public static final String YYYYMMDDHH_KANJI = "yyyy年MM月dd日 HH:mm";
    /**
     * 日付変換用フォーマット(yyyy年M月d日 H時頃)
     */
    public static final String YYYYMDHM_KANJI_ABOUT = "yyyy年M月d日 H時頃";
    /**
     * 日付変換用フォーマット(yyyy/MM/dd HH:mm:ss)
     */
    public static final String YYYYMMDDHHMMSS = "yyyy/MM/dd HH:mm:ss";
    /**
     * 日付変換用フォーマット(yyyyMMddHHmmss)
     */
    public static final String YYYYMMDDHHMMSS_2 = "yyyyMMddHHmmss";
    /**
     * 日付変換用フォーマット(yyyy-MM-dd HH:mm:ss)
     */
    public static final String YYYYMMDDHHMMSS_3 = "yyyy-MM-dd HH:mm:ss";
    /**
     * 日付変換用フォーマット(HHmmssSSS)
     */
    public static final String HHMMSSSSS = "HHmmssSSS";
    /**
     * 日付変換用フォーマット(HHmmss)
     */
    public static final String HHMMSS = "HHmmss";
    /**
     * 日付変換用フォーマット(yyyy/MM/dd HH)
     */
    public static final String YYYYMMDDHH = "yyyy/MM/dd HH";
    /**
     * 日付変換用フォーマット(YYYYMMDDHH)
     */
    public static final String YYYYMMDDHH_2 = "yyyyMMddHH";
    /**
     * 日付変換用フォーマット(yyyy/MM/dd HH:mm)
     */
    public static final String YYYYMMDDHHMM = "yyyy/MM/dd HH:mm";
    /**
     * 日付変換用フォーマット(yyyyMMddHHmm)
     */
    public static final String YYYYMMDDHHMM_2 = "yyyyMMddHHmm";
    /**
     * 日付変換用フォーマット(YYYY)
     */
    public static final String YYYY = "yyyy";
    /**
     * 日付変換用フォーマット(YY)
     */
    public static final String YY = "yy";
    /**
     * 日付変換用フォーマット(MMDD)
     */
    public static final String MMDD = "MMdd";
    /**
     * 日付変換用フォーマット(d日)
     */
    public static final String D_KANJI = "d日";
    /**
     * 日付変換用フォーマット(M月d日)
     */
    public static final String MD_KANJI = "M月d日";
    /**
     * 日付変換用フォーマット(MMDD_KANJI)
     */
    public static final String MMDD_KANJI = "MM月dd日";
    /**
     * 日付変換用フォーマット(mm)
     */
    public static final String MM = "MM";
    /**
     * 日付変換用フォーマット(M)
     */
    public static final String M = "M";
    /**
     * 日付変換用フォーマット(MMDD)
     */
    public static final String DD = "d日";
    /**
     * 日付変換用フォーマット(dd)
     */
    public static final String DD_2 = "dd";

    /**
     * 日付変換用フォーマット(d)
     */
    public static final String D = "d";

    /**
     * 日付変換用フォーマット(H)
     */
    public static final String H = "H";

    /**
     * 日付変換用フォーマット(yyyyMMddHHmmssSSS)
     */
    public static final String YYYYMMDDHHMMSSSSS = "yyyyMMddHHmmssSSS";
    /**
     * 日付変換用フォーマット(yyyy年M月d日 H:m)
     */
    public static final String YYYYMD_HHMM = "yyyy年M月d日 HH:mm";

    /**
     * 日付変換用フォーマット(和暦GGGGy年M月d日)
     */
    public static final String GGGGYMMDD = "GGGGy年M月d日";

    /**
     * 日付変換用フォーマット(和暦GGGGy年M月d日)
     */
    public static final String GGGGYMM = "GGGGy年M月";

    /**
     * 日付変換用フォーマット(和暦GGGGy年)
     */
    public static final String GGGGY = "GGGGy年";

    /**
     * 日付変換用フォーマット(和暦GGGGy)
     */
    public static final String GGGGY_WITHOUT_NEN = "GGGGy";

    /**
     * 日付変換用フォーマット(yyyy年M月d日 H時頃)
     */
    public static final String YYYYMDHM_KANJI_H = "yyyy年M月d日  H時";

    /**
     * 日付変換用フォーマット(MM/DD/YYYY)
     */
    public static final String MMDDYYYY = "MM/dd/yyyy";

    /**
     * タイムゾーン
     */
    public static final String TIMEZONE = "Asia/Tokyo";
    /**
     * 日付正規表現(YYYY/MM/DD)
     */
    private static Pattern DATE_PATTERN_1 = Pattern.compile("^\\d{4}/\\d{2}/\\d{2}$");
    /**
     * 日付正規表現(YYYY-MM-DD)
     */
    private static Pattern DATE_PATTERN_2 = Pattern.compile("^\\d{4}-\\d{2}-\\d{2}$");
    /**
     * 日付正規表現(YYYYMMDD)
     */
    private static Pattern DATE_PATTERN_3 = Pattern.compile("^\\d{4}\\d{2}\\d{2}$");
    /**
     * logger
     */
    private static final Logger LOGGER = Logger.getLogger(DateUtil.class);
    /**
     * シリアル番号
     */
    private static final long serialVersionUID = 1L;

    /**
     * 本クラスのインスタンスを作成させないため、privateのコンストラクタ
     */
    private DateUtil() {
    }

    /**
     * 現在時刻のDateを返す。
     *
     * <pre>
     * 開発モードの場合は接続元IP別にコードマスタに定義された設定値で時刻調整した値を返却する
     * </pre>
     *
     * @return 現在時刻
     * @throws Exception
     */
    public static Date now() {
        LOGGER.debug("start now");

        // 現在時刻の取得
        Calendar cl = Calendar.getInstance();

        try {
            // 開発モードの場合
            if ("develop".equals(Config.getParameter(Config.APP_RUNNING_MODE))) {
                // 時刻調整値の取得
                List<MCdmst> testDateTimeList = CodeMstUtil.getCdmstByShuShubetsuCD("9999"); // テスト用コード

                // 接続元IPアドレス取得
                String ipAddress = RequestContext.getIPAddress();

                for (MCdmst cdmst : testDateTimeList) {
                    // 接続元IPアドレスと予備1が一致するレコードの調整値を反映
                    if (ipAddress.equals(cdmst.getYobi1())) {
                        cl.add(Calendar.YEAR,
                                !StringUtil.isEmpty(cdmst.getYobi2()) ? Integer.valueOf(cdmst.getYobi2()) : 0);
                        cl.add(Calendar.MONTH,
                                !StringUtil.isEmpty(cdmst.getYobi3()) ? Integer.valueOf(cdmst.getYobi3()) : 0);
                        cl.add(Calendar.DATE,
                                !StringUtil.isEmpty(cdmst.getYobi4()) ? Integer.valueOf(cdmst.getYobi4()) : 0);
                        cl.add(Calendar.HOUR,
                                !StringUtil.isEmpty(cdmst.getYobi5()) ? Integer.valueOf(cdmst.getYobi5()) : 0);
                        cl.add(Calendar.MINUTE,
                                !StringUtil.isEmpty(cdmst.getYobi6()) ? Integer.valueOf(cdmst.getYobi6()) : 0);
                        cl.add(Calendar.SECOND,
                                !StringUtil.isEmpty(cdmst.getYobi7()) ? Integer.valueOf(cdmst.getYobi7()) : 0);
                        cl.add(Calendar.MILLISECOND,
                                !StringUtil.isEmpty(cdmst.getYobi8()) ? Integer.valueOf(cdmst.getYobi8()) : 0);
                    }
                }
            }
        } catch (Exception e) {
            // エラーが起きたらシステム時刻返却
            // LOGGER.error("時刻調整に失敗しました。", e);
        }

        Date retDate = cl.getTime();

        LOGGER.debug("end now return=" + retDate);

        return retDate;
    }

    /**
     * システムコードによりシステムマスタから業務日付を取得する
     *
     * @param systemCd システムコード
     * @return 業務日付
     * @throws Exception
     *
     */
    public static Date getGyomuDate(String systemCd) throws Exception {

        // システムコードない場合
        if (StringUtil.isEmpty(systemCd)) {
            return null;
        }

        // システムマスタ基本DAO
        ILogic iLogic = LogicMap.getLogic(UDCM00820B01Logic.class.getAnnotation(LogicKey.class).name());

        // 検索条件
        Map<String, Object> localMap = new HashMap<String, Object>();
        localMap.put(MapKeyConst.SYSTEMCD_DB, systemCd);
        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put(iLogic.getLogicParamKey(), localMap);
        iLogic.execute(paramMap);

        // 検索結果
        Map<String, Object> rs = iLogic.getResult().getOutputMap();
        List<MSystemmst> systemList = ConvertUtil.convert(rs.get(iLogic.getLogicResultKey()),
                new TypeReference<List<MSystemmst>>() {
                });

        // 業務日付取得しない場合
        if (ListUtil.isEmpty(systemList)) {
            return null;
        }
        return systemList.get(0).getGyomuDate();
    }

    /**
     * DBから現在時刻の設定値を取得する
     * @return 現在時刻の設定値
     */
    public static String dbNow() throws Exception {
        // DAO生成
        return DateUtil.dateToString(now(), YYYYMMDDHHMMSS);

    }

    /**
     * 今日日付のDateを返す。
     *  フォーマットは"yyyy/MM/dd"であること。
     * @return 今日日付
     * @throws ParseException
     */
    public static Date today() throws ParseException {
        return stringToDate(dateToString(now(), YYYYMMDD_2), YYYYMMDD_2);
    }

    /**
     * Dateを指定フォーマットのStringで返す
     * @param date Date
     * @param format フォーマット
     * @return フォーマットされたString
     */
    public static String dateToString(final Date date, final String format) {
        return getConditionedSdf(format).format(date);
    }

    /**
     * 日付のStringを渡してDate型で返す
     * @param yearMonth ("yyyy/MM")
     * @param day ("dd")
     * @return Date
     * @throws ParseException 不正なフォーマットの場合
     */
    public static Date stringYDToDate(final String yearMonth, final String day) throws ParseException {
        String strDate = new StringBuilder().append(yearMonth)
                .append("/")
                .append(day).toString();
        return stringToDate(strDate, "yyyy/MM/dd");
    }

    /**
     * 指定フォーマットのStringのDateを返す
     * @param dateStr 日付の文字列
     * @param format フォーマット
     * @return Date
     * @throws ParseException 不正なフォーマットの場合
     */
    public static Date stringToDate(final String dateStr, final String format) throws ParseException {
        if (StringUtils.isEmpty(dateStr)) {
            return null;
        }
        return getConditionedSdf(format).parse(dateStr);
    }

    /**
     * 日付(Date)の差分(月)を返す。
     *  date1からのdate2の経過日数
     * @param date1 日付1
     * @param date2 日付2
     * @return 差分(月)
     */
    public static int diffMonth(final Date date1, final Date date2) {
        Calendar cal1 = dateToCalendar(date1);
        Calendar cal2 = dateToCalendar(date2);

        clearHMS(cal1);
        clearHMS(cal2);

        // 差分の月数算出
        int count = 0;
        while (cal1.before(cal2)) {
            cal1.add(Calendar.MONTH, 1);
            count++;
        }

        return count;
    }

    /**
     * 日付(Date)の差分(日)を返す。
     *  date1からのdate2の経過日数
     * @param date1 日付1
     * @param date2 日付2
     * @return 差分(日)
     */
    public static int diffDay(final Date date1, final Date date2) {
        Calendar cal1 = dateToCalendar(date1);
        Calendar cal2 = dateToCalendar(date2);
        clearHMS(cal1);
        clearHMS(cal2);
        long msecDiff = cal2.getTime().getTime() - cal1.getTime().getTime();
        long dayDiff = msecDiff / 1000 / 60 / 60 / 24;
        return (new Long(dayDiff)).intValue();
    }

    /**
     * 日付(Date)の差分(年)を返す。
     *  date1からのdate2の経過年数
     *  date1がdate2より未来の日付の場合、-1を返す。
     * @param date1 日付1
     * @param date2 日付2
     * @return 差分(年)
     */
    public static int diffYear(final Date date1, final Date date2) {
        Calendar cal1 = dateToCalendar(date1);
        Calendar cal2 = dateToCalendar(date2);
        if (cal1.compareTo(cal2) > 0) {
            return -1;
        }
        int diffYear = cal2.get(Calendar.YEAR) - cal1.get(Calendar.YEAR);
        if (cal2.get(Calendar.MONTH) > cal1.get(Calendar.MONTH)) {
            return diffYear;
        } else if (cal2.get(Calendar.MONTH) < cal1.get(Calendar.MONTH)) {
            return diffYear - 1;
        } else if (cal2.get(Calendar.DAY_OF_MONTH) >= cal1.get(Calendar.DAY_OF_MONTH)) {
            return diffYear;
        } else {
            return diffYear - 1;
        }
    }

    /**
     * 日付(Date)の差分(分)を返す。
     *  date1からのdate2の経過時間(分)
     * @param date1 日付1
     * @param date2 日付2
     * @return 差分(分)
     */
    public static int diffMin(final Date date1, final Date date2) {
        long msecDiff = date2.getTime() - date1.getTime();
        long minDiff = msecDiff / 1000 / 60;
        return (new Long(minDiff)).intValue();
    }

    /**
     * DateをCalendarに変換する。
     *  TimeZoneはAsia/Tokyo。
     * @param date Date
     * @return Calendar
     */
    public static Calendar dateToCalendar(final Date date) {
        Calendar cal = Calendar.getInstance(TimeZone.getTimeZone(TIMEZONE));
        cal.setLenient(false);
        cal.setTime(date);
        return cal;
    }

    /**
     * 指定フォーマットのSimpleDateFormatを返す
     *  TimeZoneはAsia/Tokyo。
     * @param format フォーマット
     * @return SimpleDateFormat
     */
    public static SimpleDateFormat getConditionedSdf(final String format) {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        sdf.setLenient(false);
        sdf.setTimeZone(TimeZone.getTimeZone(TIMEZONE));
        return sdf;
    }

    /**
     * Calendarの年月による比較。
     * @param aCal 比較対象日付a
     * @param bCal 比較対象日付b
     * @return 1: a>b ,0: a=b, -1: a<b
     */
    public static int calendarCompareByYearAndMonth(final Calendar aCal, final Calendar bCal) {

        int aYear = aCal.get(Calendar.YEAR);
        int aMonth = aCal.get(Calendar.MONTH) + 1;
        int bYear = bCal.get(Calendar.YEAR);
        int bMonth = bCal.get(Calendar.MONTH) + 1;

        Date aDate = DateUtil.stringYMDToDate(String.valueOf(aYear), String.valueOf(aMonth), "1");
        Date bDate = DateUtil.stringYMDToDate(String.valueOf(bYear), String.valueOf(bMonth), "1");

        return aDate.compareTo(bDate);

        /**
        if (aMonth > bMonth || aYear > bYear) {
            return 1;
        } else if (aMonth < bMonth || aYear < bYear) {
            return -1;
        } else {
            return 0;
        }
         )**/
    }

    /**
     * Dateの比較。
     *  年月日による比較を行う。時分秒以下は無視する。
     * @param aDate 比較対象日付a
     * @param bDate 比較対象日付b
     * @return 1: a>b ,0: a=b, -1: a<b
     */
    public static int dateCompare(final Date aDate, final Date bDate) {
        SimpleDateFormat sdf = getConditionedSdf("yyyy/MM/dd");
        String aString = sdf.format(aDate);
        String bString = sdf.format(bDate);
        Date a = null;
        Date b = null;
        try {
            a = sdf.parse(aString);
            b = sdf.parse(bString);
        } catch (ParseException e) {
            throw new RuntimeException(e.toString());
        }
        return a.compareTo(b);
    }

    /**
     * 引数によるDateの比較を行う。
     * @param aDate     比較対象日時a
     * @param bDate     比較対象日時b
     * @param format    比較対象のフォーマット
     * @return 1: a>b ,0: a=b, -1: a<b
     */
    public static int dateCompare(final Date aDate, final Date bDate, final String format) {
        SimpleDateFormat sdf = getConditionedSdf(format);
        String aString = sdf.format(aDate);
        String bString = sdf.format(bDate);
        Date a = null;
        Date b = null;
        try {
            a = sdf.parse(aString);
            b = sdf.parse(bString);
        } catch (ParseException e) {
            throw new RuntimeException(e.toString());
        }
        return a.compareTo(b);
    }

    /**
     * Dateの比較。
            *  年月日(時分秒含む)による比較を行う。
     * @param aDate 比較対象日付a
     * @param bDate 比較対象日付b
     * @return 1: a>b ,0: a=b, -1: a<b
     */
    public static int dateCompareDetail(final Date aDate, final Date bDate) {
        SimpleDateFormat sdf = getConditionedSdf("yyyy/MM/dd HH:mm:ss");
        String aString = sdf.format(aDate);
        String bString = sdf.format(bDate);
        Date a = null;
        Date b = null;
        try {
            a = sdf.parse(aString);
            b = sdf.parse(bString);
        } catch (ParseException e) {
            throw new RuntimeException(e.toString());
        }
        return a.compareTo(b);
    }

    /**
     * 文字列の年月日の比較。
     *  年月日による比較を行う
     * @param aStrDate 比較対象日付a
     * @param bStrDate 比較対象日付b
     * @return 1: a>b ,0: a=b, -1: a<b
     */
    public static int strDateCompare(final String aStrDate, final String bStrDate) {
        Date aDate;
        Date bDate;
        try {
            // Date変換
            aDate = DateFormat.getDateInstance().parse(aStrDate);
            bDate = DateFormat.getDateInstance().parse(bStrDate);

        } catch (ParseException e) {
            throw new RuntimeException(e.toString());
        }
        return aDate.compareTo(bDate);
    }

    /**
     * 年月日の文字列を日付に変換する。
     * @param yearStr 年
     * @param monthStr 月
     * @param dayStr 日
     * @return 日付
     */
    public static Date stringYMDToDate(final String yearStr, final String monthStr, final String dayStr) {
        int year = Integer.parseInt(yearStr);
        int month = Integer.parseInt(monthStr);
        int day = Integer.parseInt(dayStr);

        return stringYMDToDate(year, month, day);
    }

    /**
     * 年月日を日付に変換する。
     * @param year 年
     * @param month 月
     * @param day 日
     * @return 日付
     */
    public static Date stringYMDToDate(final int year, final int month, final int day) {

        Calendar cal = Calendar.getInstance(TimeZone.getTimeZone(TIMEZONE));
        cal.setLenient(false);
        cal.set(year, month - 1, day);
        return clearHMS(cal.getTime());
    }

    /**
     * 年月日の文字列を日付に変換する。
     * @param yearStr 年
     * @param monthStr 月
     * @return 日付
     */
    public static Date stringYMToDate(final String yearStr, final String monthStr) {
        int year = Integer.parseInt(yearStr);
        int month = Integer.parseInt(monthStr);

        return stringYMDToDate(year, month, 1);
    }

    /**
     * 年月日の文字列を日付に変換する。
     * @param yearMonthStr 年月
     * @param dayStr 日
     * @return 日付
     */
    public static Date stringYMDToDate2(final String yearMonthStr, final String dayStr) {
        int year = Integer.parseInt(yearMonthStr.substring(0, 4));
        int month = Integer.parseInt(yearMonthStr.substring(4, 6));
        int day = Integer.parseInt(dayStr);
        Calendar cal = Calendar.getInstance(TimeZone.getTimeZone(TIMEZONE));
        cal.setLenient(false);
        cal.set(year, month - 1, day);
        return clearHMS(cal.getTime());
    }

    /**
     * Dateの年を数字(String)で返す。
     *  引数がnullのときはnullを返す。
     * @param date 日付
     * @return 年の文字列
     */
    public static String getYear(final Date date) {
        if (date == null) {
            return null;
        }
        Calendar cal = dateToCalendar(date);
        return new Integer(cal.get(Calendar.YEAR)).toString();
    }

    /**
     * Dateの月を2桁の数字(String)で返す。
     *  引数がnullのときはnullを返す。
     * @param date 日付
     * @return 月の文字列
     */
    public static String getMonth(final Date date) {
        if (date == null) {
            return null;
        }
        Calendar cal = dateToCalendar(date);
        Integer month = new Integer(cal.get(Calendar.MONTH) + 1);
        DecimalFormat df = new DecimalFormat("00");
        return df.format(month);

    }

    /**
     * Dateの日を2桁の数字(String)で返す。
     *  引数がnullのときはnullを返す。
     * @param date 日付
     * @return 日の文字列
     */
    public static String getDay(final Date date) {
        if (date == null) {
            return null;
        }
        Calendar cal = dateToCalendar(date);
        Integer day = new Integer(cal.get(Calendar.DAY_OF_MONTH));
        DecimalFormat df = new DecimalFormat("00");
        return df.format(day);
    }

    /**
     * Dateの時を2桁の数字(String)で返す。
     * 引数がnullのときはnullを返す。
     * @param date 日付
     * @return 時の文字列
     */
    public static String getHour(final Date date) {
        if (date == null) {
            return null;
        }
        Calendar cal = dateToCalendar(date);
        Integer hour = new Integer(cal.get(Calendar.HOUR_OF_DAY));
        DecimalFormat df = new DecimalFormat("00");
        return df.format(hour);
    }

    /**
     * Dateの分を2桁の数字(String)で返す。
     * 引数がnullのときはnullを返す。
     * @param date 日付
     * @return 分の文字列
     */
    public static String getMinute(final Date date) {
        if (date == null) {
            return null;
        }
        Calendar cal = dateToCalendar(date);
        Integer hour = new Integer(cal.get(Calendar.MINUTE));
        DecimalFormat df = new DecimalFormat("00");
        return df.format(hour);
    }

    /**
     * Dateの時間以下を0にセットする。
     * @param date 日付
     * @return クリアされた日付
     */
    public static Date clearHMS(final Date date) {
        if (date == null) {
            return date;
        }
        Calendar cal = dateToCalendar(date);
        clearHMS(cal);
        return cal.getTime();
    }

    /**
     * Calendarの時間以下を0にセットする。
     * @param cal カレンダーオブジェクト
     */
    private static void clearHMS(final Calendar cal) {
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
    }

    /**
     * 日付の妥当性チェック。
     * @param date 日付文字列
     * @param format チェック対象のフォーマット
     * @return チェック結果
     */
    public static boolean validDate(final String date, final String format) {
        SimpleDateFormat sdf = getConditionedSdf(format);
        try {
            sdf.parse(date);
        } catch (ParseException e) {
            return false;
        }
        return true;
    }

    /**
     * 出発日と帰宅日から旅行期間を算出して返す。
     * @param departureDay 出発日
     * @param returnDay 帰宅日
     * @return 旅行期間
     */
    public static int getPeriod(final Date departureDay, final Date returnDay) {
        int period = 0;

        if (DateUtil.dateCompare(returnDay, departureDay) >= 0) {
            period = DateUtil.diffDay(departureDay, returnDay) + 1;
        }
        return period;
    }

    /**
     * 現在より引数の月分の年月を配列で返す。
     * @param interval 期間
     * @return 年月の配列(YYYY/MM)
     */
    public static String[] getIntervalMonth(int interval) {

        String[] strIntervalMonth = new String[interval + 1];
        Calendar cal = dateToCalendar(now());

        strIntervalMonth[0] = dateToString(cal.getTime(), "yyyy/MM");

        for (int i = 1; i < interval + 1; i++) {
            cal.add(Calendar.MONTH, 1);
            strIntervalMonth = dateToString(cal.getTime(), "yyyy/MM");
        }

        return strIntervalMonth;
    }

    /**
     * 基準日から引数期間分の年(List)
     * @param kijyunDate 基準日
     * @param yearMaxLimit 期間(単位:年)
     * @return expYear(西暦年の下4ケタ)
     */
    public static ArrayList<String> getIntervalYear(Date kijyunDate, int yearMaxLimit) {

        ArrayList<String> expYear = new ArrayList<String>();

        SimpleDateFormat expfmt = new SimpleDateFormat("yyyy");
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(kijyunDate);

        expYear.add(null);
        for (int i = 1; i <= yearMaxLimit; i++) {
            expYear.add(expfmt.format(calendar.getTime()));
            calendar.add(Calendar.YEAR, 1);
        }

        return expYear;
    }

    /**
     * 基準日から引数期間分の年(List)
     * @param kijyunDate 基準日
     * @param yearMaxLimit 期間(単位:年)
     * @return expYear(西暦年の下2ケタ)
     */
    public static ArrayList<String> getTermYear(Date kijyunDate, int yearMaxLimit) {

        ArrayList<String> expYear = new ArrayList<String>();

        SimpleDateFormat expfmt = new SimpleDateFormat("yy");
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(kijyunDate);

        expYear.add(null);
        for (int i = 1; i <= yearMaxLimit; i++) {
            expYear.add(expfmt.format(calendar.getTime()));
            calendar.add(Calendar.YEAR, 1);
        }

        return expYear;
    }

    /**
     * 指定日を足した保険期間終了日を返す
     * @param date 基準日
     * @param day 日
     * @return 年月日
     */
    public static Date insurancePeriodAddDay(Date date, int day) {

        Calendar cal = dateToCalendar(date);
        cal.add(Calendar.DATE, day);
        return cal.getTime();
    }

    /**
     * 指定月を足した保険期間終了日を返す
     * @param date 基準日
     * @param month 月
     * @return 年月日
     */
    public static Date insurancePeriodAddMonth(Date date, int month) {

        if (month != 0) {
            Calendar cal = dateToCalendar(date);
            int beforeDate = cal.get(Calendar.DATE);
            cal.add(Calendar.MONTH, month);
            int afterDate = cal.get(Calendar.DATE);

            if (beforeDate == afterDate) {
                cal.add(Calendar.DATE, -1);
            }
            return cal.getTime();
        } else {
            return date;
        }
    }

    /**
     * 指定年を足した保険期間終了日を返す
     * @param date 基準日
     * @param year 年
     * @return 年月日
     */
    public static Date insurancePeriodAddYear(Date date, int year) {

        if (year != 0) {
            Calendar cal = dateToCalendar(date);
            int beforeDate = cal.get(Calendar.DATE);
            cal.add(Calendar.YEAR, year);
            int afterDate = cal.get(Calendar.DATE);

            if (beforeDate == afterDate) {
                cal.add(Calendar.DATE, -1);
            }
            return cal.getTime();
        } else {
            return date;
        }
    }

    /**
     * 指定月だけ過去の日付を返す
     * (保険期間とは考え方が異なる)
     * @param date 基準日
     * @param month 月
     * @return 年月日
     */
    public static Date insurancePeriodSubtractMonth(Date date, int month) {

        if (month != 0) {
            Calendar cal = dateToCalendar(date);
            cal.add(Calendar.MONTH, month);
            return cal.getTime();
        } else {
            return date;
        }
    }

    /**
     * 指定年だけ過去の日付を返す
     * (保険期間とは考え方が異なる)
     * @param date 基準日
     * @param year 年
     * @return 年月日
     */
    public static Date insurancePeriodSubtractYear(Date date, int year) {

        if (year != 0) {
            Calendar cal = dateToCalendar(date);
            cal.add(Calendar.YEAR, year);
            return cal.getTime();
        } else {
            return date;
        }
    }

    /**
     * 年月日時分の文字列を日付に変換する。
     * @param yearStr   年
     * @param monthStr  月
     * @param dayStr    日
     * @param hourStr   時
     * @param minuteStr 分
     * @return 日付
     * @throws Exception システムエラー
     */
    public static Date stringYMDHMToDate(final String yearStr, final String monthStr, final String dayStr,
            final String hourStr, final String minuteStr) throws Exception {
        StringBuilder strDate = new StringBuilder();

        strDate.append(yearStr).append("/");
        strDate.append(monthStr).append("/");
        strDate.append(dayStr).append(" ");
        strDate.append(hourStr).append(":");
        strDate.append(minuteStr);

        return DateUtil.stringToDate(strDate.toString(), YYYYMMDDHHMM);
    }

    /**
     * 引数によるDateの比較を行う。(比較フォーマットはYYYY/MM/DD)
     * @param aString     比較元日時文字列a
     * @param bString     比較対象日時文字列b
     * @return 1: a>b ,0: a=b, -1: a<b
     */
    public static int stringDateCompare(final String aString, final String bString) {
        Date aDate;
        Date bDate;
        try {
            aDate = DateUtil.stringToDate(aString, YYYYMMDD_2);
            bDate = DateUtil.stringToDate(bString, YYYYMMDD_2);
        } catch (ParseException e) {
            throw new RuntimeException(e.toString());
        }
        return aDate.compareTo(bDate);
    }

    /**
     * Dateを指定フォーマットのStringで返す
     * @param date Date
     * @param format フォーマット
     * @param defValue dateがnull時の値
     * @return フォーマットされたString
     */
    public static String dateToStringNVL(final Date date, final String format, final String defValue) {
        return date == null ? defValue : dateToString(date, format);
    }

    //
    //    /**
    //     * 文字列日付を日付に変更して関数を呼び出します。
    //     * <p>
    //     * 文字列日付がisEmptyの場合はnullで呼び出します。
    //     * </p>
    //     * @param date 日付
    //     * @param format フォーマット
    //     * @param consumer 処理関数
    //     */
    //    public static void stringToDate(final String date, final String format, final Consumer<? super Date> consumer)
    //    throws ParseException {
    //        consumer.accept(StringUtil.isEmpty(date) ? null : stringToDate(date, format));
    //    }

    /**
     * Dateを指定フォーマットの和暦のStringで返す (削除予定)
     * @param date Date
     * @param format フォーマット
     * @return フォーマットされたString
     */
    @Deprecated
    public static String dateToJapanString(final Date date, final String format) {
        Locale locale = new Locale("ja", "JP", "JP");
        DateFormat japaseseFormat = new SimpleDateFormat(format, locale);
        return japaseseFormat.format(date);

    }

    /**
     * 与えられた年が閏年か判定しbooleanを返す
     * @param cYear チェックする年
     * @return true"閏年である" false"閏年ではない"
     */
    public static boolean isLeapYear(int cYear) {
        if (cYear % 400 == 0) {
            return true;
        }
        if (cYear % 100 == 0) {
            return false;
        }
        if (cYear % 4 == 0) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 対象日が範囲開始日から範囲終了日の範囲内(境界日を含む)にあるか判定する。日付の時分秒以下は無視して判定する。
     *
     * @param targetDate 対象日
     * @param beginDate 範囲開始日
     * @param endDate 範囲終了日
     * @return 対象日が範囲開始日から範囲終了日の範囲内にある場合はtrue、それ以外:false
     */
    public static Boolean isWithinRange(Date targetDate, Date beginDate, Date endDate) {

        if (DateUtil.dateCompare(beginDate, targetDate) <= 0
                && DateUtil.dateCompare(targetDate, endDate) <= 0) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 日付の加減算を行う。
     * <p>
     * fieldがCalendar.YEARの場合は年単位、Calendar.MONTHの場合は月単位の計算を行う。<br>
     * 以下に示す通り、計算後の日付の調整を行うため、年単位、月単位以外の計算目的での使用は推奨しない。
     * <p>
     * 通常の日付加減算とは異なり、日付が月末日である場合、計算後の日付も月末日にする。 詳細は、下記例を参照。
     *
     * <pre>
     *   例)
     *    addDateInsurance(2016/2/27, Calendar.MONTH, -1) ⇒ 2016/1/27
     *    addDateInsurance(2016/2/29, Calendar.MONTH, -1) ⇒ 2016/1/31
     *    addDateInsurance(2016/2/29, Calendar.YEAR, -1) ⇒ 2015/2/28
     * </pre>
     *
     * @param date 日付
     * @param field Calendarクラスのフィールド。
     * @param forward 加算日付。fieldで指定された単位で日付計算する。
     * @return 加算後の日付
     */
    public static Date addDateInsurance(Date date, int field, int forward) {

        Calendar cal = DateUtil.dateToCalendar(date);

        int day = Integer.parseInt(DateUtil.getDay(date));
        int lastDayOfMonth = cal.getActualMaximum(Calendar.DATE);

        // 日付計算
        cal.add(field, forward);

        // 日付が月末日の場合、計算後の日付を月末日にする
        if (day == lastDayOfMonth) {
            cal.set(Calendar.DATE, cal.getActualMaximum(Calendar.DATE));
        }

        return cal.getTime();
    }

    /**
     * 次年度の4月1日を返す。
     * @param date 日付
     * @return 次年度の4月1日
     */
    public static Date getNendoDate(Date date) {

        Calendar cal = DateUtil.dateToCalendar(date);
        int year = cal.get(Calendar.YEAR);
        int month = new Integer(cal.get(Calendar.MONTH) + 1);
        if (month > 3) {
            year += 1;
        }
        return DateUtil.stringYMDToDate(year, 4, 1);
    }

    /**
     * 可変数の日付の中から最小値を返す。
     * @param date 日付
     * @return 最小値
     */
    public static Date min(Date... date) {
        return Stream.of(date).filter(d -> d != null).min(Date::compareTo).orElse(null);
    }

    /**
     * 可変数の日付の中から最大値を返す。
     * @param date 日付
     * @return 最大値
     */
    public static Date max(Date... date) {
        return Stream.of(date).filter(d -> d != null).max(Date::compareTo).orElse(null);
    }

    /**
     * dateに時刻を設定したDateオブジェクトを返す。
     *
     * @param date 編集元となる日付
     * @param hhmmss 日付に設定する時刻(HHmmss形式)の文字列
     * @return 編集元の日付に時刻を設定したDateオブジェクト
     * @throws ParseException 日付に設定する時刻がHHmmss形式以外の場合
     */
    public static Date editHMS(Date date, String hhmmss) throws ParseException {

        String datestr = dateToString(date, DateUtil.YYYYMMDD);

        return stringToDate(datestr + hhmmss, DateUtil.YYYYMMDDHHMMSS_2);
    }

    /**
     * 対象営業日取得
     *
     * @param inputDate      基準日
     * @param selectMonthInt 指定月(例:-1:前月、0:当月、1:次月)
     * @param selectDateInt  指定営業日(1:第1営業日、2:第2営業日、-2:"指定月"の前月末営業日)
     * @param mHolydayList   休業日リスト(nullの場合本メソッドでマスタから取得)
     * @return Date 処理結果
     * @throws Exception
     */
    public static Date getEigyoDate(final Date inputDate, final int selectMonthInt,
            final int selectDateInt, final List<Map<String, Object>> mHolydayList) throws Exception {

        // 基準日と指定日チェックnullを返す
        if (inputDate == null || selectDateInt == 0) {
            return null;
        }

        int sInt = selectDateInt;
        int dInt = 0;
        Date eigyoDate = null;

        if (sInt < 0) {
            dInt--;
        } else {
            dInt++;
        }

        // 基準年月日を取得
        Calendar cal = dateToCalendar(inputDate);
        cal.setTime(inputDate);

        int year = cal.get(Calendar.YEAR);
        int month = cal.get(Calendar.MONTH);
        int date = 1;

        cal.set(year, month, date, 0, 0, 0);

        // 対象月を設定
        cal.add(Calendar.MONTH, selectMonthInt);

        // 休業日リストを取得
        List<Map<String, Object>> holidayList = mHolydayList;

        // 休業日リストがNULLの場合休業日マスタから取得
        if (holidayList == null) {
            holidayList = getHoliday(cal);
        }

        while (sInt != 0) {

            // 営業日取得処理
            eigyoDate = cal.getTime();

            int youbi = cal.get(Calendar.DAY_OF_WEEK);
            // 土曜日、または日曜日以外のチェック
            if (!(youbi == Calendar.SATURDAY || youbi == Calendar.SUNDAY)) {
                // 休業日のチェック(1の場合、休業日)
                if (validEigyoDate(eigyoDate, holidayList)) {
                    sInt = sInt - dInt;
                }
            }

            if (sInt != 0) {
                cal.add(Calendar.DATE, dInt);
            }
        }

        return cal.getTime();
    }

    /**
     * (基準月+指定月)+前後1カ月分の休業日取得
     *
     * @param inputDate 基準日
     * @return             休業日一覧
     * @throws Exception
     */
    public static List<Map<String, Object>> getHoliday(final Calendar inputDate) throws Exception {

        // 休業日マスタからデータ取得
        ILogic iLogic = LogicMap.getLogic(UDCM00410C02Logic.class.getAnnotation(LogicKey.class).name());

        // 検索条件
        Map<String, Object> localMap = new HashMap<String, Object>();
        localMap.put("procDate", inputDate);
        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put(iLogic.getLogicParamKey(), localMap);
        iLogic.execute(paramMap);

        // 検索結果
        Map<String, Object> rs = iLogic.getResult().getOutputMap();

        // 休業日マスタSELECT結果取得
        return ConvertUtil.convert(rs.get(iLogic.getLogicResultKey()),
                new TypeReference<List<Map<String, Object>>>() {
                });
    }

    /**
     * 休業日チェック。
     *
     * @param base 日付
     * @param mHolydayList 休業日リスト
     * @return チェック結果
     */
    public static boolean validEigyoDate(final Date base, List<Map<String, Object>> mHolydayList) {

        for (Map<String, Object> mHolydayMap : mHolydayList) {
            if (Arrays.asList(mHolydayMap).contains(base)) {
                return false;
            }
        }

        return true;
    }

    /**
     * 保険期間と保険期間単位を返す
     *
     * @param hokenStartDate 保険始期年月日
     * @param hokenEndDate   保険終期年月日
     * @return 保険期間、保険期間単位
     */
    public static HokenKikanBean getHokenTaniKikan(Date hokenStartDate,
            Date hokenEndDate) {

        HokenKikanBean dateUtilBean = new HokenKikanBean();

        if (hokenStartDate == null) {
            dateUtilBean.setResult(false);
            return dateUtilBean;
        }

        if (hokenEndDate == null) {
            dateUtilBean.setResult(false);
            return dateUtilBean;
        }

        // Calendarクラスのインスタンスを生成
        Calendar start = Calendar.getInstance();
        Calendar end = Calendar.getInstance();
        // Date型からカレンダー型に変換
        start.setTime(hokenStartDate);
        end.setTime(hokenEndDate);

        // 保険始期年月日と保険終期年月日の年・月・日取得
        int startY = start.get(Calendar.YEAR);
        int startM = start.get(Calendar.MONTH) + 1;
        int startD = start.get(Calendar.DATE);

        int endY = end.get(Calendar.YEAR);
        int endM = end.get(Calendar.MONTH) + 1;
        int endD = end.get(Calendar.DATE);

        // Date型からStringへフォーマット

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");

        String startYMD = sdf.format(hokenStartDate);
        String endYMD = sdf.format(hokenEndDate);

        // 保険期間単位
        String hokenKikanTani;
        // 保険期間
        int hokenKikan;

        // 保険始期年月の末日を求める
        Calendar startlastCalen = Calendar.getInstance();
        startlastCalen.clear();
        // Calendarクラスでの月は1~12ではなく0~11で表される為、startMを-1
        startlastCalen.set(startY, startM - 1, startD);
        int startlast = startlastCalen.getActualMaximum(Calendar.DATE);

        // 保険終期年月の末日を求める
        Calendar endlastCalen = Calendar.getInstance();
        endlastCalen.clear();
        endlastCalen.set(endY, endM - 1, endD);
        int endlast = endlastCalen.getActualMaximum(Calendar.DATE);

        // 保険期間単位を判別(年)
        // 保険始期日の月と保険終期日の月が一致し,保険始期日と保険終期日が月末日であること
        // または、保険始期日の月日と保険終期日の月日が一致し、保険始期日と保険始期日の月末日が異なること
        if ((!startYMD.equals(endYMD)) && (startM == endM) && ((startD == startlast && endD == endlast)
                || ((startD == endD) && (startD != startlast)))) {

            // 年単位の契約の場合
            hokenKikanTani = "Y";
            hokenKikan = endY - startY;

            // 保険期間単位を判別(月)
            // 保険始期日の月と保険終期日の月が異なり,保険始期日と保険終期日が一致し、保険始期日と保険始期日の月末日が異なること
            // または、保険始期日の月と保険終期日の月が異なり、保険始期日と保険終期日が月末日であること
            // または、保険始期日の月と保険終期日の月が異なり、保険終期日が2月で保険終期日が月末日であり、保険始期日が29もしくは30日であること。
        } else if ((startM != endM)
                && ((startD == endD) && (startD != startlast)
                        || ((startD == startlast) && (endD == endlast))
                        || (endM == 2) && (endD == endlast)
                                && ((startD == 29) || (startD == 30)))) {

            // 月単位の契約の場合
            // Date型作成(YYYY/MM/DD)
            Date frome = null;
            Date to = null;

            try {
                frome = DateFormat.getDateInstance().parse(startYMD);
                to = DateFormat.getDateInstance().parse(endYMD);
            } catch (ParseException e) {
                dateUtilBean.setResult(false);
                return dateUtilBean;
            }

            // Calendarの時間を指定されたDateに設定
            Calendar calFrom = Calendar.getInstance();
            calFrom.setTime(frome);
            calFrom.set(Calendar.DATE, 1);

            Calendar calTo = Calendar.getInstance();
            calTo.setTime(to);
            calTo.set(Calendar.DATE, 1);

            // 差分の月数算出
            int count = 0;
            while (calFrom.before(calTo)) {
                calFrom.add(Calendar.MONTH, 1);
                count++;
            }
            hokenKikanTani = "M";
            hokenKikan = count;

        } else {
            // 日単位の契約の場合
            Date dateTo = null;
            Date dateFrom = null;

            // 日付を作成
            try {
                dateFrom = sdf.parse(startYMD);
                dateTo = sdf.parse(endYMD);
            } catch (ParseException e) {
                dateUtilBean.setResult(false);
                return dateUtilBean;
            }

            // 日付をlong値に変換。
            long dateTimeTo = dateTo.getTime();
            long dateTimeFrom = dateFrom.getTime();

            // 差分の日数を算出。
            long dayDiff = (dateTimeTo - dateTimeFrom) / (1000 * 60 * 60 * 24) + 1;
            // 月単位の契約の場合
            hokenKikanTani = "D";
            hokenKikan = (int) dayDiff;
        }

        String hokenkikanKbn = "";
        // 保険期間区分の設定
        switch (hokenKikanTani) {
        case "Y":
            switch (hokenKikan) {
            case 1:
                hokenkikanKbn = "3";
                break;
            case 2:
                hokenkikanKbn = "4";
                break;
            case 3:
                hokenkikanKbn = "5";
                break;
            case 4:
                hokenkikanKbn = "6";
                break;
            default:
                hokenkikanKbn = "7";
                break;
            }
            break;
        case "M":
            if (hokenKikan <= 1) {
                hokenkikanKbn = "1";
            } else if (hokenKikan <= 3) {
                hokenkikanKbn = "2";
            } else if (hokenKikan <= 12) {
                hokenkikanKbn = "3";
            } else if (hokenKikan <= 24) {
                hokenkikanKbn = "4";
            } else if (hokenKikan <= 36) {
                hokenkikanKbn = "5";
            } else if (hokenKikan <= 48) {
                hokenkikanKbn = "6";
            } else {
                hokenkikanKbn = "7";
            }
            break;
        case "D":
            if (hokenKikan <= 31) {
                hokenkikanKbn = "1";
            } else if (hokenKikan <= 93) {
                hokenkikanKbn = "2";
            } else if (hokenKikan <= 365) {
                hokenkikanKbn = "3";
            } else if (hokenKikan <= 730) {
                hokenkikanKbn = "4";
            } else if (hokenKikan <= 1095) {
                hokenkikanKbn = "5";
            } else if (hokenKikan <= 1460) {
                hokenkikanKbn = "6";
            } else {
                hokenkikanKbn = "7";
            }
            break;
        }

        dateUtilBean.setHokenKikan(hokenKikan);
        dateUtilBean.setHokenKikanTani(hokenKikanTani);
        dateUtilBean.setHokenKikanKbn(hokenkikanKbn);
        dateUtilBean.setResult(true);

        return dateUtilBean;

    }

    /**
     * 該当月の1日を取得する
     *
     * @param baseDate 基準日
     * @return 該当月1日
     * @throws Exception
     *             システムエラー
     *
     */
    public static Date getFirstDate(Date baseDate) throws Exception {

        Calendar cal = Calendar.getInstance();
        cal.setTime(baseDate);
        cal.set(Calendar.DATE, 1);
        Date firstDate = cal.getTime();

        return firstDate;
    }

    /**
    * 該当月の末日を取得する
    *
    * @param baseDate 基準日
    * @return 該当月末日
    * @throws Exception
    *             システムエラー
    *
    */
    public static Date getEndDate(Date baseDate) throws Exception {

        Calendar cal = Calendar.getInstance();
        cal.setTime(baseDate);
        int lastDay = cal.getActualMaximum(Calendar.DATE);
        cal.set(Calendar.DATE, lastDay);
        Date endDate = cal.getTime();

        return endDate;
    }

    /**
     * 引数で渡された日付の時間以下の各フィールドに最大値を設定して返す。
     * <pre>
     * 以下の値が設定される
     * 時間:23
     * 分:59
     * 秒:59
     * ミリ秒:999
     * </pre>
     * @param date 日付
     * @return 日付
     * @throws Exception
     */
    public static Date getMaxHMS(Date date) throws Exception {
        if (date == null) {
            return null;
        }

        Calendar cal = dateToCalendar(date);
        cal.set(Calendar.HOUR_OF_DAY, cal.getActualMaximum(Calendar.HOUR_OF_DAY));
        cal.set(Calendar.MINUTE, cal.getActualMaximum(Calendar.MINUTE));
        cal.set(Calendar.SECOND, cal.getActualMaximum(Calendar.SECOND));
        cal.set(Calendar.MILLISECOND, cal.getActualMaximum(Calendar.MILLISECOND));

        return cal.getTime();
    }

    /**
     * 引数で渡された日付が属する四半期の初日を返す。
     * @param date 基準日
     * @return 基準日が属する四半期の初日
     * @throws Exception
     */
    public static Date getShihankiFirstDay(Date date) throws Exception {
        if (date == null) {
            return null;
        }
        // 年
        Integer year = Integer.parseInt(dateToString(date, YYYY));
        // 月
        Integer month = Integer.parseInt(dateToString(date, M));

        if (month < 4) {
            // 第四四半期:1月~3月
            return stringYMDToDate(year, 1, 1);
        } else if (month < 7) {
            // 第一四半期:4月~6月
            return stringYMDToDate(year, 4, 1);
        } else if (month < 10) {
            // 第二四半期:7月~9月
            return stringYMDToDate(year, 7, 1);
        } else {
            // 第三四半期:10月~12月
            return stringYMDToDate(year, 10, 1);
        }
    }

    /**
     * 引数で渡された日付が属する四半期の最終日を返す。
     * @param date 基準日
     * @return 基準日が属する四半期の末日
     * @throws Exception
     */
    public static Date getShihankiEndDay(Date date) throws Exception {
        if (date == null) {
            return null;
        }

        // 年
        Integer year = Integer.parseInt(dateToString(date, YYYY));
        // 月
        Integer month = Integer.parseInt(dateToString(date, M));

        if (month < 4) {
            // 第四四半期:1月~3月
            return getEndDate(stringYMDToDate(year, 3, 1));
        } else if (month < 7) {
            // 第一四半期:4月~6月
            return getEndDate(stringYMDToDate(year, 6, 1));
        } else if (month < 10) {
            // 第二四半期:7月~9月
            return getEndDate(stringYMDToDate(year, 9, 1));
        } else {
            // 第三四半期:10月~12月
            return getEndDate(stringYMDToDate(year, 12, 1));
        }
    }

    /**
     * ミリ秒数の文字列を日付に変更して関数を呼び出します。
     *
     * @param dateLongStr ミリ秒数の文字列
     * @return 変換結果
     */
    public static Date longStrToDate(final String dateLongStr) {
        try {
            return new Date(Long.parseLong(dateLongStr));
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * ミリ秒数の文字列を日付に変更して関数を呼び出します。
     *
     * @param dateLongStr ミリ秒数の文字列
     * @param format フォーマット
     * @return 変換結果
     */
    public static String longStrToString(final String dateLongStr, final String format) {
        try {
            return getConditionedSdf(format).format(longStrToDate(dateLongStr));
        } catch (Exception e) {
            return dateLongStr;
        }
    }

    /**
     * Dateを指定フォーマットの和暦のStringで返す
     * @param date Date
     * @param format フォーマット
     * @return フォーマットされたString
     */
    public static String dateToWarekiString(final Date date, final String format) {
        if (date == null) {
            return null;
        }

        Locale locale = new Locale("ja", "JP", "JP");
        DateFormat japaseseFormat = new SimpleDateFormat(format, locale);
        return japaseseFormat.format(date);

    }

    /**
     * 日付のLong値を取得する
     * @param date 書式付き日付
     * @return 日付のLong値
     */
    public static Long getLongVlueDate(String date) {
        try {
            if (DATE_PATTERN_1.matcher(date).matches()) {
                return stringToDate(date, YYYYMMDD_2).getTime();
            } else if (DATE_PATTERN_2.matcher(date).matches()) {
                return stringToDate(date, YYYYMMDD_WITH_HYPHEN).getTime();
            } else if (DATE_PATTERN_3.matcher(date).matches()) {
                return stringToDate(date, YYYYMMDD).getTime();
            } else {
                return Long.valueOf(date);
            }
        } catch (Exception e) {
            return null;
        }
    }

}

◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆


package jp.co.ji.jbaas.util.common;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.IntStream;

import com.fasterxml.jackson.core.type.TypeReference;

import jp.co.ji.jbaas.common.MapKeyConst;
import jp.co.ji.jbaas.common.StringConst;
import jp.co.ji.jbaas.dao.DAOFactory;
import jp.co.ji.model.fusss.common.MMojihenkanmst;

/**
* 文字変換ユーティリティ
*
* @author NSD
*
*/
public class MojiHenkanUtil {

    /** カスタムメソッド */
    private static final String MAPPERPATH = "jp.co.ji.sql.custom.fusss.common.MMojihenkanmstMapper.selectByPKey";

    /** 全角カナ→ローマ字変換定義 */
    private static final String KARRAY[][] = { { "キュウ", "kyu" },
            { "キョウ", "kyo" },
            { "シュウ", "shu" },
            { "ショウ", "sho" },
            { "チュウ", "chu" },
            { "チョウ", "cho" },
            { "ニュウ", "nyu" },
            { "ニョウ", "nyo" },
            { "ヒュウ", "hyu" },
            { "ヒョウ", "hyo" },
            { "ミュウ", "myu" },
            { "ミョウ", "myo" },
            { "リュウ", "ryu" },
            { "リョウ", "ryo" },
            { "ギュウ", "gyu" },
            { "ギョウ", "gyo" },
            { "ジュウ", "ju" },
            { "ジョウ", "jo" },
            { "ビュウ", "byu" },
            { "ビョウ", "byo" },
            { "ピュウ", "pyu" },
            { "ピョウ", "pyo" },
            { "キェ", "kye" },
            { "キャ", "kya" },
            { "キュ", "kyu" },
            { "キョ", "kyo" },
            { "ギィ", "gyi" },
            { "ギェ", "gye" },
            { "ギャ", "gya" },
            { "ギュ", "gyu" },
            { "ギョ", "gyo" },
            { "シィ", "syi" },
            { "シェ", "she" },
            { "シャ", "sha" },
            { "シュ", "shu" },
            { "ショ", "sho" },
            { "ジィ", "zyi" },
            { "ジェ", "je" },
            { "ジャ", "ja" },
            { "ジュ", "ju" },
            { "ジョ", "jo" },
            { "チィ", "tyi" },
            { "チェ", "che" },
            { "チャ", "cha" },
            { "チュ", "chu" },
            { "チョ", "cho" },
            { "ヂィ", "dyi" },
            { "ヂェ", "dye" },
            { "ヂャ", "dya" },
            { "ヂュ", "dyu" },
            { "ヂョ", "dyo" },
            { "ニィ", "nyi" },
            { "ニェ", "nye" },
            { "ニャ", "nya" },
            { "ニュ", "nyu" },
            { "ニョ", "nyo" },
            { "ヒィ", "hyi" },
            { "ヒェ", "hye" },
            { "ヒャ", "hya" },
            { "ヒュ", "hyu" },
            { "ヒョ", "hyo" },
            { "ビィ", "byi" },
            { "ビェ", "bye" },
            { "ビャ", "bya" },
            { "ビュ", "byu" },
            { "ビョ", "byo" },
            { "ピィ", "pyi" },
            { "ピェ", "pye" },
            { "ピャ", "pya" },
            { "ピュ", "pyu" },
            { "ピョ", "pyo" },
            { "ファ", "fa" },
            { "フィ", "fi" },
            { "フェ", "fe" },
            { "フォ", "fo" },
            { "ミィ", "myi" },
            { "ミェ", "mye" },
            { "ミャ", "mya" },
            { "ミュ", "myu" },
            { "ミョ", "myo" },
            { "リィ", "ryi" },
            { "リェ", "rye" },
            { "リャ", "rya" },
            { "リュ", "ryu" },
            { "リョ", "ryo" },
            { "オウ", "o" },
            { "オオ", "o" },
            { "コウ", "ko" },
            { "ソウ", "so" },
            { "トウ", "to" },
            { "ノウ", "no" },
            { "ホウ", "ho" },
            { "モウ", "mo" },
            { "ヨウ", "yo" },
            { "ロウ", "ro" },
            { "ゴウ", "go" },
            { "ゾウ", "zo" },
            { "ドウ", "do" },
            { "ボウ", "bo" },
            { "ポウ", "po" },
            { "ウウ", "u" },
            { "クウ", "ku" },
            { "スウ", "su" },
            { "ツウ", "tsu" },
            { "ヌウ", "nu" },
            { "フウ", "fu" },
            { "ムウ", "mu" },
            { "ユウ", "yu" },
            { "ルウ", "ru" },
            { "グウ", "gu" },
            { "ズウ", "zu" },
            { "ヅウ", "zu" },
            { "ブウ", "bu" },
            { "プウ", "pu" },
            { "ジェ", "jie" },
            { "ティ", "tei" },
            { "ディ", "dei" },
            { "デュ", "deyu" },
            { "ファ", "fua" },
            { "フィ", "fui" },
            { "フェ", "fue" },
            { "フォ", "fuo" },
            { "ヴァ", "bva" },
            { "ヴィ", "bui" },
            { "ヴェ", "be" },
            { "ヴォ", "buo" },
            { "ァ", "xa" },
            { "ア", "a" },
            { "ィ", "xi" },
            { "イ", "i" },
            { "ゥ", "xu" },
            { "ウ", "u" },
            { "ェ", "xe" },
            { "エ", "e" },
            { "ォ", "xo" },
            { "オ", "o" },
            { "カ", "ka" },
            { "ガ", "ga" },
            { "キ", "ki" },
            { "ギ", "gi" },
            { "ク", "ku" },
            { "グ", "gu" },
            { "ケ", "ke" },
            { "ゲ", "ge" },
            { "コ", "ko" },
            { "ゴ", "go" },
            { "サ", "sa" },
            { "ザ", "za" },
            { "シ", "shi" },
            { "ジ", "ji" },
            { "ス", "su" },
            { "ズ", "zu" },
            { "セ", "se" },
            { "ゼ", "ze" },
            { "ソ", "so" },
            { "ゾ", "zo" },
            { "タ", "ta" },
            { "ダ", "da" },
            { "チ", "chi" },
            { "ヂ", "di" },
            { "ツ", "tsu" },
            { "ヅ", "du" },
            { "テ", "te" },
            { "デ", "de" },
            { "ト", "to" },
            { "ド", "do" },
            { "ナ", "na" },
            { "ニ", "ni" },
            { "ヌ", "nu" },
            { "ネ", "ne" },
            { "ノ", "no" },
            { "ハ", "ha" },
            { "バ", "ba" },
            { "パ", "pa" },
            { "ヒ", "hi" },
            { "ビ", "bi" },
            { "ピ", "pi" },
            { "フ", "fu" },
            { "ブ", "bu" },
            { "プ", "pu" },
            { "ヘ", "he" },
            { "ベ", "be" },
            { "ペ", "pe" },
            { "ホ", "ho" },
            { "ボ", "bo" },
            { "ポ", "po" },
            { "マ", "ma" },
            { "ミ", "mi" },
            { "ム", "mu" },
            { "メ", "me" },
            { "モ", "mo" },
            { "ャ", "xya" },
            { "ヤ", "ya" },
            { "ュ", "xyu" },
            { "ユ", "yu" },
            { "ョ", "xyo" },
            { "ヨ", "yo" },
            { "ラ", "ra" },
            { "リ", "ri" },
            { "ル", "ru" },
            { "レ", "re" },
            { "ロ", "ro" },
            { "ワ", "wa" },
            { "ヰ", "wi" },
            { "ヱ", "we" },
            { "ン", "n" },
            { "ヲ", "o" },
            { "ヴ", "bu" },
            { " ", " " }
    };

    /** ローマ字→全角カナ変換定義 */
    private static final String RARRAY[][] = {
            { "bva", "ヴァ" },
            { "bya", "ビャ" },
            { "bye", "ビェ" },
            { "byi", "ビィ" },
            { "byo", "ビョ" },
            { "byu", "ビュ" },
            { "cha", "チャ" },
            { "che", "チェ" },
            { "chi", "チ" },
            { "cho", "チョ" },
            { "chu", "チュ" },
            { "dya", "ヂャ" },
            { "dye", "ヂェ" },
            { "dyi", "ヂィ" },
            { "dyo", "ヂョ" },
            { "dyu", "ヂュ" },
            { "gya", "ギャ" },
            { "gye", "ギェ" },
            { "gyi", "ギィ" },
            { "gyo", "ギョ" },
            { "gyu", "ギュ" },
            { "hya", "ヒャ" },
            { "hye", "ヒェ" },
            { "hyi", "ヒィ" },
            { "hyo", "ヒョ" },
            { "hyu", "ヒュ" },
            { "kya", "キャ" },
            { "kye", "キェ" },
            { "kyi", "キィ" },
            { "kyo", "キョ" },
            { "kyu", "キュ" },
            { "mya", "ミャ" },
            { "mye", "ミェ" },
            { "myi", "ミィ" },
            { "myo", "ミョ" },
            { "myu", "ミュ" },
            { "nya", "ニャ" },
            { "nye", "ニェ" },
            { "nyi", "ニィ" },
            { "nyo", "ニョ" },
            { "nyu", "ニュ" },
            { "pya", "ピャ" },
            { "pye", "ピェ" },
            { "pyi", "ピィ" },
            { "pyo", "ピョ" },
            { "pyu", "ピュ" },
            { "rya", "リャ" },
            { "rye", "リェ" },
            { "ryi", "リィ" },
            { "ryo", "リョ" },
            { "ryu", "リュ" },
            { "sha", "シャ" },
            { "she", "シェ" },
            { "shi", "シ" },
            { "sho", "ショ" },
            { "shu", "シュ" },
            { "syi", "シィ" },
            { "tsu", "ツ" },
            { "tyi", "チィ" },
            { "xya", "ャ" },
            { "xyo", "ョ" },
            { "xyu", "ュ" },
            { "zyi", "ジィ" },
            { "sya", "シャ" },
            { "syu", "シュ" },
            { "syo", "ショ" },
            { "tya", "チャ" },
            { "tyu", "チュ" },
            { "tyo", "チョ" },
            { "ba", "バ" },
            { "be", "ベ" },
            { "bi", "ビ" },
            { "bo", "ボ" },
            { "bu", "ブ" },
            { "da", "ダ" },
            { "de", "デ" },
            { "di", "ヂ" },
            { "do", "ド" },
            { "du", "ヅ" },
            { "fa", "ファ" },
            { "fe", "フェ" },
            { "fi", "フィ" },
            { "fo", "フォ" },
            { "fu", "フ" },
            { "ga", "ガ" },
            { "ge", "ゲ" },
            { "gi", "ギ" },
            { "go", "ゴ" },
            { "gu", "グ" },
            { "ha", "ハ" },
            { "he", "ヘ" },
            { "hi", "ヒ" },
            { "ho", "ホ" },
            { "ja", "ジャ" },
            { "je", "ジェ" },
            { "ji", "ジ" },
            { "jo", "ジョ" },
            { "ju", "ジュ" },
            { "ka", "カ" },
            { "ke", "ケ" },
            { "ki", "キ" },
            { "ko", "コ" },
            { "ku", "ク" },
            { "ma", "マ" },
            { "me", "メ" },
            { "mi", "ミ" },
            { "mo", "モ" },
            { "mu", "ム" },
            { "na", "ナ" },
            { "ne", "ネ" },
            { "ni", "ニ" },
            { "no", "ノ" },
            { "nu", "ヌ" },
            { "pa", "パ" },
            { "pe", "ペ" },
            { "pi", "ピ" },
            { "po", "ポ" },
            { "pu", "プ" },
            { "ra", "ラ" },
            { "re", "レ" },
            { "ri", "リ" },
            { "ro", "ロ" },
            { "ru", "ル" },
            { "sa", "サ" },
            { "se", "セ" },
            { "so", "ソ" },
            { "su", "ス" },
            { "ta", "タ" },
            { "te", "テ" },
            { "to", "ト" },
            { "wa", "ワ" },
            { "we", "ヱ" },
            { "wi", "ヰ" },
            { "wo", "ヲ" },
            { "xa", "ァ" },
            { "xe", "ェ" },
            { "xi", "ィ" },
            { "xo", "ォ" },
            { "xu", "ゥ" },
            { "ya", "ヤ" },
            { "yo", "ヨ" },
            { "yu", "ユ" },
            { "za", "ザ" },
            { "ze", "ゼ" },
            { "zo", "ゾ" },
            { "zu", "ズ" },
            { "si", "シ" },
            { "ti", "チ" },
            { "tu", "ツ" },
            { "hu", "フ" },
            { "wo", "オ" },
            { "zi", "ジ" },
            { "di", "ヂ" },
            { "du", "ヅ" },
            { "je", "ジェ" },
            { "a", "ア" },
            { "e", "エ" },
            { "i", "イ" },
            { "n", "ン" },
            { "o", "オ" },
            { "u", "ウ" },
            { " ", " " }

    };

    /** 文字コード */
    public enum CharsetEnum {

        SJIS("SJIS"), // SJIS

        MS932("MS932"),; // MS932

        private final String mojicode;

        /**
         * 初期化の文字コード設定
         * @param mojicode 文字コード
         */
        CharsetEnum(final String mojicode) {
            this.mojicode = mojicode;
        }

        /** 設定された値を返す */
        @Override
        public String toString() {
            return this.mojicode;
        }
    }

    /**
     * コンストラクタ
     * 本クラスのインスタンスを作成させないため、privateのコンストラクタ
     */
    private MojiHenkanUtil() {
    }

    /**
    *
    * 指定された文字コードにより文字コード変換(あふれ切捨て処理なし)
    * 指定の文字コードがNULLの場合、デフォルトのSJISで変換
    *
    * @param henkanMoto 変換元文字列
    * @param charset 文字コード
    * @return 変換後文字列
    * @throws Exception
    *
    */
    public static String converMojiretsuByHenkanmstByCharset(String henkanMoto, CharsetEnum charset) throws Exception {
        return converMojiretsuByHenkanmstByCharset(henkanMoto, charset, null);
    }

    /**
    *
    * 指定された文字コードにより文字変換
    * 指定の文字コードがNULLの場合、デフォルトのSJISで変換
    *
    * @param henkanMoto 変換元文字列
    * @param charset 文字コード
    * @param digits 桁数
    * @return 変換後文字列
    * @throws Exception
    *
    */
    public static String converMojiretsuByHenkanmstByCharset(String henkanMoto, CharsetEnum charset, Integer digits)
            throws Exception {

        // 文字コード指定しない場合、デフォルトSJISを設定
        if (null == charset) {
            charset = CharsetEnum.SJIS;
        }

        Map<String, Object> conditionMap = new HashMap<String, Object>();
        conditionMap.put(MapKeyConst.MOJICD, charset.toString());

        // 返却
        return converMojiretsuByHenkanmst(henkanMoto, digits, conditionMap);
    }

    /**
     *
     * SJIS文字コードにより文字変換(あふれ切捨て処理なし)
     *
     * @param henkanMoto 変換元文字列
     * @return 変換後文字列
     * @throws Exception
     *
     */
    public static String converMojiretsuByHenkanmst(String henkanMoto) throws Exception {
        return converMojiretsuByHenkanmst(henkanMoto, null);
    }

    /**
     *
     * SJIS文字コードと規定桁数により文字変換
     *
     * @param henkanMoto 変換元文字列
     * @param digits 規定桁数
     * @return 変換後文字列
     * @throws Exception
     *
     */
    public static String converMojiretsuByHenkanmst(String henkanMoto, Integer digits) throws Exception {

        Map<String, Object> conditionMap = new HashMap<String, Object>();
        // デフォルトSJISを設定
        conditionMap.put(MapKeyConst.MOJICD, MojiHenkanUtil.CharsetEnum.SJIS.toString());
        // 返却
        return converMojiretsuByHenkanmst(henkanMoto, digits, conditionMap);
    }

    /**
     *
     * SJIS文字コードと規定桁数により文字変換
     *
     * @param henkanMoto 変換元文字列
     * @param digits 規定桁数
     * @param conditionMap 検索条件
     * @return 変換後文字列
     * @throws Exception
     *
     */
    private static String converMojiretsuByHenkanmst(String henkanMoto, Integer digits,
            Map<String, Object> conditionMap) throws Exception {

        // 変換元文字列がなし場合直接返却
        if (StringUtil.isEmpty(henkanMoto)) {
            return henkanMoto;
        }

        // 変換必要文字リスト取得
        List<String> queryList = getHenkanMotoList(henkanMoto, conditionMap.get(MapKeyConst.MOJICD).toString());

        // 変換必要ない場合、直接返却
        if (ListUtil.isEmpty(queryList)) {
            if (null != digits && 0 >= digits) {
                return "";
            } else if (null != digits && henkanMoto.length() > digits) {
                henkanMoto = henkanMoto.substring(0, digits);
            }
            return henkanMoto;
        }

        // 変換元リストにより変換後リスト取得
        List<MMojihenkanmst> rsList = getHenkanAfterList(queryList, conditionMap);

        // 変換元文字列を変換し、変換後文字列取得
        String henkanSaki = getResultString(henkanMoto, queryList, rsList);

        // 規定桁数によりあふれ切捨て処理を行う
        if (null != digits && 0 >= digits) {
            return "";
        } else if (null != digits && henkanSaki.length() > digits) {
            henkanSaki = henkanSaki.substring(0, digits);
        }
        // 返却
        return henkanSaki;
    }

    /**
    *
    * 全角カナ→ローマ字文字変換
    *
    * @param zenkana 変換元文字列
    * @return 変換後文字列
    * @throws Exception
    *
    */
    public static String convertZenkanaToRomaji(String zenkana) throws Exception {

        int i = 0;
        int now = 0;
        int max = zenkana.length();
        int addCount = 0;
        Boolean tuFlg = false;
        Boolean nFlg = false;
        String targetStr;
        String cnvStr = null;
        StringBuilder sbRomaji = new StringBuilder();

        // 破裂音子音
        String regex = "[bmp]";
        Pattern p = Pattern.compile(regex);

        // 全角カナ→ローマ字文字変換
        while (now < max) {
            cnvStr = null;
            tuFlg = false;
            nFlg = false;
            addCount = 1;

            // 先頭が"ッ"か判定
            targetStr = zenkana.substring(now, now + 1);
            // 先頭が"ッ"か判定
            if (targetStr.equals("ッ")) {
                now += 1;
                tuFlg = true;
            } else if (targetStr.equals("ン")) {
                // 先頭が"ン"か判定
                now += 1;
                nFlg = true;
            }

            // カナ文字ローマ字変換判定
            for (i = 3; i > 0; i--) {
                if (max - now >= i && cnvStr == null) {
                    cnvStr = convertByArray(zenkana.substring(now, now + i), KARRAY);

                    if (cnvStr != null) {
                        addCount = i;
                        break;
                    }
                }
            }
            now += addCount;

            // 変換文字の結合
            if (cnvStr != null && cnvStr.length() > 0) {
                // "ッ"の場合は次の先頭文字を重ねる
                if (tuFlg == true) {
                    sbRomaji.append(cnvStr.substring(0, 1));
                } else if (nFlg == true) {
                    // "ン"+破裂音"b""m""p"の場合は"m"に変換する
                    Matcher m = p.matcher(cnvStr.substring(0, 1));
                    if (m.find()) {
                        sbRomaji.append("m");
                    } else {
                        // "ン"+破裂音以外の場合は"n"に変換する
                        sbRomaji.append("n");
                    }
                }
                sbRomaji.append(cnvStr);
            } else if (nFlg == true) {
                // 末尾の"ン"は"n"に変換
                sbRomaji.append("n");
            }

        }

        return sbRomaji.toString();
    }

    /**
    *
    * ローマ字→全角カナ文字変換
    *
    * @param romaji 変換元文字列
    * @return 変換後文字列
    * @throws Exception
    *
    */
    public static String convertRomajiToZenkana(String romaji) throws Exception {

        int i = 0;
        int now = 0;
        int max = romaji.length();
        int addCount = 0;
        Boolean tuFlg = false;
        Boolean nFlg = false;
        String targetStr1;
        String targetStr2;
        String cnvStr = null;
        StringBuilder sbKana = new StringBuilder();

        // 母音
        String regex1 = "[aiueo]";
        Pattern p1 = Pattern.compile(regex1);

        // 破裂音子音
        String regex2 = "[bmp]";
        Pattern p2 = Pattern.compile(regex2);

        // 全角カナ→ローマ字文字変換
        while (now < max) {
            cnvStr = null;
            tuFlg = false;
            nFlg = false;
            addCount = 1;

            // 先頭が子音の重複か判定
            if (max - now >= 2) {
                targetStr1 = romaji.substring(now, now + 1);
                targetStr2 = romaji.substring(now + 1, now + 2);
                // "m"+破裂音"b""m""p"の場合は"ン"に変換する
                if (targetStr1.equals("m")) {
                    Matcher m2 = p2.matcher(targetStr2);
                    if (m2.find()) {
                        // 破裂音の場合は"ン"に変換する
                        now += 1;
                        nFlg = true;
                    }
                }
                // 次の文字が重複しているか判定
                else if (targetStr1.equals(targetStr2)) {
                    Matcher m1 = p1.matcher(targetStr1);
                    // 子音且つ"n"でない場合は"ッ"フラグON
                    if (!m1.find() && !targetStr1.equals("n")) {
                        now += 1;
                        tuFlg = true;
                    }
                }
            }

            // ローマ字カナ文字変換判定
            for (i = 4; i > 0; i--) {
                if (max - now >= i && cnvStr == null) {
                    cnvStr = convertByArray(romaji.substring(now, now + i), RARRAY);

                    if (cnvStr != null) {
                        addCount = i;
                        break;
                    }
                }
            }
            now += addCount;

            // 変換文字の結合
            if (cnvStr != null && cnvStr.length() > 0) {
                // "m"+破裂音の場合は"ン"を追加する
                if (nFlg == true) {
                    sbKana.append("ン");
                }
                // 子音の重複の場合は"ッ"を追加する
                if (tuFlg == true) {
                    sbKana.append("ッ");
                }
                sbKana.append(cnvStr);
            }

        }

        return sbKana.toString();

    }

    /**
     *
     * 変換先により変換元文字列を編集
     *
     * @param henkanMoto 変換元文字列
     * @param queryList 変換元リスト
     * @param rsList 変換先リスト
     * @return 変換後文字列
     *
     */
    private static String getResultString(String henkanMoto, List<String> queryList, List<MMojihenkanmst> rsList) {
        // 結果マップ
        Map<String, String> resultMap = new HashMap<String, String>();
        for (MMojihenkanmst resultBean : rsList) {
            resultMap.put(resultBean.getHenkanMoto(), resultBean.getHenkanSaki());
        }

        // 変換先
        String henkanSaki = henkanMoto;
        // 変換必要リストをループして変換処理を行う
        for (String query : queryList) {
            // 変換先ある場合、変換
            if (resultMap.containsKey(query)) {
                henkanSaki = henkanSaki.replaceAll(query, resultMap.get(query));
            }
            // 変換先なし場合全角の「?」へ変換
            else {
                henkanSaki = henkanSaki.replaceAll(query, StringConst.QUESTION_ZENKAKU);
            }
        }
        return henkanSaki;
    }

    /**
     * 変換元により変換先を転換する
     *
     * @param queryList 変換元リスト
     * @param queryMap 検索条件
     * @return 変換先リスト
     * @throws Exception
     */
    private static List<MMojihenkanmst> getHenkanAfterList(List<String> queryList, Map<String, Object> queryMap)
            throws Exception {
        if (MapUtil.isEmptyMap(queryMap)) {
            queryMap = new HashMap<String, Object>();
        }
        // 変換結果リスト
        List<MMojihenkanmst> rsList = new ArrayList<MMojihenkanmst>();
        // 2000件ごとに検索する
        for (int i = 0; i < queryList.size(); i += 2000) {
            List<String> paramList = new ArrayList<String>();
            if ((i + 2000) >= queryList.size()) {
                paramList.addAll(queryList.subList(i, queryList.size()));
            } else {
                paramList.addAll(queryList.subList(i, i + 2000));
            }

            queryMap.put(MapKeyConst.LIST, paramList);
            List<Map<String, String>> ret = DAOFactory.getDAO(DAOFactory.FUSSS).selectList(
                    MAPPERPATH, queryMap);

            List<MMojihenkanmst> retList = ConvertUtil.convert(ret, new TypeReference<List<MMojihenkanmst>>() {
            });
            rsList.addAll(retList);
        }
        return rsList;
    }

    /**
     *
     * 変換する必要リスト取得
     *
     * @param henkanMoto 変換元文字列
     * @param charset 変換文字コード
     * @return 変換する必要リスト
     * @throws Exception
     *
     */
    private static List<String> getHenkanMotoList(String henkanMoto, String charset) throws Exception {
        // 変換必要リスト
        List<String> queryList = new ArrayList<String>();

        // 変換元文字列をcodepointへ変換
        IntStream in = henkanMoto.codePoints();
        Iterator<Integer> it = in.iterator();
        // ループ、変換必要リストを取得
        while (it.hasNext()) {
            // 変換文字のcodepoint
            int henkanInt = it.next();
            // 変換文字
            String henkanStr = codepointToString(henkanInt);
            // 半角疑問符の場合直接追加
            if (StringConst.QUESTION_HANKAKU.equals(henkanStr)) {
                continue;
            }
            // 変換文字を設定エンコードへ変換
            String sjisStr = strToEncodeStr(henkanStr, charset);
            // 文字変換マスタに連携する必要がない場合
            if (StringConst.QUESTION_HANKAKU.equals(sjisStr)) {
                // 文字変換マスタに連携する必要がある場合
                // 重複の場合、除外
                if (!queryList.contains(henkanStr)) {
                    queryList.add(henkanStr);
                }
            }
        }
        return queryList;
    }

    /**
     * コードポイントを文字列へ変換
     *
     * @param cp コードポイント
     * @return 変換後文字列
     *
     */
    private static String codepointToString(int cp) {
        StringBuilder sb = new StringBuilder();
        sb.appendCodePoint(cp);
        return sb.toString();
    }

    /**
     * 文字列を指定されたエンコードへ変換
     *
     * @param henkanmoto 変換元文字列
     * @param encode 変換先エンコード
     * @return 変換後文字列
     * @throws UnsupportedEncodingException
     *
     */
    private static String strToEncodeStr(String henkanmoto, String encode) throws UnsupportedEncodingException {
        return new String(henkanmoto.getBytes(encode), encode);
    }

    /**
     * 変換定義配列により文字を変換する
     *
     * @param henkanmoto 変換元文字列
     * @param array 変換定義配列
     * @return 変換後文字列
     *
     */
    private static String convertByArray(String henkanmoto, String array[][]) {
        String ret = null;
        for (int i = 0; i < array.length; i++) {
            if (henkanmoto.equals(array[0])) {
                ret = array[1];
            }
        }
        return ret;
    }
}



◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆

    /**
    * メッセージ取得
    *
    * @param msgId
    *            メッセージID
    * @param argv
    *            可変項目の配列
    * @return メッセージ
    * @throws Exception
    */
    public static String getMsg(final String msgId, final String... argv) throws Exception {

        // TODO suda キャッシュするか毎回とるかは要検討

        // メッセージマスタ取得
        List<Map<String, Object>> messageMstList = null;
        ILogic messageLogic = LogicMap.getLogic(LogicUtil.getLogicKeyByClass(UDCM00440B01Logic.class));
        // ロジック実行
        String paramKey = messageLogic.getLogicParamKey();
        messageLogic.execute(new HashMap<String, Object>() {
            {
                put(paramKey, new HashMap<String, Object>() {
                    {
                        put(MapKeyConst.MSGID, msgId);
                    }
                });
            }
        });
        messageMstList = StringUtil.convert(messageLogic.getResult().getOutputMap().get(messageLogic.getLogicResultKey()),
                new TypeReference<List<Map<String, Object>>>() {
                });
        if (ListUtil.isEmpty(messageMstList)) {
            throw new LogicBusinessException("メッセージを取得できませんでした:msgID=" + msgId);
        }
        Optional<Map<String, Object>> foundMst = messageMstList.stream()
                .filter(x -> x.get(MapKeyConst.MSGID).equals(msgId))
                .findFirst(); // 最初の要素または空
        String message = (foundMst.get().get(MapKeyConst.MSG)).toString();

        // TODO 2020/04/07 maehara テスト用にメッセージIDを追加。単体テスト完了後に削除
        StringBuilder messageB = new StringBuilder("ID:" + msgId + "[" + message);
        messageB.append("]");
        message = messageB.toString(); // 仮メッセージ「ID:{メッセージID}[message]」

        // MessageFormatがObject配列しか許容していないため変換
        Object[] objArray = Arrays.asList(argv).toArray(new Object[argv.length]);

        return MessageFormat.format(message, objArray);
    }

    /**
    * メッセージ取得
    *
    * @param msgId メッセージID
    * @return メッセージ
    * @throws Exception
    */
    public static String getMsg(final String msgId) throws Exception {
        return getMsg(msgId, NO_PADDINGMESSAGE);
    }

    /**
    * メッセージ取得
    *
    * @param msgId メッセージID
    * @param argv 可変項目の配列
    * @return MMsgmst
    * @throws Exception
    */
    public static Map<String, String> getInfoMsg(final String msgId, final String... argv) throws Exception {
        String msg = getMsg(msgId, argv);

        MMsgmst msgmst = new MMsgmst();
        msgmst.setMsgID(msgId);
        msgmst.setMsg(msg);

        return ConvertUtil.convertToMap(msgmst);
    }

    /**
    * インフォメッセージ取得
    *
    * @param msgId メッセージID
    * @return メッセージMAP
    * @throws Exception
    */
    public static Map<String, String> getInfoMsg(final String msgId) throws Exception {
        return getInfoMsg(msgId, NO_PADDINGMESSAGE);
    }

    /**
     * メッセージ取得
     *
     * @param msgId
     *            メッセージID
     * @param argv
     *            可変項目の配列
     * @return メッセージID付メッセージ
     * @throws Exception
     */
    public static String getLogMsg(final String msgId, final String... argv)
            throws Exception {
        return msgId + ":" + getMsg(msgId, argv);
    }



日本 Japan
 ·日本留学生活 求个大阪合租
·日本留学生活 自家房招租求
·日本留学生活 东京地区出9成新lv钱包
·日本育儿教育 孩子从国内过来如何学习日语
·日本育儿教育 明年四月横滨招月嫂
·日本育儿教育 请问咋让娃突破识字关?感谢分享中文共读和学习经验的妈妈
 ·中文新闻 东区明星迈克尔·格列柯,53 岁,将在第一次出生两年后第二次
·中文新闻 《爱情岛》明星卡米拉·瑟洛和杰米·朱维特在透露即将迎来第三

日语考试

旅行管理

华人网出套资格考试用书,课本4本,习题6本,CD课时9张,16小时左右。7千出。位置东京,上板桥车站附近,东武东上线上,池袋,山手线上交易。微信qzq20198 评论 1111111 ...

日语考试

募集一起备考FP考试

华人网情况介绍‘ 本人打算明年1月先考3级 之后考2级想找小伙伴一起学习。 我滴情况是,社会人30代前半,人品端正热爱学习和户外运动 想持续保持学习和进步。 坐标最好是东京靠埼玉, ...

日语考试

行政书士资格考试

华人网今年十一月份打算考行政书士资格,有没有一起考试的小伙伴,可以加我微信,大家一起分享学习经验。同时更加欢迎考过的前辈给予指导!万分感谢! ...

日语考试

1v1辅导研究计划书(情报,通信专业)

华人网教育背景:985计算机+早大情报 辅导经历:曾在东京知名的理工孰任教,教授课程包括《高等数学》,《线性代数》,《形式语言》,《数理统计》,曾1v1辅导过多名学生的研究计划书。 ...

日语考试

找个小伙伴一起学习java

华人网准备明年入职,有资料可以共享给你,我是基本0开始的所以想互相监督,约定线上固定时间,守时素质高的,日语太差的别了,一起学习 评论 留下你的V我加你。举个例子,约定好每周 ...

日语考试

求书 ソーシャルワーク基盤と専門職

华人网求书 ソーシャルワーク基盤と専門職 评论 这本书应该是日本学校的教材,而且好像是较新版本,LZ是不是觉得这里比去书店找能更快找到? 评论 学校要用的书想便宜点买个二手的 ...