/*
 * ***************************************************************
 * , Copyright. HSBC Holdings plc ccyy ALL RIGHTS RESERVED.
 *
 * This software is only to be used for the purpose for which it
 * has been provided. No part of it is to be reproduced,
 * disassembled, transmitted, stored in a retrieval system or
 * translated in any human or computer language in any way or
 * for any other purposes whatsoever without the prior written
 * consent of HSBC Holdings plc.
 * ***************************************************************
 */

package util;

import org.apache.commons.lang3.StringUtils;

import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * <p>  Function: DateUtil Class</p>
 */
public class DateUtil {

    /**
     * format year
     */
    public static final String DATE_FORMAT_YYYY = "yyyy";
    /**
     * format Year month
     */
    public static final String DATE_FORMAT_YYYYMM = "yyyyMM";
    /**
     * format Year-month
     */
    public static final String DATE_FORMAT_YYYY_MM = "yyyy-MM";
    /**
     * format Year(yy)MonthDay
     */
    public static final String DATE_FORMAT_YYMMDD = "yyMMdd";
    /**
     * format Year(yy)-Month-Day
     */
    public static final String DATE_FORMAT_YY_MM_DD = "yy-MM-dd";
    /**
     * format Year(yyyy)MonthDay
     */
    public static final String DATE_FORMAT_YYYYMMDD = "yyyyMMdd";
    /**
     * format Year(yyyy)-Month-Day
     */
    public static final String DATE_FORMAT_YYYY_MM_DD = "yyyy-MM-dd";
    /**
     * format Year(yyyy)MonthDay Hour:Minute
     */
    public static final String DATE_TIME_FORMAT_YYYYMMDD_HH_MI = "yyyyMMdd HH:mm";
    /**
     * format Year(yyyy)-Month-Day Hour:Minute
     */
    public static final String DATE_TIME_FORMAT_YYYY_MM_DD_HH_MI = "yyyy-MM-dd HH:mm";
    /**
     * format Year(yyyy)MonthDayHourMinuteSecond
     */
    public static final String DATE_TIME_FORMAT_YYYYMMDDHHMISS = "yyyyMMddHHmmss";
    /**
     * format Year(yyyy)-Month-Day Hour:Minute:Second
     */
    public static final String DATE_TIME_FORMAT_YYYY_MM_DD_HH_MI_SS = "yyyy-MM-dd HH:mm:ss";
    /**
     * format Year(yyyy)MonthDayHourMinuteSecondSSS
     */
    public static final String DATE_TIME_FORMAT_YYYYMMDDHHMISSSSS = "yyyy-MM-dd HH:mm:ss:SSS";
    /**
     * format HourMinute
     */
    public static final String DATE_FORMAT_HHMI = "HHmm";
    /**
     * GMT time format
     */
    public static final String DATE_TIME_FORMATE_DD_MM_YYYY_HH_MM_SS = "dd MM yyyy HH:mm:ss";

    /**
     * format Day-Month-Year(yy)
     */
    public static final String DATE_TIME_FORMATE_DD_MM_YYYY = "dd-MM-yyyy";

    /**
     * parseDateToStr
     *
     * @param date       date
     * @param dateFormat dateFormat
     * @return date String
     */
    public static String parseDateToStr(Date date, String dateFormat) {
        if (date == null) {
            return "";
        }
        DateFormat format = new SimpleDateFormat(dateFormat);
        return format.format(date);
    }

    /**
     * parseStrToDate
     *
     * @param date       String Date
     * @param dateFormat date Format
     * @return date
     */
    public static Date parseStrToDate(String date, String dateFormat) throws ParseException {
        if (StringUtils.isBlank(date)) {
            return null;
        }
        DateFormat format = new SimpleDateFormat(dateFormat);
        return format.parse(date);
    }

    /**
     * Date convert to XMLGregorianCalendar
     *
     * @param date date
     * @return XMLGregorianCalendar
     */
    public static XMLGregorianCalendar dateToXmlDate(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        DatatypeFactory dtf = null;
        try {
            dtf = DatatypeFactory.newInstance();
        } catch (DatatypeConfigurationException ignored) {
            System.out.println("ERROR:" + ignored);
        }
        XMLGregorianCalendar dateType = null;
        if (dtf != null) {
            dateType = dtf.newXMLGregorianCalendar();
            dateType.setYear(cal.get(Calendar.YEAR));
            dateType.setMonth(cal.get(Calendar.MONTH) + 1);
            dateType.setDay(cal.get(Calendar.DAY_OF_MONTH));
            dateType.setHour(cal.get(Calendar.HOUR_OF_DAY));
            dateType.setMinute(cal.get(Calendar.MINUTE));
            dateType.setSecond(cal.get(Calendar.SECOND));
        }

        return dateType;
    }

    /**
     * XMLGregorianCalendar convert to Date
     *
     * @param cal XMLGregorianCalendar
     * @return Date
     */
    public static Date xmlDate2Date(XMLGregorianCalendar cal) {
        return cal.toGregorianCalendar().getTime();
    }

    /**
     * Get GMT time
     *
     * @return GMT time string
     */
    public static String getGmtTimeString() {
        Calendar c = Calendar.getInstance();
        SimpleDateFormat df = new SimpleDateFormat(DATE_TIME_FORMATE_DD_MM_YYYY_HH_MM_SS);
        return df.format(c.getTime()) + " GMT";
    }
}
