前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java工具集-日期(DateUtils)

Java工具集-日期(DateUtils)

作者头像
cwl_java
发布2019-10-28 11:29:50
3.2K0
发布2019-10-28 11:29:50
举报
文章被收录于专栏:cwl_Javacwl_Java

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://blog.csdn.net/weixin_42528266/article/details/102622081

简单工具类

写作初衷:由于日常开发经常需要用到很多工具类,经常根据需求自己写也比较麻烦 网上好了一些工具类例如commom.lang3或者hutool或者Jodd这样的开源工具,但是 发现他们之中虽然设计不错,但是如果我想要使用,就必须要引入依赖并且去维护依赖,有些 甚至会有存在版本编译不通过问题,故此想要写作一个每个类都可以作为独立工具类使用 每个使用者只需要复制该类,到任何项目当中都可以使用,所以需要尊从以下两个原则才能 做到.在此诚邀各位大佬参与.可以把各自用过的工具,整合成只依赖JDK,每个类都能够单独 使用的工具.每个人当遇到业务需求需要使用的时候,只需要到这里单独拷贝一个即可使用. 抛弃传统的需要引入依赖的烦恼.让大家一起来解决你所面临的业务问题吧!

介绍

遵从两大原则

  • 1.绝不依赖JDK以外的源码
  • 2.牺牲代码复用性,每个类都必须是单独的组件,绝不互相引用,做到完全解耦
代码语言:javascript
复制
package *;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.text.DateFormat;
import java.text.DateFormatSymbols;
import java.text.FieldPosition;
import java.text.Format;
import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.TimeZone;

/**
 * @program: simple_tools
 * @description:
 * @author: ChenWenLong
 * @create: 2019-06-04 16:19
 **/
public class DateUtils {

    //无时区的格式化
    public static final FastDateFormat ISO_DATETIME_FORMAT
            = FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ss");
    //带时区的格式化
    public static final FastDateFormat ISO_DATETIME_TIME_ZONE_FORMAT
            = FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ssZZ");
    //纯日期格式化
    public static final FastDateFormat ISO_DATE_FORMAT
            = FastDateFormat.getInstance("yyyy-MM-dd");
    //带时区的日期格式化
    public static final FastDateFormat ISO_DATE_TIME_ZONE_FORMAT
            = FastDateFormat.getInstance("yyyy-MM-ddZZ");
    //不带时区的时间格式化
    public static final FastDateFormat ISO_TIME_FORMAT
            = FastDateFormat.getInstance("'T'HH:mm:ss");
    //带时区的时间格式化
    public static final FastDateFormat ISO_TIME_TIME_ZONE_FORMAT
            = FastDateFormat.getInstance("'T'HH:mm:ssZZ");
    //没有T前缀的,非ISO8601规范的时间格式化
    public static final FastDateFormat ISO_TIME_NO_T_FORMAT
            = FastDateFormat.getInstance("HH:mm:ss");
    //带时区的,非ISO8601规范的时间格式化
    public static final FastDateFormat ISO_TIME_NO_T_TIME_ZONE_FORMAT
            = FastDateFormat.getInstance("HH:mm:ssZZ");
    public static final FastDateFormat SMTP_DATETIME_FORMAT
            = FastDateFormat.getInstance("EEE, dd MMM yyyy HH:mm:ss Z", Locale.US);
    private static String[] parsePatterns = {
            "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM",
            "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
            "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};
    //世界时间格式
    public static final TimeZone UTC_TIME_ZONE = TimeZone.getTimeZone("GMT");
    //每秒=1000毫秒
    public static final long MILLIS_PER_SECOND = 1000;
    //每分钟=60秒
    public static final long MILLIS_PER_MINUTE = 60 * MILLIS_PER_SECOND;
    //每小时=60分钟
    public static final long MILLIS_PER_HOUR = 60 * MILLIS_PER_MINUTE;
    //每天=24小时
    public static final long MILLIS_PER_DAY = 24 * MILLIS_PER_HOUR;
    //表示半个月,这个表示是上半旬还是下半旬
    public final static int SEMI_MONTH = 1001;

    public final static int RANGE_WEEK_SUNDAY = 1;
    public final static int RANGE_WEEK_MONDAY = 2;
    public final static int RANGE_WEEK_RELATIVE = 3;
    public final static int RANGE_WEEK_CENTER = 4;
    public final static int RANGE_MONTH_SUNDAY = 5;
    public final static int RANGE_MONTH_MONDAY = 6;

    private static final int[][] fields = {
            {Calendar.MILLISECOND},
            {Calendar.SECOND},
            {Calendar.MINUTE},
            {Calendar.HOUR_OF_DAY, Calendar.HOUR},
            {Calendar.DATE, Calendar.DAY_OF_MONTH, Calendar.AM_PM},
            {Calendar.MONTH, SEMI_MONTH},
            {Calendar.YEAR},
            {Calendar.ERA}};

    /**
     * 功能描述:
     * 〈判断是否是同一天,接受Date类型〉
     *
     * @params : [date1, date2]
     * @return : boolean
     * @author : cwl
     * @date : 2019/6/6 11:00
     */
    public static boolean isSameDay(Date date1, Date date2) {
        if (date1 == null || date2 == null) {
            throw new IllegalArgumentException("The date must not be null");
        }
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(date1);
        Calendar cal2 = Calendar.getInstance();
        cal2.setTime(date2);
        return isSameDay(cal1, cal2);
    }

    /**
     * 功能描述:
     * 〈判断是否是同一天,接受Calendar〉
     *
     * @params : [cal1, cal2]
     * @return : boolean
     * @author : cwl
     * @date : 2019/6/6 11:01
     */
    public static boolean isSameDay(Calendar cal1, Calendar cal2) {
        if (cal1 == null || cal2 == null) {
            throw new IllegalArgumentException("The date must not be null");
        }
        return (cal1.get(Calendar.ERA) == cal2.get(Calendar.ERA) &&
                cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) &&
                cal1.get(Calendar.DAY_OF_YEAR) == cal2.get(Calendar.DAY_OF_YEAR));
    }

    /**
     * 功能描述:
     * 〈判断是否是同一时间,接受Date类型〉
     *
     * @params : [date1, date2]
     * @return : boolean
     * @author : cwl
     * @date : 2019/6/6 11:02
     */
    public static boolean isSameTime(Date date1, Date date2) {
        if (date1 == null || date2 == null) {
            throw new IllegalArgumentException("The date must not be null");
        }
        return date1.getTime() == date2.getTime();
    }

    /**
     * 功能描述:
     * 〈判断是否是同一时间,接受Calendar〉
     *
     * @params : [cal1, cal2]
     * @return : boolean
     * @author : cwl
     * @date : 2019/6/6 11:03
     */
    public static boolean isSameTime(Calendar cal1, Calendar cal2) {
        if (cal1 == null || cal2 == null) {
            throw new IllegalArgumentException("The date must not be null");
        }
        return cal1.getTime().getTime() == cal2.getTime().getTime();
    }

