Java工具集-日期(DateUtils)

  • 2019 年 10 月 28 日
  • 筆記

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

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

简单工具类

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

介绍

遵从两大原则

  • 1.绝不依赖JDK以外的源码
  • 2.牺牲代码复用性,每个类都必须是单独的组件,绝不互相引用,做到完全解耦
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 + ']';              }          }      }  }
Exit mobile version