DateTimeUtil


import com.google.common.collect.Lists;
import java.sql.Timestamp;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.Days;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.ISODateTimeFormat;
import org.springframework.util.Assert;

/**
 * @author
 */
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class DateTimeUtil {

    private static final String DATE_STRING_NOT_NULL = "The 'dateString' must not be null!";
    private static final String DATE_NOT_NULL = "The 'date' must not be null!";

    /**
     *       :yyyy-MM-dd
     */
    public static final String DEFAULT_DATE_PATTERN = "yyyy-MM-dd";
    
    /**
     *     :yyyy-MM-dd HH
     */
    public static final String YYYYMM_HH_DATE_PATTERN = "yyyy-MM-dd HH";
    
    /**
     *       :yyyyMM
     */
    public static final String YYYYMM_DATE_PATTERN = "yyyyMM";
    
    /**
     *       :yyyyMMdd
     */
    public static final String YYYYMMDD_DATE_PATTERN = "yyyyMMdd";

    public static final String YYYY_MM_DD = "yyyy/MM/dd";

    /**
     *       :yyyy-MM-dd HH:mm:ss
     */
    public static final String DEFAULT_DATETIME_PATTERN = "yyyy-MM-dd HH:mm:ss";

    /**
     *         
     */
    public static int currentYear() {
        return DateTime.now().getYear();
    }

    /**
     *         
     */
    public static Date currentDate() {
        return DateTime.now().toDate();
    }

    /**
     *         ,            。
     */
    public static String nowDate(String strFormat) {
        Assert.notNull(strFormat, DATE_STRING_NOT_NULL);
        return new DateTime().toString(strFormat, Locale.CHINESE);
    }

    /**
     *          
     */
    public static Timestamp currentTimestamp() {
        return new Timestamp(new DateTime().getMillis());
    }

    /**
     *          java.util.Date  
     *
     * @param pattern     
     */
    public static Date toDate(String dateString, String pattern) {
        Assert.notNull(dateString, DATE_STRING_NOT_NULL);
        Assert.notNull(pattern, "The 'pattern' must not be null!");
        return DateTime.parse(dateString, DateTimeFormat.forPattern(pattern)).toDate();
    }
    
    public static Date toDate(Date date, String pattern) {
        Assert.notNull(date, DATE_NOT_NULL);
        Assert.notNull(pattern, "The 'pattern' must not be null!");
        return DateTime.parse(toDateString(date, pattern), DateTimeFormat.forPattern(pattern)).toDate();
    }
    
    /**
     *          java.util.Date  
     *
     * @param dateString example:"20XX-05-03T15:11:45.7009265+08:00"
     */
    public static Date toISODate(String dateString) {
        Assert.notNull(dateString, DATE_STRING_NOT_NULL);
        return DateTime.parse(dateString, ISODateTimeFormat.dateTime()).toDate();
    }

    /**
     *          java.util.Date  ,        
     */
    public static Date toDate(String dateString) {
        Assert.notNull(dateString, DATE_STRING_NOT_NULL);
        return DateTime.parse(dateString).toDate();
    }

    /**
     *          java.util.Date  
     */
    public static Date toDateTime(String dateString) {
        Assert.notNull(dateString, DATE_STRING_NOT_NULL);
        return DateTime.parse(dateString, DateTimeFormat.forPattern(DEFAULT_DATETIME_PATTERN)).toDate();
    }

    /**
     *  java.util.Date        
     */
    public static String toDateString(Date date, String pattern) {
        Assert.notNull(date, DATE_NOT_NULL);
        Assert.notNull(pattern, "The 'pattern' must not be null!");
        return new DateTime(date).toString(pattern, Locale.CHINESE);
    }

    /**
     *  java.util.Date        ,        
     */
    public static String toDateString(Date date) {
        Assert.notNull(date, DATE_NOT_NULL);
        return new DateTime(date).toString(DEFAULT_DATE_PATTERN, Locale.CHINESE);
    }

    /**
     *  int 10          ,        
     */
    public static String toDateString(int time) {
        Assert.notNull(time, DATE_STRING_NOT_NULL);
        return new DateTime(new Date(time * 1000L)).toString(DEFAULT_DATETIME_PATTERN, Locale.CHINESE);
    }

    /**
     *  long 13          ,        
     */
    public static String toDateString(long time) {
        Assert.notNull(time, DATE_STRING_NOT_NULL);
        return new DateTime(new Date(time)).toString(DEFAULT_DATETIME_PATTERN, Locale.CHINESE);
    }

    /**
     *  java.util.Date          ,        
     */
    public static String toDateTimeString(Date date) {
        Assert.notNull(date, DATE_NOT_NULL);
        return new DateTime(date).toString(DEFAULT_DATETIME_PATTERN, Locale.CHINESE);
    }

    /**
     *     
     */
    public static Date diffDate(Date date, Integer days) {
        Assert.notNull(date, DATE_NOT_NULL);
        Assert.notNull(days, "The 'days' must not be null!");
        return new DateTime(date).minusDays(days).toDate();

    }

    /**
     *     
     *
     * @param date   
     * @return     
     */
    public static long getMillis(Date date) {
        Assert.notNull(date, DATE_NOT_NULL);
        return new DateTime(date).getMillis();
    }

    /**
     *     
     *
     * @param date   
     * @param days   
     * @return         
     */
    public static Date addDate(Date date, Integer days) {
        Assert.notNull(date, DATE_NOT_NULL);
        Assert.notNull(days, "The 'days' must not be null!");
        return new DateTime(date).plusDays(days).toDate();
    }

    /**
     *       
     */
    public static Date addYear(Date date, Integer years) {
        Assert.notNull(date, DATE_NOT_NULL);
        Assert.notNull(years, DATE_STRING_NOT_NULL);
        return new DateTime(date).plusYears(years).toDate();
    }

    /**
     *       
     */
    public static Date addMonth(Date date, Integer months) {
        Assert.notNull(date, DATE_NOT_NULL);
        Assert.notNull(months, DATE_STRING_NOT_NULL);
        return new DateTime(date).plusMonths(months).toDate();
    }

    /**
     *       
     */
    public static Date addHours(Date date, Integer hours) {
        Assert.notNull(date, DATE_NOT_NULL);
        Assert.notNull(hours, "The 'hours' must not be null!");
        return new DateTime(date).plusHours(hours).toDate();
    }

    /**
     *       
     */
    public static Date addMinutes(Date date, Integer minutes) {
        Assert.notNull(date, DATE_NOT_NULL);
        Assert.notNull(minutes, "The 'minutes' must not be null!");
        return new DateTime(date).plusMinutes(minutes).toDate();
    }

    /**
     *      
     */
    public static Date addSeconds(Date date, Integer seconds) {
        Assert.notNull(date, DATE_NOT_NULL);
        Assert.notNull(seconds, "The 'seconds' must not be null!");
        return new DateTime(date).plusSeconds(seconds).toDate();
    }

    /**
     *            
     *
     * @param quarters   
     * @return        
     */
    public static String getMonth(String quarters) {
        Assert.notNull(quarters, "The 'quarters' must not be null!");
        String month;
        int m = Integer.parseInt(quarters);
        m = m * 3 - 2;
        if (m > 0 && m < 10) {
            month = "0" + String.valueOf(m);
        } else {
            month = String.valueOf(m);
        }
        return month;
    }

    /**
     *            
     *
     * @param month   
     * @return        
     */
    public static String getQuarters(String month) {
        Assert.notNull(month, "The 'month' must not be null!");
        String quarters = null;
        int m = Integer.parseInt(month);
        if (m == 1 || m == 2 || m == 3) {
            quarters = "1";
        }
        if (m == 4 || m == 5 || m == 6) {
            quarters = "2";
        }
        if (m == 7 || m == 8 || m == 9) {
            quarters = "3";
        }
        if (m == 10 || m == 11 || m == 12) {
            quarters = "4";
        }
        return quarters;
    }

    /**
     *             ,           
     */
    public static String getFirstDateOfWeek(String datestr) {
        Assert.notNull(datestr, DATE_STRING_NOT_NULL);
        DateTime dt = DateTime.parse(datestr);
        return dt.plusDays(-(dt.getDayOfWeek()) + 1).toString(DEFAULT_DATE_PATTERN);
    }

    /**
     *             
     */
    public static int getWeekOfYear(String datestr) {
        Assert.notNull(datestr, DATE_STRING_NOT_NULL);
        return DateTime.parse(datestr).weekOfWeekyear().get();
    }

    /**
     *        yyyy-MM-dd HH:mm:ss     
     */
    public static String getWeekday(String datestr) {
        Assert.notNull(datestr, DATE_STRING_NOT_NULL);
        try {
            switch (DateTime.parse(datestr).dayOfWeek().get()) {
                case 1:
                    return "   ";
                case 2:
                    return "   ";
                case 3:
                    return "   ";
                case 4:
                    return "   ";
                case 5:
                    return "   ";
                case 6:
                    return "   ";
                default:
                    return "   ";
            }
        } catch (Exception ex) {
            throw new SysException(ex);
        }

    }

    public static Date getDate(Object object) {
        Assert.notNull(object, "The 'object' must not be null!");
        if (object instanceof String) {
            return DateTime.parse((String) object).toDate();
        } else if (object instanceof Date || object instanceof Timestamp) {
            return (Date) object;
        } else if (object instanceof Long) {
            return new DateTime((Long) object).toDate();
        } else {
            throw new SysException("this object can't to date!");
        }
    }

    public static Date fromTimeticks(Long ticks) {
        Assert.notNull(ticks, "The 'ticks' must not be null!");
        return new DateTime(ticks).toDate();
    }

    public static Long toTimeticks(Date time) {
        return time.getTime();
    }

    /**
     *   UTC   (10 )
     */
    public static int getUTCOfSeconds() {
        return (int) (new DateTime(DateTimeZone.UTC).toDate().getTime() / 1000);
    }

    /**
     *   Date  UTC   (10 )
     */
    public static int getUTCOfSeconds(Date date) {
        return (int) (date.getTime() / 1000);
    }

    /**
     *   UTC      (10 )
     */
    public static int getUTCMinDayOfSeconds(Date date) {
        Assert.notNull(date, DATE_NOT_NULL);
        return (int) (new DateTime(date, DateTimeZone.UTC).millisOfDay().withMinimumValue().toDate().getTime() / 1000);
    }

    /**
     *   UTC 24     (10 )
     */
    public static int getUTCMaxDayOfSeconds() {
        return (int) (DateTime.now(DateTimeZone.UTC).millisOfDay().withMaximumValue().toDate().getTime() / 1000);
    }

    /**
     *   UTC 24     (10 )
     */
    public static int getUTCMaxDayOfSeconds(Date date) {
        Assert.notNull(date, DATE_NOT_NULL);
        return (int) (new DateTime(date, DateTimeZone.UTC).millisOfDay().withMaximumValue().toDate().getTime() / 1000);
    }

    /**
     *   UTC   (      )
     */
    public static long getUTCOfMillis() {
        return DateTime.now(DateTimeZone.UTC).toDate().getTime();
    }

    /**
     *              seconds:
     */
    public static int getUTCMinMonthOfSeconds() {
        return getUTCMinDayOfSeconds(DateTime.now().dayOfMonth().withMinimumValue().toDate());
    }

    /**
     *           24    seconds:
     */
    public static int getUTCMaxMonthOfSeconds() {
        return getUTCMaxDayOfSeconds(DateTime.now().dayOfMonth().withMaximumValue().toDate());
    }

    /**
     *        7    0    seconds:
     */
    public static int getUTCBefore7DayOfSeconds() {
        return getUTCMinDayOfSeconds(DateTime.now().minusDays(7).toDate());
    }

    /**
     *        X    0    seconds:
     */
    public static int getUTCBeforeDayOfSeconds(int beforeDay) {
        return getUTCMinDayOfSeconds(DateTime.now().minusDays(beforeDay).toDate());
    }

    /**
     *  UTC        java.util.Date(yyyy-MM-dd)  
     */
    public static String toUTCShortStringTime(int time) {
        Assert.notNull(time, DATE_STRING_NOT_NULL);
        return new DateTime(new Date(time * 1000L), DateTimeZone.UTC).toString(DEFAULT_DATE_PATTERN);
    }

    /**
     *      X 
     */
    public static int betweenDays(Date startTime, Date endTime) {
        DateTime _startTime = new DateTime(startTime);
        DateTime _endTime = new DateTime(endTime);
        return Days.daysBetween(_startTime, _endTime).getDays();
    }

    /**
     *          
     */
    public static List days(Date startTime, int days) {
        List _days = Lists.newArrayList();
        Date time = startTime;
        for (int i = 0; i < days; i++) {
            _days.add(toDateString(time, DEFAULT_DATE_PATTERN));
            time = DateTimeUtil.addDate(time, 1);
        }
        return _days;
    }

    public static Long getSecondDay(Long day) {
        return 24 * 60 * 60 * day;
    }

    public static boolean isToday(Date time) {
        if (EmptyUtils.isEmpty(time)) {
            return false;
        }
        DateTime.Property property = DateTime.now().millisOfDay();
        return time.getTime() >= property.withMinimumValue().getMillis() && time.getTime() <= property
            .withMaximumValue().getMillis();
    }

}