    /**
     * 功能描述:
     * 〈是否是同一地区是时间,即将二手Calendar类型.Date类型并没有地区这种说法〉
     *
     * @params : [cal1, cal2]
     * @return : boolean
     * @author : cwl
     * @date : 2019/6/6 11:07
     */
    public static boolean isSameLocalTime(Calendar cal1, Calendar cal2) {
        if (cal1 == null || cal2 == null) {
            throw new IllegalArgumentException("The date must not be null");
        }
        return (cal1.get(Calendar.MILLISECOND) == cal2.get(Calendar.MILLISECOND) &&
                cal1.get(Calendar.SECOND) == cal2.get(Calendar.SECOND) &&
                cal1.get(Calendar.MINUTE) == cal2.get(Calendar.MINUTE) &&
                cal1.get(Calendar.HOUR) == cal2.get(Calendar.HOUR) &&
                cal1.get(Calendar.DAY_OF_YEAR) == cal2.get(Calendar.DAY_OF_YEAR) &&
                cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) &&
                cal1.get(Calendar.ERA) == cal2.get(Calendar.ERA) &&
                cal1.getClass() == cal2.getClass());
    }

    /**
     * 功能描述:
     * 〈尝试用不同的格式去格式化字符串日期〉
     *
     * @params : [str, parsePatterns]
     * @return : java.util.Date
     * @author : cwl
     * @date : 2019/6/6 11:19
     */
    public static Date parseDate(String str, String[] parsePatterns) throws ParseException {
        if (str == null || parsePatterns == null) {
            throw new IllegalArgumentException("Date and Patterns must not be null");
        }

        SimpleDateFormat parser = null;
        ParsePosition pos = new ParsePosition(0);
        for (int i = 0; i < parsePatterns.length; i++) {
            if (i == 0) {
                parser = new SimpleDateFormat(parsePatterns[0]);
            } else {
                parser.applyPattern(parsePatterns[i]);
            }
            pos.setIndex(0);
            Date date = parser.parse(str, pos);
            if (date != null && pos.getIndex() == str.length()) {
                return date;
            }
        }
        throw new ParseException("Unable to parse the date: " + str, -1);
    }

    /**
     * 功能描述:
     * 〈解析时间格式〉
     *
     * @params : [str]
     * @return : java.util.Date
     * @author : cwl
     * @date : 2019/10/17 16:47
     */
    public static Date parseDate(Object str) {
        if (str == null) {
            return null;
        }
        try {
            return parseDate(str.toString(), parsePatterns);
        } catch (ParseException e) {
            return null;
        }
    }

    /**
     * 功能描述:
     * 〈加amount年〉
     *
     * @params : [date, amount]
     * @return : java.util.Date
     * @author : cwl
     * @date : 2019/6/6 11:22
     */
    public static Date addYears(Date date, int amount) {
        return add(date, Calendar.YEAR, amount);
    }

    /**
     * 功能描述:
     * 〈加amount月〉
     *
     * @params : [date, amount]
     * @return : java.util.Date
     * @author : cwl
     * @date : 2019/6/6 11:22
     */
    public static Date addMonths(Date date, int amount) {
        return add(date, Calendar.MONTH, amount);
    }

    /**
     * 功能描述:
     * 〈加amount月〉
     *
     * @params : [date, amount]
     * @return : java.util.Date
     * @author : cwl
     * @date : 2019/6/6 11:23
     */
    public static Date addWeeks(Date date, int amount) {
        return add(date, Calendar.WEEK_OF_YEAR, amount);
    }

    /**
     * 功能描述:
     * 〈加amount天〉
     *
     * @params : [date, amount]
     * @return : java.util.Date
     * @author : cwl
     * @date : 2019/6/6 11:23
     */
    public static Date addDays(Date date, int amount) {
        return add(date, Calendar.DAY_OF_MONTH, amount);
    }

    /**
     * 功能描述:
     * 〈标准格式化时间.传入毫秒数mills和pattern格式〉
     *
     * @params : [millis, pattern]
     * @return : java.lang.String
     * @author : cwl
     * @date : 2019/6/5 17:29
     */
    public static String formatUTC(long millis, String pattern) {
        return format(new Date(millis), pattern, UTC_TIME_ZONE, null);
    }

    /**
     * 功能描述:
     * 〈加amount小时〉
     *
     * @params : [date, amount]
     * @return : java.util.Date
     * @author : cwl
     * @date : 2019/6/6 11:24
     */
    public static Date addHours(Date date, int amount) {
        return add(date, Calendar.HOUR_OF_DAY, amount);
    }


    /**
     * 功能描述:
     * 〈标准格式化时间,传入date时间格式,pattern格式〉
     *
     * @params : [date, pattern]
     * @return : java.lang.String
     * @author : cwl
     * @date : 2019/6/5 17:30
     */
    public static String formatUTC(Date date, String pattern) {
        return format(date, pattern, UTC_TIME_ZONE, null);
    }

    /**
     * 功能描述:
     * 〈加amount分钟〉
     *
     * @params : [date, amount]
     * @return : java.util.Date
     * @author : cwl
     * @date : 2019/6/6 11:24
     */
    public static Date addMinutes(Date date, int amount) {
        return add(date, Calendar.MINUTE, amount);
    }

    /**
     * 功能描述:
     * 〈加amount秒〉
     *
     * @params : [date, amount]
     * @return : java.util.Date
     * @author : cwl
     * @date : 2019/6/6 11:24
     */
    public static Date addSeconds(Date date, int amount) {
        return add(date, Calendar.SECOND, amount);
    }

    /**
     * 功能描述:
     * 〈加amount毫秒〉
     *
     * @params : [date, amount]
     * @return : java.util.Date
     * @author : cwl
     * @date : 2019/6/6 11:33
     */
    public static Date addMilliseconds(Date date, int amount) {
        return add(date, Calendar.MILLISECOND, amount);
    }

    /**
     * 功能描述:
     * 〈添加年/月/日/时/分/秒/毫秒 amount为添加量〉
     *
     * @params : [date, calendarField, amount]
     * @return : java.util.Date
     * @author : cwl
     * @date : 2019/6/6 11:34
     */
    public static Date add(Date date, int calendarField, int amount) {
        if (date == null) {
            throw new IllegalArgumentException("The date must not be null");
        }
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(calendarField, amount);
        return c.getTime();
    }

    /**
     * 功能描述:
     * 〈设置date年份,并返回一个新的日期〉
     *
     * @params : [date, amount]
     * @return : java.util.Date
     * @author : cwl
     * @date : 2019/6/6 11:35
     */
    public static Date setYears(Date date, int amount) {
        return set(date, Calendar.YEAR, amount);
    }

    /**
     * 功能描述:
     * 〈设置date月份,返回一个新的日期〉
     *
     * @params : [date, amount]
     * @return : java.util.Date
     * @author : cwl
     * @date : 2019/6/6 11:36
     */
    public static Date setMonths(Date date, int amount) {
        return set(date, Calendar.MONTH, amount);
    }

    /**
     * 功能描述:
     * 〈设置date日期,返回一个新的日期〉
     *
     * @params : [date, amount]
     * @return : java.util.Date
     * @author : cwl
     * @date : 2019/6/6 11:37
     */
    public static Date setDays(Date date, int amount) {
        return set(date, Calendar.DAY_OF_MONTH, amount);
    }

    /**
     * 功能描述:
     * 〈设置时间,返回一个新的时间〉
     *
     * @params : [date, amount]
     * @return : java.util.Date
     * @author : cwl
     * @date : 2019/6/6 11:38
     */
    public static Date setHours(Date date, int amount) {
        return set(date, Calendar.HOUR_OF_DAY, amount);
    }

    /**
     * 功能描述:
     * 〈设置时间,返回一个新的时间〉
     *
     * @params : [date, amount]
     * @return : java.util.Date
     * @author : cwl
     * @date : 2019/6/6 11:38
     */
    public static Date setMinutes(Date date, int amount) {
        return set(date, Calendar.MINUTE, amount);
    }

    /**
     * 功能描述:
     * 〈设置时间,返回一个新的时间〉
     *
     * @params : [date, amount]
     * @return : java.util.Date
     * @author : cwl
     * @date : 2019/6/6 11:39
     */
    public static Date setSeconds(Date date, int amount) {
        return set(date, Calendar.SECOND, amount);
    }

    /**
     * 功能描述:
     * 〈设置时间,返回一个新的时间〉
     *
     * @params : [date, amount]
     * @return : java.util.Date
     * @author : cwl
     * @date : 2019/6/6 11:39
     */
    public static Date setMilliseconds(Date date, int amount) {
        return set(date, Calendar.MILLISECOND, amount);
    }

    /**
     * 功能描述:
     * 〈设置时间〉
     *
     * @params : [date, calendarField, amount]
     * @return : java.util.Date
     * @author : cwl
     * @date : 2019/6/6 11:40
     */
    private static Date set(Date date, int calendarField, int amount) {
        if (date == null) {
            throw new IllegalArgumentException("The date must not be null");
        }
        // getInstance() returns a new object, so this method is thread safe.
        Calendar c = Calendar.getInstance();
        c.setLenient(false);
        c.setTime(date);
        c.set(calendarField, amount);
        return c.getTime();
    }

    /**
     * 功能描述:
     * 〈对日期Date类型进行四舍五入〉
     *
     * @params : [date, field]
     * @return : java.util.Date
     * @author : cwl
     * @date : 2019/6/6 13:58
     */
    public static Date round(Date date, int field) {
        if (date == null) {
            throw new IllegalArgumentException("The date must not be null");
        }
        Calendar gval = Calendar.getInstance();
        gval.setTime(date);
        modify(gval, field, true);
        return gval.getTime();
    }

    /**
     * 功能描述:
     * 〈对日历类Calander类型进行四舍五入〉
     *
     * @params : [date, field]
     * @return : java.util.Calendar
     * @author : cwl
     * @date : 2019/6/6 13:58
     */
    public static Calendar round(Calendar date, int field) {
        if (date == null) {
            throw new IllegalArgumentException("The date must not be null");
        }
        Calendar rounded = (Calendar) date.clone();
        modify(rounded, field, true);
        return rounded;
    }

    /**
     * 功能描述:
     * 〈对Date类型或者Calendar类型进行四舍五入〉
     *
     * @params : [date, field]
     * @return : java.util.Date
     * @author : cwl
     * @date : 2019/6/6 14:02
     */
    public static Date round(Object date, int field) {
        if (date == null) {
            throw new IllegalArgumentException("The date must not be null");
        }
        if (date instanceof Date) {
            return round((Date) date, field);
        } else if (date instanceof Calendar) {
            return round((Calendar) date, field).getTime();
        } else {
            throw new ClassCastException("Could not round " + date);
        }
    }

    /**
     * 功能描述:
     * 〈截断日期,例如可以对分钟数进行取整截断,或者对小时进行取整截断,或者对秒数取整截断.仅接受日期类Date〉
     *
     * @params : [date, field]
     * @return : java.util.Date
     * @author : cwl
     * @date : 2019/6/6 14:04
     */
    public static Date truncate(Date date, int field) {
        if (date == null) {
            throw new IllegalArgumentException("The date must not be null");
        }
        Calendar gval = Calendar.getInstance();
        gval.setTime(date);
        modify(gval, field, false);
        return gval.getTime();
    }

    /**
     * 功能描述:
     * 〈截断日期,例如可以对分钟数进行取整截断,或者对小时进行取整截断,或者对秒数取整截断.仅接受日历类Calendar〉
     *
     * @params : [date, field]
     * @return : java.util.Calendar
     * @author : cwl
     * @date : 2019/6/6 14:06
     */
    public static Calendar truncate(Calendar date, int field) {
        if (date == null) {
            throw new IllegalArgumentException("The date must not be null");
        }
        Calendar truncated = (Calendar) date.clone();
        modify(truncated, field, false);
        return truncated;
    }

    /**
     * 功能描述:
     * 〈截断日期,例如可以对分钟数进行取整截断,或者对小时进行取整截断,或者对秒数取整截断.接受日历类和日期类〉
     *
     * @params : [date, field]
     * @return : java.util.Date
     * @author : cwl
     * @date : 2019/6/6 14:09
     */
    public static Date truncate(Object date, int field) {
        if (date == null) {
            throw new IllegalArgumentException("The date must not be null");
        }
        if (date instanceof Date) {
            return truncate((Date) date, field);
        } else if (date instanceof Calendar) {
            return truncate((Calendar) date, field).getTime();
        } else {
            throw new ClassCastException("Could not truncate " + date);
        }
    }

    private static void modify(Calendar val, int field, boolean round) {
        if (val.get(Calendar.YEAR) > 280000000) {
            throw new ArithmeticException("Calendar value too large for accurate calculations");
        }

        if (field == Calendar.MILLISECOND) {
            return;
        }
        // 手动截断毫秒、秒和分钟,而不是使用日历方法。
        Date date = val.getTime();
        long time = date.getTime();
        boolean done = false;

        // 截断毫秒
        int millisecs = val.get(Calendar.MILLISECOND);
        if (!round || millisecs < 500) {
            time = time - millisecs;
        }
        if (field == Calendar.SECOND) {
            done = true;
        }

        // 截断秒
        int seconds = val.get(Calendar.SECOND);
        if (!done && (!round || seconds < 30)) {
            time = time - (seconds * 1000L);
        }
        if (field == Calendar.MINUTE) {
            done = true;
        }

        // 截断分钟
        int minutes = val.get(Calendar.MINUTE);
        if (!done && (!round || minutes < 30)) {
            time = time - (minutes * 60000L);
        }

        // 重新设置时间
        if (date.getTime() != time) {
            date.setTime(time);
            val.setTime(date);
        }
        // ----------------- Fix for LANG-59 ----------------------- END ----------------
        boolean roundUp = false;
        for (int i = 0; i < fields.length; i++) {
            for (int j = 0; j < fields[i].length; j++) {
                if (fields[i][j] == field) {
                    //This is our field... we stop looping
                    if (round && roundUp) {
                        if (field == SEMI_MONTH) {
                            //判断这是每个月的上半旬还是下半旬,如果是上半旬,那么就加上15天减去1个月
                            if (val.get(Calendar.DATE) == 1) {
                                val.add(Calendar.DATE, 15);
                            } else {
                                val.add(Calendar.DATE, -15);
                                val.add(Calendar.MONTH, 1);
                            }
                        } else {
                            //这里需要+1,因为最后一个数字是四舍五入的
                            val.add(fields[i][0], 1);
                        }
                    }
                    return;
                }
            }
            // 对各种不同的类型进行四舍五入
            int offset = 0;
            boolean offsetSet = false;
            switch (field) {
                case SEMI_MONTH:
                    if (fields[i][0] == Calendar.DATE) {
                        offset = val.get(Calendar.DATE) - 1;
                        //如果offset大于15,那么说明是在下半个月
                        if (offset >= 15) {
                            offset -= 15;
                        }
                        //记录下我们是在这个范围的上半部分还是下半部分
                        roundUp = offset > 7;
                        offsetSet = true;
                    }
                    break;
                case Calendar.AM_PM:
                    if (fields[i][0] == Calendar.HOUR_OF_DAY) {
                        //对小时字段的值进行处理
                        offset = val.get(Calendar.HOUR_OF_DAY);
                        if (offset >= 12) {
                            offset -= 12;
                        }
                        roundUp = offset > 6;
                        offsetSet = true;
                    }
                    break;
            }
            if (!offsetSet) {
                int min = val.getActualMinimum(fields[i][0]);
                int max = val.getActualMaximum(fields[i][0]);
                //从允许的最小值计算偏移量
                offset = val.get(fields[i][0]) - min;
                //如果这是介于最小值和最大值之间的一半以上,则设置汇总
                roundUp = offset > ((max - min) / 2);
            }
            //我们需要移除这个字段
            if (offset != 0) {
                val.set(fields[i][0], val.get(fields[i][0]) - offset);
            }
        }
        throw new IllegalArgumentException("The field " + field + " is not supported");

    }

    /**
     * 功能描述:
     * 〈通过毫秒数millis,指定地区Locale,指定格式pattern 标准格式化时间〉
     *
     * @params : [millis, pattern, locale]
     * @return : java.lang.String
     * @author : cwl
     * @date : 2019/6/5 17:31
     */
    public static String formatUTC(long millis, String pattern, Locale locale) {
        return format(new Date(millis), pattern, UTC_TIME_ZONE, locale);
    }

    /**
     * 功能描述:
     * 〈返回一个从focus开始的迭代器〉
     *
     * @params : [focus, rangeStyle]
     * @return : java.util.Iterator
     * @author : cwl
     * @date : 2019/6/6 14:38
     */
    public static Iterator iterator(Date focus, int rangeStyle) {
        if (focus == null) {
            throw new IllegalArgumentException("The date must not be null");
        }
        Calendar gval = Calendar.getInstance();
        gval.setTime(focus);
        return iterator(gval, rangeStyle);
    }

    /**
     * 功能描述:
     * 〈返回一个从focus开始的迭代器〉
     *
     * @params : [focus, rangeStyle]
     * @return : java.util.Iterator
     * @author : cwl
     * @date : 2019/6/6 14:54
     */
    public static Iterator iterator(Calendar focus, int rangeStyle) {
        if (focus == null) {
            throw new IllegalArgumentException("The date must not be null");
        }
        Calendar start = null;
        Calendar end = null;
        int startCutoff = Calendar.SUNDAY;
        int endCutoff = Calendar.SATURDAY;
        switch (rangeStyle) {
            case RANGE_MONTH_SUNDAY:
            case RANGE_MONTH_MONDAY:
                // 从fucus当中截取它的月份作为起始月
                start = truncate(focus, Calendar.MONTH);
                // 拷贝起始月作为结束月,并且对结束月进行加一个月减一天的操作
                end = (Calendar) start.clone();
                end.add(Calendar.MONTH, 1);
                end.add(Calendar.DATE, -1);
                // 循环开始到开始到开始时间的前一个周一或者是周日
                if (rangeStyle == RANGE_MONTH_MONDAY) {
                    startCutoff = Calendar.MONDAY;
                    endCutoff = Calendar.SUNDAY;
                }
                break;
            case RANGE_WEEK_SUNDAY:
            case RANGE_WEEK_MONDAY:
            case RANGE_WEEK_RELATIVE:
            case RANGE_WEEK_CENTER:
                // 从fucus当中截取它的月份作为起始月
                start = truncate(focus, Calendar.DATE);
                end = truncate(focus, Calendar.DATE);
                switch (rangeStyle) {
                    case RANGE_WEEK_SUNDAY:
                        // already set by default
                        break;
                    case RANGE_WEEK_MONDAY:
                        startCutoff = Calendar.MONDAY;
                        endCutoff = Calendar.SUNDAY;
                        break;
                    case RANGE_WEEK_RELATIVE:
                        startCutoff = focus.get(Calendar.DAY_OF_WEEK);
                        endCutoff = startCutoff - 1;
                        break;
                    case RANGE_WEEK_CENTER:
                        startCutoff = focus.get(Calendar.DAY_OF_WEEK) - 3;
                        endCutoff = focus.get(Calendar.DAY_OF_WEEK) + 3;
                        break;
                }
                break;
            default:
                throw new IllegalArgumentException("The range style " + rangeStyle + " is not valid.");
        }
        if (startCutoff < Calendar.SUNDAY) {
            startCutoff += 7;
        }
        if (startCutoff > Calendar.SATURDAY) {
            startCutoff -= 7;
        }
        if (endCutoff < Calendar.SUNDAY) {
            endCutoff += 7;
        }
        if (endCutoff > Calendar.SATURDAY) {
            endCutoff -= 7;
        }
        while (start.get(Calendar.DAY_OF_WEEK) != startCutoff) {
            start.add(Calendar.DATE, -1);
        }
        while (end.get(Calendar.DAY_OF_WEEK) != endCutoff) {
            end.add(Calendar.DATE, 1);
        }
        return new DateIterator(start, end);
    }

    /**
     * 功能描述:
     * 〈获取一个日期类date或者是日历类Calendar迭代器对象〉
     *
     * @params : [focus, rangeStyle]
     * @return : java.util.Iterator
     * @author : cwl
     * @date : 2019/6/6 14:59
     */
    public static Iterator iterator(Object focus, int rangeStyle) {
        if (focus == null) {
            throw new IllegalArgumentException("The date must not be null");
        }
        if (focus instanceof Date) {
            return iterator((Date) focus, rangeStyle);
        } else if (focus instanceof Calendar) {
            return iterator((Calendar) focus, rangeStyle);
        } else {
            throw new ClassCastException("Could not iterate based on " + focus);
        }
    }

    //============================分割时间-仅Date类型==============================
    /**
     * 功能描述:
     * 〈分割出对应时间点的毫秒数〉
     *
     * @params : [date, fragment]
     * @return : long
     * @author : cwl
     * @date : 2019/6/6 15:03
     */
    public static long getFragmentInMilliseconds(Date date, int fragment) {
        return getFragment(date, fragment, Calendar.MILLISECOND);
    }

    /**
     * 功能描述:
     * 〈分割出对应时间的秒数〉
     *
     * @params : [date, fragment]
     * @return : long
     * @author : cwl
     * @date : 2019/6/6 15:03
     */
    public static long getFragmentInSeconds(Date date, int fragment) {
        return getFragment(date, fragment, Calendar.SECOND);
    }

    /**
     * 功能描述:
     * 〈分割出对应时间的秒数〉
     *
     * @params : [date, fragment]
     * @return : long
     * @author : cwl
     * @date : 2019/6/6 15:08
     */
    public static long getFragmentInMinutes(Date date, int fragment) {
        return getFragment(date, fragment, Calendar.MINUTE);
    }

    /**
     * 功能描述:
     * 〈分割出对应时间段的小时数〉
     *
     * @params : [date, fragment]
     * @return : long
     * @author : cwl
     * @date : 2019/6/6 15:08
     */
    public static long getFragmentInHours(Date date, int fragment) {
        return getFragment(date, fragment, Calendar.HOUR_OF_DAY);
    }

    /**
     * 功能描述:
     * 〈分割出对应时间的天数〉
     *
     * @params : [date, fragment]
     * @return : long
     * @author : cwl
     * @date : 2019/6/6 15:10
     */
    public static long getFragmentInDays(Date date, int fragment) {
        return getFragment(date, fragment, Calendar.DAY_OF_YEAR);
    }
    //============================分割时间-仅Date类型==============================

    //==========================分割时间-仅Calendar类型============================
    /**
     * 功能描述:
     * 〈分割时间毫秒数〉
     *
     * @params : [calendar, fragment]
     * @return : long
     * @author : cwl
     * @date : 2019/6/6 15:12
     */
    public static long getFragmentInMilliseconds(Calendar calendar, int fragment) {
        return getFragment(calendar, fragment, Calendar.MILLISECOND);
    }

    /**
     * 功能描述:
     * 〈分割时间秒数〉
     *
     * @params : [calendar, fragment]
     * @return : long
     * @author : cwl
     * @date : 2019/6/6 15:13
     */
    public static long getFragmentInSeconds(Calendar calendar, int fragment) {
        return getFragment(calendar, fragment, Calendar.SECOND);
    }

    /**
     * 功能描述:
     * 〈分割时间分钟数〉
     *
     * @params : [calendar, fragment]
     * @return : long
     * @author : cwl
     * @date : 2019/6/6 15:13
     */
    public static long getFragmentInMinutes(Calendar calendar, int fragment) {
        return getFragment(calendar, fragment, Calendar.MINUTE);
    }

    /**
     * 功能描述:
     * 〈分割时间小时数〉
     *
     * @params : [calendar, fragment]
     * @return : long
     * @author : cwl
     * @date : 2019/6/6 15:14
     */
    public static long getFragmentInHours(Calendar calendar, int fragment) {
        return getFragment(calendar, fragment, Calendar.HOUR_OF_DAY);
    }

    /**
     * 功能描述:
     * 〈分割时间天数〉
     *
     * @params : [calendar, fragment]
     * @return : long
     * @author : cwl
     * @date : 2019/6/6 15:14
     */
    public static long getFragmentInDays(Calendar calendar, int fragment) {
        return getFragment(calendar, fragment, Calendar.DAY_OF_YEAR);
    }

    /**
     * 功能描述:
     * 〈任意单元碎片的进行切割日期〉
     *
     * @params : [date, fragment, unit]
     * @return : long
     * @author : cwl
     * @date : 2019/6/6 15:16
     */
    private static long getFragment(Date date, int fragment, int unit) {
        if(date == null) {
            throw  new IllegalArgumentException("The date must not be null");
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return getFragment(calendar, fragment, unit);
    }

    /**
     * 功能描述:
     * 〈任意单元碎片的进行切割日历类时间〉
     *
     * @params : [calendar, fragment, unit]
     * @return : long
     * @author : cwl
     * @date : 2019/6/6 15:17
     */
    private static long getFragment(Calendar calendar, int fragment, int unit) {
        if(calendar == null) {
            throw  new IllegalArgumentException("The date must not be null");
        }
        long millisPerUnit = getMillisPerUnit(unit);
        long result = 0;

        // 大于一天的情况都分解成天来计算
        switch (fragment) {
            case Calendar.YEAR:
                result += (calendar.get(Calendar.DAY_OF_YEAR) * MILLIS_PER_DAY) / millisPerUnit;
                break;
            case Calendar.MONTH:
                result += (calendar.get(Calendar.DAY_OF_MONTH) * MILLIS_PER_DAY) / millisPerUnit;
                break;
        }

        switch (fragment) {
            // Number of days already calculated for these cases
            case Calendar.YEAR:
            case Calendar.MONTH:

                // The rest of the valid cases
            case Calendar.DAY_OF_YEAR:
            case Calendar.DATE:
                result += (calendar.get(Calendar.HOUR_OF_DAY) * MILLIS_PER_HOUR) / millisPerUnit;
            case Calendar.HOUR_OF_DAY:
                result += (calendar.get(Calendar.MINUTE) * MILLIS_PER_MINUTE) / millisPerUnit;
            case Calendar.MINUTE:
                result += (calendar.get(Calendar.SECOND) * MILLIS_PER_SECOND) / millisPerUnit;
            case Calendar.SECOND:
                result += (calendar.get(Calendar.MILLISECOND) * 1) / millisPerUnit;
                break;
            case Calendar.MILLISECOND: break;//never useful
            default: throw new IllegalArgumentException("The fragment " + fragment + " is not supported");
        }
        return result;
    }

    /**
     * 功能描述:
     * 〈返回任意单元对应的毫秒数〉
     *
     * @params : [unit]
     * @return : long
     * @author : cwl
     * @date : 2019/6/6 15:19
     */
    private static long getMillisPerUnit(int unit) {
        long result;
        switch (unit) {
            case Calendar.DAY_OF_YEAR:
            case Calendar.DATE:
                result = MILLIS_PER_DAY;
                break;
            case Calendar.HOUR_OF_DAY:
                result = MILLIS_PER_HOUR;
                break;
            case Calendar.MINUTE:
                result = MILLIS_PER_MINUTE;
                break;
            case Calendar.SECOND:
                result = MILLIS_PER_SECOND;
                break;
            case Calendar.MILLISECOND:
                result = 1;
                break;
            default: throw new IllegalArgumentException("The unit " + unit + " cannot be represented is milleseconds");
        }
        return result;
    }

    /**
     * 功能描述:
     * 〈指定日期date格式化〉
     *
     * @params : [date, pattern, locale]
     * @return : java.lang.String
     * @author : cwl
     * @date : 2019/6/5 17:32
     */
    public static String formatUTC(Date date, String pattern, Locale locale) {
        return format(date, pattern, UTC_TIME_ZONE, locale);
    }

    /**
     * 功能描述:
     * 〈指定格式pattern进行毫秒数格式化〉
     *
     * @params : [millis, pattern]
     * @return : java.lang.String
     * @author : cwl
     * @date : 2019/6/5 17:32
     */
    public static String format(long millis, String pattern) {
        return format(new Date(millis), pattern, null, null);
    }

    /**
     * 功能描述:
     * 〈指定pattern格式化date日期〉
     *
     * @params : [date, pattern]
     * @return : java.lang.String
     * @author : cwl
     * @date : 2019/6/5 17:33
     */
    public static String format(Date date, String pattern) {
        return format(date, pattern, null, null);
    }

    /**
     * 功能描述:
     * 〈指定格式化Calendar日历类〉
     *
     * @params : [calendar, pattern]
     * @return : java.lang.String
     * @author : cwl
     * @date : 2019/6/5 17:33
     */
    public static String format(Calendar calendar, String pattern) {
        return format(calendar, pattern, null, null);
    }

    /**
     * 功能描述:
     * 〈指定时区和格式pattern格式化millis〉
     *
     * @params : [millis, pattern, timeZone]
     * @return : java.lang.String
     * @author : cwl
     * @date : 2019/6/5 17:34
     */
    public static String format(long millis, String pattern, TimeZone timeZone) {
        return format(new Date(millis), pattern, timeZone, null);
    }

    /**
     * 功能描述:
     * 〈指定日期date和timeZone时区以及格式pattern进行格式化〉
     *
     * @params : [date, pattern, timeZone]
     * @return : java.lang.String
     * @author : cwl
     * @date : 2019/6/5 17:35
     */
    public static String format(Date date, String pattern, TimeZone timeZone) {
        return format(date, pattern, timeZone, null);
    }

    /**
     * 功能描述:
     * 〈指定时区timeZone,格式pattern,日历类calendar格式化时间〉
     *
     * @params : [calendar, pattern, timeZone]
     * @return : java.lang.String
     * @author : cwl
     * @date : 2019/6/5 17:35
     */
    public static String format(Calendar calendar, String pattern, TimeZone timeZone) {
        return format(calendar, pattern, timeZone, null);
    }

    /**
     * 功能描述:
     * 〈指定格式和地区格式化date〉
     *
     * @params : [date, pattern, locale]
     * @return : java.lang.String
     * @author : cwl
     * @date : 2019/6/5 18:00
     */
    public static String format(Date date, String pattern, Locale locale) {
        return format(date, pattern, null, locale);
    }

    /**
     * 功能描述:
     * 〈指定地区和格式,格式化毫秒数〉
     *
     * @params : [millis, pattern, locale]
     * @return : java.lang.String
     * @author : cwl
     * @date : 2019/6/5 17:37
     */
    public static String format(long millis, String pattern, Locale locale) {
        return format(new Date(millis), pattern, null, locale);
    }

    /**
     * 功能描述:
     * 〈指定格式和地区格式化日历类〉
     *
     * @params : [calendar, pattern, locale]
     * @return : java.lang.String
     * @author : cwl
     * @date : 2019/6/5 18:01
     */
    public static String format(Calendar calendar, String pattern, Locale locale) {
        return format(calendar, pattern, null, locale);
    }

    /**
     * 功能描述:
     * 〈指定格式时区和地区格式化毫秒数〉
     *
     * @params : [millis, pattern, timeZone, locale]
     * @return : java.lang.String
     * @author : cwl
     * @date : 2019/6/5 18:02
     */
    public static String format(long millis, String pattern, TimeZone timeZone, Locale locale) {
        return format(new Date(millis), pattern, timeZone, locale);
    }

    /**
     * 功能描述:
     * 〈指定格式/时区/地区格式化日期〉
     *
     * @params : [date, pattern, timeZone, locale]
     * @return : java.lang.String
     * @author : cwl
     * @date : 2019/6/5 18:04
     */
    public static String format(Date date, String pattern, TimeZone timeZone, Locale locale) {
        FastDateFormat df = FastDateFormat.getInstance(pattern, timeZone, locale);
        return df.format(date);
    }

    /**
     * 功能描述:
     * 〈指定格式/时区/地区格式化日历类〉
     *
     * @params : [calendar, pattern, timeZone, locale]
     * @return : java.lang.String
     * @author : cwl
     * @date : 2019/6/5 18:05
     */
    public static String format(Calendar calendar, String pattern, TimeZone timeZone, Locale locale) {
        FastDateFormat df = FastDateFormat.getInstance(pattern, timeZone, locale);
        return df.format(calendar);
    }

    //迭代日期的构造器
    static class DateIterator implements Iterator {
        private final Calendar endFinal;
        private final Calendar spot;

        /**
         * 功能描述:
         * 〈从开始日期startFinal到结束日期endFinal的迭代器〉
         *
         * @params : [startFinal, endFinal]
         * @return :
         * @author : cwl
         * @date : 2019/6/6 14:43
         */
        DateIterator(Calendar startFinal, Calendar endFinal) {
            super();
            this.endFinal = endFinal;
            spot = startFinal;
            spot.add(Calendar.DATE, -1);
        }

        /**
         * 功能描述:
         * 〈迭代器是否已经达到了结束日期〉
         *
         * @params : []
         * @return : boolean
         * @author : cwl
         * @date : 2019/6/6 14:44
         */
        public boolean hasNext() {
            return spot.before(endFinal);
        }

        /**
         * 功能描述:
         * 〈在迭代器循环当中,返回下一个日历对象〉
         *
         * @params : []
         * @return : java.lang.Object
         * @author : cwl
         * @date : 2019/6/6 14:45
         */
        public Object next() {
            if (spot.equals(endFinal)) {
                throw new NoSuchElementException();
            }
            spot.add(Calendar.DATE, 1);
            return spot.clone();
        }

        /**
         * 功能描述:
         * 〈覆盖于父类的方法,用于抛出一个不可操作的异常〉
         *
         * @params : []
         * @return : void
         * @author : cwl
         * @date : 2019/6/6 14:46
         */
        public void remove() {
            throw new UnsupportedOperationException();
        }
    }

    //快速日期格式化
    public static class FastDateFormat extends Format{
        //支持序列化
        private static final long serialVersionUID = 1L;
        //全样式模式的常量,表示日期格式为全样式
        public static final int FULL = DateFormat.FULL;
        //长区域的时间样式
        public static final int LONG = DateFormat.LONG;
        //中间地区地区的时间样式
        public static final int MEDIUM = DateFormat.MEDIUM;
        //短区域的时间样式
        public static final int SHORT = DateFormat.SHORT;
        //默认的时间样式
        private static String cDefaultPattern;
        //对象缓存
        private static final Map cInstanceCache = new HashMap(7);
        private static final Map cDateInstanceCache = new HashMap(7);
        private static final Map cTimeInstanceCache = new HashMap(7);
        private static final Map cDateTimeInstanceCache = new HashMap(7);
        private static final Map cTimeZoneDisplayCache = new HashMap(7);

        private final String mPattern;//日期样式
        private final TimeZone mTimeZone;//时区
        private final boolean mTimeZoneForced;//是否使用默认时区
        private final Locale mLocale;//地区
        private final boolean mLocaleForced;//是否使用默认地区
        private transient int mMaxLengthEstimate;//预计的最大长度

        private transient Rule[] mRules;

        /**
         * 功能描述:
         * 〈获取一个默认的日期格式化对象〉
         *
         * @params : []
         * @return : com.simple.util.time.DateUtils.FastDateFormat
         * @author : cwl
         * @date : 2019/6/4 17:21
         */
        public static FastDateFormat getInstance() {
            return getInstance(getDefaultPattern(), null, null);
        }

        /**
         * 功能描述:
         * 〈获取一个指定的日期格式化对象,指定格式为pattern〉
         *
         * @params : [pattern]
         * @return : com.simple.util.time.DateUtils.FastDateFormat
         * @author : cwl
         * @date : 2019/6/4 17:22
         */
        public static FastDateFormat getInstance(String pattern) {
            return getInstance(pattern, null, null);
        }

        /**
         * 功能描述:
         * 〈创建一个指定格式pattern与时区timeZone的日期格式化对象〉
         *
         * @params : [pattern, timeZone]
         * @return : com.simple.util.time.DateUtils.FastDateFormat
         * @author : cwl
         * @date : 2019/6/4 17:23
         */
        public static FastDateFormat getInstance(String pattern, TimeZone timeZone) {
            return getInstance(pattern, timeZone, null);
        }

        /**
         * 功能描述:
         * 〈创建一个指定格式pattern和指定地区locale的日期格式化对象〉
         *
         * @params : [pattern, locale]
         * @return : com.simple.util.time.DateUtils.FastDateFormat
         * @author : cwl
         * @date : 2019/6/4 17:24
         */
        public static FastDateFormat getInstance(String pattern, Locale locale) {
            return getInstance(pattern, null, locale);
        }

        /**
         * 功能描述:
         * 〈创建一个指定格式pattern,指定时区timeZone,指定地区locale的日期格式化对象,为了避免重复创建,使用synchronize同步方法〉
         *
         * @params : [pattern, timeZone, locale]
         * @return : com.simple.util.time.DateUtils.FastDateFormat
         * @author : cwl
         * @date : 2019/6/4 17:25
         */
        public static synchronized FastDateFormat getInstance(String pattern, TimeZone timeZone, Locale locale) {
            FastDateFormat emptyFormat = new FastDateFormat(pattern, timeZone, locale);
            FastDateFormat format = (FastDateFormat) cInstanceCache.get(emptyFormat);
            if (format == null) {
                format = emptyFormat;
                format.init();  // convert shell format into usable one
                cInstanceCache.put(format, format);  // this is OK!
            }
            return format;
        }

        /**
         * 功能描述:
         * 〈获得指定日期样式的日期格式化对象〉
         *
         * @params : [style]
         * @return : com.simple.util.time.DateUtils.FastDateFormat
         * @author : cwl
         * @date : 2019/6/4 17:26
         */
        public static FastDateFormat getDateInstance(int style) {
            return getDateInstance(style, null, null);
        }

        /**
         * 功能描述:
         * 〈获得指定日期样式style和地区locale的日期格式化对象〉
         *
         * @params : [style, locale]
         * @return : com.simple.util.time.DateUtils.FastDateFormat
         * @author : cwl
         * @date : 2019/6/4 17:27
         */
        public static FastDateFormat getDateInstance(int style, Locale locale) {
            return getDateInstance(style, null, locale);
        }

        /**
         * 功能描述:
         * 〈获得指定日期样式style和时区timeZone的日期格式化对象〉
         *
         * @params : [style, timeZone]
         * @return : com.simple.util.time.DateUtils.FastDateFormat
         * @author : cwl
         * @date : 2019/6/4 17:28
         */
        public static FastDateFormat getDateInstance(int style, TimeZone timeZone) {
            return getDateInstance(style, timeZone, null);
        }

        /**
         * 功能描述:
         * 〈获得指定日期样式style和时区timeZone以及指定地区locale的日期格式化对象〉
         *
         * @params : [style, timeZone, locale]
         * @return : com.simple.util.time.DateUtils.FastDateFormat
         * @author : cwl
         * @date : 2019/6/4 17:29
         */
        public static synchronized FastDateFormat getDateInstance(int style, TimeZone timeZone, Locale locale) {
            Object key = new Integer(style);
            if (timeZone != null) {
                key = new Pair(key, timeZone);
            }

            if (locale == null) {
                locale = Locale.getDefault();
            }

            key = new Pair(key, locale);

            FastDateFormat format = (FastDateFormat) cDateInstanceCache.get(key);
            if (format == null) {
                try {
                    SimpleDateFormat formatter = (SimpleDateFormat) DateFormat.getDateInstance(style, locale);
                    String pattern = formatter.toPattern();
                    format = getInstance(pattern, timeZone, locale);
                    cDateInstanceCache.put(key, format);

                } catch (ClassCastException ex) {
                    throw new IllegalArgumentException("No date pattern for locale: " + locale);
                }
            }
            return format;
        }

        /**
         * 功能描述:
         * 〈获得指定时间样式style的日期格式化对象〉
         *
         * @params : [style]
         * @return : com.simple.util.time.DateUtils.FastDateFormat
         * @author : cwl
         * @date : 2019/6/4 17:30
         */
        public static FastDateFormat getTimeInstance(int style) {
            return getTimeInstance(style, null, null);
        }

        /**
         * 功能描述:
         * 〈获得指定地区locale和样式style的时间格式化对象〉
         *
         * @params : [style, locale]
         * @return : com.simple.util.time.DateUtils.FastDateFormat
         * @author : cwl
         * @date : 2019/6/4 17:31
         */
        public static FastDateFormat getTimeInstance(int style, Locale locale) {
            return getTimeInstance(style, null, locale);
        }

        /**
         * 功能描述:
         * 〈获得指定样式style和指定时区timeZone的时间格式化对象〉
         *
         * @params : [style, timeZone]
         * @return : com.simple.util.time.DateUtils.FastDateFormat
         * @author : cwl
         * @date : 2019/6/4 17:31
         */
        public static FastDateFormat getTimeInstance(int style, TimeZone timeZone) {
            return getTimeInstance(style, timeZone, null);
        }

        /**
         * 功能描述:
         * 〈获得指定样式style和指定时区timeZone以及指定地区locale的时间格式化对象〉
         *
         * @params : [style, timeZone, locale]
         * @return : com.simple.util.time.DateUtils.FastDateFormat
         * @author : cwl
         * @date : 2019/6/4 17:32
         */
        public static synchronized FastDateFormat getTimeInstance(int style, TimeZone timeZone, Locale locale) {
            Object key = new Integer(style);
            if (timeZone != null) {
                key = new Pair(key, timeZone);
            }
            if (locale != null) {
                key = new Pair(key, locale);
            }

            FastDateFormat format = (FastDateFormat) cTimeInstanceCache.get(key);
            if (format == null) {
                if (locale == null) {
                    locale = Locale.getDefault();
                }

                try {
                    SimpleDateFormat formatter = (SimpleDateFormat) DateFormat.getTimeInstance(style, locale);
                    String pattern = formatter.toPattern();
                    format = getInstance(pattern, timeZone, locale);
                    cTimeInstanceCache.put(key, format);

                } catch (ClassCastException ex) {
                    throw new IllegalArgumentException("No date pattern for locale: " + locale);
                }
            }
            return format;
        }

        /**
         * 功能描述:
         * 〈获得时间与日期格式化对象,指定日期样式dateStyle和指定时间样式timeStyle〉
         *
         * @params : [dateStyle, timeStyle]
         * @return : com.simple.util.time.DateUtils.FastDateFormat
         * @author : cwl
         * @date : 2019/6/4 17:33
         */
        public static FastDateFormat getDateTimeInstance(
                int dateStyle, int timeStyle) {
            return getDateTimeInstance(dateStyle, timeStyle, null, null);
        }

        /**
         * 功能描述:
         * 〈获得时间与日期格式化对象,指定日期样式dateStyle和指定时间样式timeStyle,指定地区locale〉
         *
         * @params : [dateStyle, timeStyle, locale]
         * @return : com.simple.util.time.DateUtils.FastDateFormat
         * @author : cwl
         * @date : 2019/6/4 17:34
         */
        public static FastDateFormat getDateTimeInstance(
                int dateStyle, int timeStyle, Locale locale) {
            return getDateTimeInstance(dateStyle, timeStyle, null, locale);
        }

        /**
         * 功能描述:
         * 〈获得时间与日期格式化对象,指定日期样式dateStyle和指定时间样式timeStyle,指定时区timeZone〉
         *
         * @params : [dateStyle, timeStyle, timeZone]
         * @return : com.simple.util.time.DateUtils.FastDateFormat
         * @author : cwl
         * @date : 2019/6/4 17:34
         */
        public static FastDateFormat getDateTimeInstance(
                int dateStyle, int timeStyle, TimeZone timeZone) {
            return getDateTimeInstance(dateStyle, timeStyle, timeZone, null);
        }

        /**
         * 功能描述:
         * 〈获得时间与日期格式化对象,指定日期样式dateStyle和指定时间样式timeStyle,指定时区timeZone,指定地区locale〉
         *
         * @params : [dateStyle, timeStyle, timeZone, locale]
         * @return : com.simple.util.time.DateUtils.FastDateFormat
         * @author : cwl
         * @date : 2019/6/4 17:35
         */
        public static synchronized FastDateFormat getDateTimeInstance(int dateStyle, int timeStyle, TimeZone timeZone,
                                                                      Locale locale) {

            Object key = new Pair(new Integer(dateStyle), new Integer(timeStyle));
            if (timeZone != null) {
                key = new Pair(key, timeZone);
            }
            if (locale == null) {
                locale = Locale.getDefault();
            }
            key = new Pair(key, locale);

            FastDateFormat format = (FastDateFormat) cDateTimeInstanceCache.get(key);
            if (format == null) {
                try {
                    SimpleDateFormat formatter = (SimpleDateFormat) DateFormat.getDateTimeInstance(dateStyle, timeStyle,
                            locale);
                    String pattern = formatter.toPattern();
                    format = getInstance(pattern, timeZone, locale);
                    cDateTimeInstanceCache.put(key, format);

                } catch (ClassCastException ex) {
                    throw new IllegalArgumentException("No date time pattern for locale: " + locale);
                }
            }
            return format;
        }

        /**
         * 功能描述:
         * 〈获取时区显示名称,使用缓存以提高性能.daylight为是否是白天,style选择样式,locale选择地区〉
         *
         * @params : [tz, daylight, style, locale]
         * @return : java.lang.String
         * @author : cwl
         * @date : 2019/6/4 17:37
         */
        public static synchronized String getTimeZoneDisplay(TimeZone tz, boolean daylight, int style, Locale locale) {
            Object key = new TimeZoneDisplayKey(tz, daylight, style, locale);
            String value = (String) cTimeZoneDisplayCache.get(key);
            if (value == null) {
                // This is a very slow call, so cache the results.
                value = tz.getDisplayName(daylight, style, locale);
                cTimeZoneDisplayCache.put(key, value);
            }
            return value;
        }

        /**
         * 功能描述:
         * 〈获得默认的日期格式〉
         *
         * @params : []
         * @return : java.lang.String
         * @author : cwl
         * @date : 2019/6/4 17:38
         */
        private static synchronized String getDefaultPattern() {
            if (cDefaultPattern == null) {
                cDefaultPattern = new SimpleDateFormat().toPattern();
            }
            return cDefaultPattern;
        }
        
        /**
         * 功能描述: 
         * 〈创建一个指定样式pattern,指定时区timeZone,指定地区locale的日期格式化对象〉
         *
         * @params : [pattern, timeZone, locale]
         * @return :
         * @author : cwl
         * @date : 2019/6/4 17:39
         */
        private FastDateFormat(String pattern, TimeZone timeZone, Locale locale) {
            super();
            if (pattern == null) {
                throw new IllegalArgumentException("The pattern must not be null");
            }
            mPattern = pattern;

            mTimeZoneForced = (timeZone != null);
            if (timeZone == null) {
                timeZone = TimeZone.getDefault();
            }
            mTimeZone = timeZone;

            mLocaleForced = (locale != null);
            if (locale == null) {
                locale = Locale.getDefault();
            }
            mLocale = locale;
        }

        /**
         * 功能描述:
         * 〈初始化日期格式〉
         *
         * @params : []
         * @return : void
         * @author : cwl
         * @date : 2019/6/4 17:44
         */
        private void init() {
            List rulesList = parsePattern();
            mRules = (Rule[]) rulesList.toArray(new Rule[rulesList.size()]);

            int len = 0;
            for (int i=mRules.length; --i >= 0; ) {
                len += mRules[i].estimateLength();
            }

            mMaxLengthEstimate = len;
        }

        /**
         * 功能描述:
         * 〈获得给定模式的规则集合〉
         *
         * @params : []
         * @return : java.util.List
         * @author : cwl
         * @date : 2019/6/4 17:45
         */
        private List parsePattern() {
            DateFormatSymbols symbols = new DateFormatSymbols(mLocale);
            List rules = new ArrayList();

            String[] ERAs = symbols.getEras();
            String[] months = symbols.getMonths();
            String[] shortMonths = symbols.getShortMonths();
            String[] weekdays = symbols.getWeekdays();
            String[] shortWeekdays = symbols.getShortWeekdays();
            String[] AmPmStrings = symbols.getAmPmStrings();

            int length = mPattern.length();
            int[] indexRef = new int[1];

            for (int i = 0; i < length; i++) {
                indexRef[0] = i;
                String token = parseToken(mPattern, indexRef);
                i = indexRef[0];

                int tokenLen = token.length();
                if (tokenLen == 0) {
                    break;
                }

                Rule rule;
                char c = token.charAt(0);

                switch (c) {
                    case 'G': // era designator (text)
                        rule = new TextField(Calendar.ERA, ERAs);
                        break;
                    case 'y': // year (number)
                        if (tokenLen >= 4) {
                            rule = selectNumberRule(Calendar.YEAR, tokenLen);
                        } else {
                            rule = TwoDigitYearField.INSTANCE;
                        }
                        break;
                    case 'M': // month in year (text and number)
                        if (tokenLen >= 4) {
                            rule = new TextField(Calendar.MONTH, months);
                        } else if (tokenLen == 3) {
                            rule = new TextField(Calendar.MONTH, shortMonths);
                        } else if (tokenLen == 2) {
                            rule = TwoDigitMonthField.INSTANCE;
                        } else {
                            rule = UnpaddedMonthField.INSTANCE;
                        }
                        break;
                    case 'd': // day in month (number)
                        rule = selectNumberRule(Calendar.DAY_OF_MONTH, tokenLen);
                        break;
                    case 'h': // hour in am/pm (number, 1..12)
                        rule = new TwelveHourField(selectNumberRule(Calendar.HOUR, tokenLen));
                        break;
                    case 'H': // hour in day (number, 0..23)
                        rule = selectNumberRule(Calendar.HOUR_OF_DAY, tokenLen);
                        break;
                    case 'm': // minute in hour (number)
                        rule = selectNumberRule(Calendar.MINUTE, tokenLen);
                        break;
                    case 's': // second in minute (number)
                        rule = selectNumberRule(Calendar.SECOND, tokenLen);
                        break;
                    case 'S': // millisecond (number)
                        rule = selectNumberRule(Calendar.MILLISECOND, tokenLen);
                        break;
                    case 'E': // day in week (text)
                        rule = new TextField(Calendar.DAY_OF_WEEK, tokenLen < 4 ? shortWeekdays : weekdays);
                        break;
                    case 'D': // day in year (number)
                        rule = selectNumberRule(Calendar.DAY_OF_YEAR, tokenLen);
                        break;
                    case 'F': // day of week in month (number)
                        rule = selectNumberRule(Calendar.DAY_OF_WEEK_IN_MONTH, tokenLen);
                        break;
                    case 'w': // week in year (number)
                        rule = selectNumberRule(Calendar.WEEK_OF_YEAR, tokenLen);
                        break;
                    case 'W': // week in month (number)
                        rule = selectNumberRule(Calendar.WEEK_OF_MONTH, tokenLen);
                        break;
                    case 'a': // am/pm marker (text)
                        rule = new TextField(Calendar.AM_PM, AmPmStrings);
                        break;
                    case 'k': // hour in day (1..24)
                        rule = new TwentyFourHourField(selectNumberRule(Calendar.HOUR_OF_DAY, tokenLen));
                        break;
                    case 'K': // hour in am/pm (0..11)
                        rule = selectNumberRule(Calendar.HOUR, tokenLen);
                        break;
                    case 'z': // time zone (text)
                        if (tokenLen >= 4) {
                            rule = new TimeZoneNameRule(mTimeZone, mTimeZoneForced, mLocale, TimeZone.LONG);
                        } else {
                            rule = new TimeZoneNameRule(mTimeZone, mTimeZoneForced, mLocale, TimeZone.SHORT);
                        }
                        break;
                    case 'Z': // time zone (value)
                        if (tokenLen == 1) {
                            rule = TimeZoneNumberRule.INSTANCE_NO_COLON;
                        } else {
                            rule = TimeZoneNumberRule.INSTANCE_COLON;
                        }
                        break;
                    case '\'': // literal text
                        String sub = token.substring(1);
                        if (sub.length() == 1) {
                            rule = new CharacterLiteral(sub.charAt(0));
                        } else {
                            rule = new StringLiteral(sub);
                        }
                        break;
                    default:
                        throw new IllegalArgumentException("Illegal pattern component: " + token);
                }

                rules.add(rule);
            }

            return rules;
        }

        /**
         * 功能描述:
         * 〈解析格式pattern〉
         *
         * @params : [pattern, indexRef]
         * @return : java.lang.String
         * @author : cwl
         * @date : 2019/6/4 17:47
         */
        private String parseToken(String pattern, int[] indexRef) {
            StringBuffer buf = new StringBuffer();

            int i = indexRef[0];
            int length = pattern.length();

            char c = pattern.charAt(i);
            if (c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z') {
                // Scan a run of the same character, which indicates a time
                // pattern.
                buf.append(c);

                while (i + 1 < length) {
                    char peek = pattern.charAt(i + 1);
                    if (peek == c) {
                        buf.append(c);
                        i++;
                    } else {
                        break;
                    }
                }
            } else {
                // This will identify token as text.
                buf.append('\'');

                boolean inLiteral = false;

                for (; i < length; i++) {
                    c = pattern.charAt(i);

                    if (c == '\'') {
                        if (i + 1 < length && pattern.charAt(i + 1) == '\'') {
                            // '' is treated as escaped '
                            i++;
                            buf.append(c);
                        } else {
                            inLiteral = !inLiteral;
                        }
                    } else if (!inLiteral &&
                            (c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z')) {
                        i--;
                        break;
                    } else {
                        buf.append(c);
                    }
                }
            }

            indexRef[0] = i;
            return buf.toString();
        }

        /**
         * 功能描述:
         * 〈获取所需要的数字规则〉
         *
         * @params : [field, padding]
         * @return : com.simple.util.time.DateUtils.FastDateFormat.NumberRule
         * @author : cwl
         * @date : 2019/6/4 17:48
         */
        private NumberRule selectNumberRule(int field, int padding) {
            switch (padding) {
                case 1:
                    return new UnpaddedNumberField(field);
                case 2:
                    return new TwoDigitNumberField(field);
                default:
                    return new PaddedNumberField(field, padding);
            }
        }

        /**
         * 功能描述:
         * 〈格式化Date或者Calender日期类〉
         *
         * @params : [obj, toAppendTo, pos]
         * @return : java.lang.StringBuffer
         * @author : cwl
         * @date : 2019/6/4 17:50
         */
        @Override
        public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos) {
            if (obj instanceof Date) {
                return format((Date) obj, toAppendTo);
            } else if (obj instanceof Calendar) {
                return format((Calendar) obj, toAppendTo);
            } else if (obj instanceof Long) {
                return format(((Long) obj).longValue(), toAppendTo);
            } else {
                throw new IllegalArgumentException("Unknown class: " +
                        (obj == null ? "<null>" : obj.getClass().getName()));
            }
        }

        /**
         * 功能描述:
         * 〈格式化毫秒数〉
         *
         * @params : [millis]
         * @return : java.lang.String
         * @author : cwl
         * @date : 2019/6/4 17:50
         */
        public String format(long millis) {
            return format(new Date(millis));
        }

        /**
         * 功能描述:
         * 〈格式化date日期类〉
         *
         * @params : [date]
         * @return : java.lang.String
         * @author : cwl
         * @date : 2019/6/4 17:51
         */
        public String format(Date date) {
            Calendar c = new GregorianCalendar(mTimeZone);
            c.setTime(date);
            return applyRules(c, new StringBuffer(mMaxLengthEstimate)).toString();
        }

        /**
         * 功能描述:
         * 〈格式化Clalendar日期〉
         *
         * @params : [calendar]
         * @return : java.lang.String
         * @author : cwl
         * @date : 2019/6/4 17:52
         */
        public String format(Calendar calendar) {
            return format(calendar, new StringBuffer(mMaxLengthEstimate)).toString();
        }

        /**
         * 功能描述:
         * 〈格式化毫秒数,结果缓存到buf当中〉
         *
         * @params : [millis, buf]
         * @return : java.lang.StringBuffer
         * @author : cwl
         * @date : 2019/6/4 17:52
         */
        public StringBuffer format(long millis, StringBuffer buf) {
            return format(new Date(millis), buf);
        }

        /**
         * 功能描述:
         * 〈格式化Date日期类型,并且将结果缓存到buf当中〉
         *
         * @params : [date, buf]
         * @return : java.lang.StringBuffer
         * @author : cwl
         * @date : 2019/6/4 17:53
         */
        public StringBuffer format(Date date, StringBuffer buf) {
            Calendar c = new GregorianCalendar(mTimeZone);
            c.setTime(date);
            return applyRules(c, buf);
        }

        /**
         * 功能描述:
         * 〈格式化Calendar日期类型,并且将结果缓存到buf当中〉
         *
         * @params : [calendar, buf]
         * @return : java.lang.StringBuffer
         * @author : cwl
         * @date : 2019/6/4 17:54
         */
        public StringBuffer format(Calendar calendar, StringBuffer buf) {
            if (mTimeZoneForced) {
                calendar = (Calendar) calendar.clone();
                calendar.setTimeZone(mTimeZone);
            }
            return applyRules(calendar, buf);
        }

        /**
         * 功能描述:
         * 〈通过将规则应用于指定的日历来执行格式化〉
         *
         * @params : [calendar, buf]
         * @return : java.lang.StringBuffer
         * @author : cwl
         * @date : 2019/6/4 17:55
         */
        private StringBuffer applyRules(Calendar calendar, StringBuffer buf) {
            Rule[] rules = mRules;
            int len = mRules.length;
            for (int i = 0; i < len; i++) {
                rules[i].appendTo(buf, calendar);
            }
            return buf;
        }

        public String getmPattern() {
            return mPattern;
        }

        public TimeZone getmTimeZone() {
            return mTimeZone;
        }

        public boolean ismTimeZoneForced() {
            return mTimeZoneForced;
        }

        public Locale getmLocale() {
            return mLocale;
        }

        public boolean ismLocaleForced() {
            return mLocaleForced;
        }

        public int getmMaxLengthEstimate() {
            return mMaxLengthEstimate;
        }

        @Override
        public boolean equals(Object obj) {
            if (obj instanceof FastDateFormat == false) {
                return false;
            }
            FastDateFormat other = (FastDateFormat) obj;
            if (
                    (mPattern == other.mPattern || mPattern.equals(other.mPattern)) &&
                            (mTimeZone == other.mTimeZone || mTimeZone.equals(other.mTimeZone)) &&
                            (mLocale == other.mLocale || mLocale.equals(other.mLocale)) &&
                            (mTimeZoneForced == other.mTimeZoneForced) &&
                            (mLocaleForced == other.mLocaleForced)
            ) {
                return true;
            }
            return false;
        }

        @Override
        public int hashCode() {
            int total = 0;
            total += mPattern.hashCode();
            total += mTimeZone.hashCode();
            total += (mTimeZoneForced ? 1 : 0);
            total += mLocale.hashCode();
            total += (mLocaleForced ? 1 : 0);
            return total;
        }

        private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
            in.defaultReadObject();
            init();
        }

        @Override
        public String toString() {
            return "FastDateFormat[" + mPattern + "]";
        }
        //用于定义一个规则的接口
        private interface Rule {

            /**
             * 功能描述:
             * 〈返回预计的长度〉
             *
             * @params : []
             * @return : int
             * @author : cwl
             * @date : 2019/6/4 16:47
             */
            int estimateLength();

            /**
             * 功能描述:
             * 〈根据规则实现将指定日历的值添加到StringBuffer缓存当中〉
             *
             * @params : [buffer, calendar]
             * @return : void
             * @author : cwl
             * @date : 2019/6/4 16:48
             */
            void appendTo(StringBuffer buffer, Calendar calendar);
        }

        //定义一个数字的规则
        private interface NumberRule extends Rule {

            /**
             * 功能描述:
             * 〈将指定值添加到buffer当中〉
             *
             * @params : [buffer, value]
             * @return : void
             * @author : cwl
             * @date : 2019/6/4 16:50
             */
            void appendTo(StringBuffer buffer, int value);
        }

        //输出一个常量的字符
        private static class CharacterLiteral implements Rule {
            private final char mValue;

            CharacterLiteral(char value) {
                mValue = value;
            }

            public int estimateLength() {
                return 1;
            }

            public void appendTo(StringBuffer buffer, Calendar calendar) {
                buffer.append(mValue);
            }
        }
        @Override
        public Object parseObject(String source, ParsePosition pos) {
            pos.setIndex(0);
            pos.setErrorIndex(0);
            return null;
        }

        //用于输出一个常量字符
        private static class StringLiteral implements Rule {
            private final String mValue;

            StringLiteral(String value) {
                mValue = value;
            }

            public int estimateLength() {
                return mValue.length();
            }

            public void appendTo(StringBuffer buffer, Calendar calendar) {
                buffer.append(mValue);
            }
        }

        //输出一组值当中的一个
        private static class TextField implements Rule {
            private final int mField;
            private final String[] mValues;

            TextField(int field, String[] values) {
                mField = field;
                mValues = values;
            }
            public int estimateLength() {
                int max = 0;
                for (int i=mValues.length; --i >= 0; ) {
                    int len = mValues[i].length();
                    if (len > max) {
                        max = len;
                    }
                }
                return max;
            }

            public void appendTo(StringBuffer buffer, Calendar calendar) {
                buffer.append(mValues[calendar.get(mField)]);
            }
        }

        //输出年份
        private static class UnpaddedNumberField implements NumberRule {
            static final UnpaddedNumberField INSTANCE_YEAR = new UnpaddedNumberField(Calendar.YEAR);

            private final int mField;

            UnpaddedNumberField(int field) {
                mField = field;
            }

            public int estimateLength() {
                return 4;
            }
            public void appendTo(StringBuffer buffer, Calendar calendar) {
                appendTo(buffer, calendar.get(mField));
            }
            public final void appendTo(StringBuffer buffer, int value) {
                if (value < 10) {
                    buffer.append((char)(value + '0'));
                } else if (value < 100) {
                    buffer.append((char)(value / 10 + '0'));
                    buffer.append((char)(value % 10 + '0'));
                } else {
                    buffer.append(Integer.toString(value));
                }
            }
        }

        //输出月份
        private static class UnpaddedMonthField implements NumberRule {
            static final UnpaddedMonthField INSTANCE = new UnpaddedMonthField();
            UnpaddedMonthField() {
                super();
            }
            public int estimateLength() {
                return 2;
            }
            public void appendTo(StringBuffer buffer, Calendar calendar) {
                appendTo(buffer, calendar.get(Calendar.MONTH) + 1);
            }
            public final void appendTo(StringBuffer buffer, int value) {
                if (value < 10) {
                    buffer.append((char)(value + '0'));
                } else {
                    buffer.append((char)(value / 10 + '0'));
                    buffer.append((char)(value % 10 + '0'));
                }
            }
        }

        //用于填充两位数的内部类
        private static class PaddedNumberField implements NumberRule {
            private final int mField;
            private final int mSize;

            PaddedNumberField(int field, int size) {
                if (size < 3) {
                    // Should use UnpaddedNumberField or TwoDigitNumberField.
                    throw new IllegalArgumentException();
                }
                mField = field;
                mSize = size;
            }
            public int estimateLength() {
                return 4;
            }

            public void appendTo(StringBuffer buffer, Calendar calendar) {
                appendTo(buffer, calendar.get(mField));
            }

            public final void appendTo(StringBuffer buffer, int value) {
                if (value < 100) {
                    for (int i = mSize; --i >= 2; ) {
                        buffer.append('0');
                    }
                    buffer.append((char)(value / 10 + '0'));
                    buffer.append((char)(value % 10 + '0'));
                } else {
                    int digits;
                    if (value < 1000) {
                        digits = 3;
                    } else {
                        if(value <= -1){
                            throw new IllegalArgumentException("Negative values should not be possible" + value);
                        }
                        digits = Integer.toString(value).length();
                    }
                    for (int i = mSize; --i >= digits; ) {
                        buffer.append('0');
                    }
                    buffer.append(Integer.toString(value));
                }
            }
        }

        //用来输出两位数的内部类
        private static class TwoDigitNumberField implements NumberRule {
            private final int mField;

            TwoDigitNumberField(int field) {
                mField = field;
            }

            public int estimateLength() {
                return 2;
            }

            public void appendTo(StringBuffer buffer, Calendar calendar) {
                appendTo(buffer, calendar.get(mField));
            }

            public final void appendTo(StringBuffer buffer, int value) {
                if (value < 100) {
                    buffer.append((char)(value / 10 + '0'));
                    buffer.append((char)(value % 10 + '0'));
                } else {
                    buffer.append(Integer.toString(value));
                }
            }
        }

        //用来输出两位数字的年份的内部类
        private static class TwoDigitYearField implements NumberRule {
            static final TwoDigitYearField INSTANCE = new TwoDigitYearField();

            TwoDigitYearField() {
                super();
            }

            public int estimateLength() {
                return 2;
            }

            public void appendTo(StringBuffer buffer, Calendar calendar) {
                appendTo(buffer, calendar.get(Calendar.YEAR) % 100);
            }

            public final void appendTo(StringBuffer buffer, int value) {
                buffer.append((char)(value / 10 + '0'));
                buffer.append((char)(value % 10 + '0'));
            }
        }

        //用来输出两位数字的月份的内部类
        private static class TwoDigitMonthField implements NumberRule {
            static final TwoDigitMonthField INSTANCE = new TwoDigitMonthField();

            TwoDigitMonthField() {
                super();
            }

            public int estimateLength() {
                return 2;
            }

            public void appendTo(StringBuffer buffer, Calendar calendar) {
                appendTo(buffer, calendar.get(Calendar.MONTH) + 1);
            }

            public final void appendTo(StringBuffer buffer, int value) {
                buffer.append((char)(value / 10 + '0'));
                buffer.append((char)(value % 10 + '0'));
            }
        }
        //用来输出12小时字段的内部类
        private static class TwelveHourField implements NumberRule {
            private final NumberRule mRule;
            TwelveHourField(NumberRule rule) {
                mRule = rule;
            }

            public int estimateLength() {
                return mRule.estimateLength();
            }
            public void appendTo(StringBuffer buffer, Calendar calendar) {
                int value = calendar.get(Calendar.HOUR);
                if (value == 0) {
                    value = calendar.getLeastMaximum(Calendar.HOUR) + 1;
                }
                mRule.appendTo(buffer, value);
            }
            public void appendTo(StringBuffer buffer, int value) {
                mRule.appendTo(buffer, value);
            }
        }

        //用来输出24小时字段的内部类
        private static class TwentyFourHourField implements NumberRule {
            private final NumberRule mRule;

            TwentyFourHourField(NumberRule rule) {
                mRule = rule;
            }
            public int estimateLength() {
                return mRule.estimateLength();
            }

            public void appendTo(StringBuffer buffer, Calendar calendar) {
                int value = calendar.get(Calendar.HOUR_OF_DAY);
                if (value == 0) {
                    value = calendar.getMaximum(Calendar.HOUR_OF_DAY) + 1;
                }
                mRule.appendTo(buffer, value);
            }
            public void appendTo(StringBuffer buffer, int value) {
                mRule.appendTo(buffer, value);
            }
        }

        //用来输出时区名称的内部类
        private static class TimeZoneNameRule implements Rule {
            private final TimeZone mTimeZone;
            private final boolean mTimeZoneForced;
            private final Locale mLocale;
            private final int mStyle;
            private final String mStandard;
            private final String mDaylight;

            TimeZoneNameRule(TimeZone timeZone, boolean timeZoneForced, Locale locale, int style) {
                mTimeZone = timeZone;
                mTimeZoneForced = timeZoneForced;
                mLocale = locale;
                mStyle = style;

                if (timeZoneForced) {
                    mStandard = getTimeZoneDisplay(timeZone, false, style, locale);
                    mDaylight = getTimeZoneDisplay(timeZone, true, style, locale);
                } else {
                    mStandard = null;
                    mDaylight = null;
                }
            }

            public int estimateLength() {
                if (mTimeZoneForced) {
                    return Math.max(mStandard.length(), mDaylight.length());
                } else if (mStyle == TimeZone.SHORT) {
                    return 4;
                } else {
                    return 40;
                }
            }

            public void appendTo(StringBuffer buffer, Calendar calendar) {
                if (mTimeZoneForced) {
                    if (mTimeZone.useDaylightTime() && calendar.get(Calendar.DST_OFFSET) != 0) {
                        buffer.append(mDaylight);
                    } else {
                        buffer.append(mStandard);
                    }
                } else {
                    TimeZone timeZone = calendar.getTimeZone();
                    if (timeZone.useDaylightTime() && calendar.get(Calendar.DST_OFFSET) != 0) {
                        buffer.append(getTimeZoneDisplay(timeZone, true, mStyle, mLocale));
                    } else {
                        buffer.append(getTimeZoneDisplay(timeZone, false, mStyle, mLocale));
                    }
                }
            }
        }

        //将时区作为数字输出的内部类
        private static class TimeZoneNumberRule implements Rule {
            static final TimeZoneNumberRule INSTANCE_COLON = new TimeZoneNumberRule(true);
            static final TimeZoneNumberRule INSTANCE_NO_COLON = new TimeZoneNumberRule(false);

            final boolean mColon;

            TimeZoneNumberRule(boolean colon) {
                mColon = colon;
            }

            public int estimateLength() {
                return 5;
            }

            public void appendTo(StringBuffer buffer, Calendar calendar) {
                int offset = calendar.get(Calendar.ZONE_OFFSET) + calendar.get(Calendar.DST_OFFSET);

                if (offset < 0) {
                    buffer.append('-');
                    offset = -offset;
                } else {
                    buffer.append('+');
                }

                int hours = offset / (60 * 60 * 1000);
                buffer.append((char)(hours / 10 + '0'));
                buffer.append((char)(hours % 10 + '0'));

                if (mColon) {
                    buffer.append(':');
                }

                int minutes = offset / (60 * 1000) - 60 * hours;
                buffer.append((char)(minutes / 10 + '0'));
                buffer.append((char)(minutes % 10 + '0'));
            }
        }

        //时区名称作为Key值的内部类
        private static class TimeZoneDisplayKey {
            private final TimeZone mTimeZone;
            private final int mStyle;
            private final Locale mLocale;

            TimeZoneDisplayKey(TimeZone timeZone,
                               boolean daylight, int style, Locale locale) {
                mTimeZone = timeZone;
                if (daylight) {
                    style |= 0x80000000;
                }
                mStyle = style;
                mLocale = locale;
            }

            public int hashCode() {
                return mStyle * 31 + mLocale.hashCode();
            }

            public boolean equals(Object obj) {
                if (this == obj) {
                    return true;
                }
                if (obj instanceof TimeZoneDisplayKey) {
                    TimeZoneDisplayKey other = (TimeZoneDisplayKey)obj;
                    return
                            mTimeZone.equals(other.mTimeZone) &&
                                    mStyle == other.mStyle &&
                                    mLocale.equals(other.mLocale);
                }
                return false;
            }
        }

        // 用于创建复合对象的Helper类
        private static class Pair {
            private final Object mObj1;
            private final Object mObj2;

            public Pair(Object obj1, Object obj2) {
                mObj1 = obj1;
                mObj2 = obj2;
            }

            public boolean equals(Object obj) {
                if (this == obj) {
                    return true;
                }

                if (!(obj instanceof Pair)) {
                    return false;
                }

                Pair key = (Pair)obj;

                return
                        (mObj1 == null ?
                                key.mObj1 == null : mObj1.equals(key.mObj1)) &&
                                (mObj2 == null ?
                                        key.mObj2 == null : mObj2.equals(key.mObj2));
            }

            public int hashCode() {
                return (mObj1 == null ? 0 : mObj1.hashCode()) + (mObj2 == null ? 0 : mObj2.hashCode());
            }
            public String toString() {
                return "[" + mObj1 + ':' + mObj2 + ']';
            }
        }
    }
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-10-18 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 简单工具类
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档