日本华人论坛 程序编写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
 ·日本中文新闻 日本26年新成人预估仅109万 与去年并列历史第二低
·日本中文新闻 日本皇居新年参贺突发裸奔事件 男子涉公然猥亵被捕
·日本中文新闻 印度宣布超越日本成为全球第四大经济体
·日本留学生活 在熟悉的城市,遇見不一樣的感受
·日本留学生活 求购一些水电燃气话费等公共料金请求书
·日本华人网络交流 制造信息垃圾的产业,这种现象在日本尤其普遍。
·日本华人网络交流 美军入侵 委内瑞拉领空 并非零伤亡
·日本华人网络交流 年末采购食品,恰时间就能全半价。
 ·中文新闻 马丁·克鲁内斯 (Martin Clunes) 在新剧中变身休·爱德华兹 (Huw Edw
·中文新闻 当朋友们讲述他们对他们的阴谋感到震惊以及他们如何向他们隐

日语考试

旅行管理

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

日语考试

募集一起备考FP考试

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

日语考试

行政书士资格考试

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

日语考试

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

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

日语考试

找个小伙伴一起学习java

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

日语考试

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

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