
java日期处理工具类
发布日期:2022-02-10 11:36:52
浏览次数:26
分类:技术文章
本文共 14887 字,大约阅读时间需要 49 分钟。
- import java.text.ParseException;
- import java.text.SimpleDateFormat;
- import java.util.Calendar;
- import java.util.Date;
- import java.util.HashMap;
- import java.util.Map;
- /**
- *
- * @author yli
- *
- */
- public class DateUtil {
- /**
- * 分隔符:空格
- */
- public static String SEPARATE_SPACE = " ";
- /**
- * 分隔符:减号即 -
- */
- public static String SEPARATE_SUB = "-";
- /**
- * 分隔符:空串
- */
- public static String SEPARATE_EMPTY = "";
- /**
- * 日期第WW周格式模板
- */
- public static String TEMPLATE_WW = "ww";
- /**
- * current_date
- */
- public static String CURRENT_DATE = "current_date";
- /**
- * min_date
- */
- public static String MIN_DATE = "min_date";
- /**
- * max_date
- */
- public static String MAX_DATE = "max_date";
- /**
- * statis_date
- */
- public static String STATIS_DATE = "statis_date";
- /**
- * statis_table
- */
- public static String STATIS_TABLE = "statis_table";
- /**
- * select_date
- */
- public static String SELECT_DATE = "select_date";
- /**
- * select_month
- */
- public static String SELECT_MONTH = "select_month";
- /**
- * select_preMonth
- */
- public static String SELECT_PREMONTH = "select_preMonth";
- /**
- * statis_month
- */
- public static String STATIS_MONTH = "statis_month";
- /**
- * statis_preMonth
- */
- public static String STATIS_PREMONTH = "statis_preMonth";
- /**
- * select_predate
- */
- public static String SELECT_PREDATE = "select_predate";
- /**
- * statis_predate
- */
- public static String STATIS_PREDATE = "statis_predate";
- /**
- * page_date
- */
- public static String PAGE_DATE = "page_date";
- /**
- * select_date_d
- */
- public static String SELECT_DATE_D = "select_date_d";
- /**
- * select_date_w
- */
- public static String SELECT_DATE_W = "select_date_w";
- /**
- * select_date_m
- */
- public static String SELECT_DATE_M = "select_date_m";
- /**
- * report_mode
- */
- public static String REPORT_MODE = "report_mode";
- /**
- * 天的偏移量
- */
- public static String DAY_OFFSET = "dayOffset";
- /**
- * 月的偏移量
- */
- public static String MONTH_OFFSET = "monthOffset";
- /**
- * 年的偏移量
- */
- public static String YEAR_OFFSET = "yearOffset";
- /**
- * 数据报使用的表名后缀
- *
- */
- public static enum ReportTableEnum {
- D("D"),
- W("W"),
- M("M"),
- D_7("D_7");
- private final String value;
- public String getValue() {
- return this.value;
- }
- ReportTableEnum(String value) {
- this.value = value;
- }
- }
- public static enum DateOffset {
- day_1(1), day_15(15), day_30(30), month_1(1);
- private final int value;
- public int getValue() {
- return this.value;
- }
- DateOffset(int value) {
- this.value = value;
- }
- }
- /**
- * 数据宝使用的日期格式,以下格式Java都支持<br>
- * 并且关于周的计算,和日期控件My97Date一样采用ISO8601定义的算法
- */
- public static enum DateFormatEnum {
- /**
- * 20121208
- */
- yyyyMMdd("yyyyMMdd"),
- /**
- * 2012-12-08
- */
- yyyyMMdd_sub("yyyy-MM-dd"),
- /**
- * 2012年12月08日
- */
- yyyyMMdd_zh_cn("yyyy年MM月dd日"),
- /**
- * 201249
- */
- yyyyww("yyyyww"),
- /**
- * 2012-12-08 第49周
- */
- yyyyMMddww_sub("yyyy-MM-dd 第ww周"),
- /**
- * 2012年12月08日 第49周
- */
- yyyyMMddww_zh_cn("yyyy年MM月dd日 第ww周"),
- /**
- * 201212
- */
- yyyyMM("yyyyMM"),
- /**
- * 2012-12
- */
- yyyyMM_sub("yyyy-MM"),
- /**
- * 2012年12月
- */
- yyyyMM_zh_cn("yyyy年MM月");
- private final String value;
- public String getValue() {
- return value;
- }
- DateFormatEnum(String value) {
- this.value = value;
- }
- }
- /**
- * 报表模式[日/周/月/前7天/前15天/前30天/等等]<br>
- * 初始化为对应的数据库表名后缀:这样在SQL语句中不需要动态判断<br>
- */
- public static enum ReportMode {
- day("d"),
- week("w"),
- month("m"),
- day7("d_7");
- private final String value;
- public String getValue() {
- return value;
- }
- ReportMode(String value) {
- this.value = value;
- }
- }
- public static Map<String, ReportMode> reportModeDict = new HashMap<String, ReportMode>();
- static {
- reportModeDict.put(ReportMode.day.toString(), ReportMode.day);
- reportModeDict.put(ReportMode.week.toString(), ReportMode.week);
- reportModeDict.put(ReportMode.month.toString(), ReportMode.month);
- reportModeDict.put(ReportMode.day7.toString(), ReportMode.day7);
- }
- /**
- * 将用[户选择的日期格式][查询所需的日期格式][页面显示所需的日期格式]定义成字典
- */
- public static Map<ReportMode, DateFormatEnum[]> dateFormatDict = new HashMap<ReportMode, DateFormatEnum[]>();
- /**
- * 完成已知报表模式下字典信息初始化<br>
- * 注意前XX天这种格式数据和日报没有区别
- */
- static {
- dateFormatDict.put(ReportMode.day, new DateFormatEnum[] {
- DateFormatEnum.yyyyMMdd_sub, DateFormatEnum.yyyyMMdd,
- DateFormatEnum.yyyyMMdd_zh_cn });
- dateFormatDict.put(ReportMode.week, new DateFormatEnum[] {
- DateFormatEnum.yyyyMMddww_sub, DateFormatEnum.yyyyww,
- DateFormatEnum.yyyyMMddww_zh_cn });
- dateFormatDict.put(ReportMode.month, new DateFormatEnum[] {
- DateFormatEnum.yyyyMM_sub, DateFormatEnum.yyyyMM,
- DateFormatEnum.yyyyMM_zh_cn });
- dateFormatDict.put(ReportMode.day7, new DateFormatEnum[] {
- DateFormatEnum.yyyyMMdd_sub, DateFormatEnum.yyyyMMdd,
- DateFormatEnum.yyyyMMdd_zh_cn });
- }
- /**
- *
- * 日期格式转换:将日期转换成字符串
- *
- * @param date
- * @param dateFormat
- * @return
- */
- public static String formatDate(Date date, DateFormatEnum dateFormat) {
- SimpleDateFormat simpleFormat = new SimpleDateFormat(
- dateFormat.getValue());
- return simpleFormat.format(date);
- }
- /**
- *
- * 日期格式转换:将字符串转换成日期<br>
- * 如果date和格式dateFormat不匹配,将抛出异常,并返回null
- *
- * @param date
- * @param dateFormat
- * @return
- */
- public static Date formatDate(String date, DateFormatEnum dateFormat) {
- SimpleDateFormat simpleFormat = new SimpleDateFormat(
- dateFormat.getValue());
- Date objectDate = null;
- try {
- objectDate = simpleFormat.parse(date);
- } catch (ParseException e) {
- e.printStackTrace();
- }
- return objectDate;
- }
- // 根据天和年的偏移量计算最小和最大日期
- public static Map<String, Object> getMinMaxDate(int dayOffset,
- int yearOffset) {
- Date date = new Date();
- return getMinMaxDate(date, dayOffset, yearOffset);
- }
- // 根据天和年的偏移量计算最小和最大日期
- public static Map<String, Object> getMinMaxDate(Date date, int dayOffset,
- int yearOffset) {
- Map<String, Object> minmaxMap = new HashMap<String, Object>();
- // 设置日期
- Calendar calendar = Calendar.getInstance();
- calendar.setTime(date);
- // 根据[天]的偏移量,以[date]为基准,计算日期控件所需的最大日期
- calendar.add(Calendar.DAY_OF_MONTH, dayOffset);
- String maxDateString = formatDate(calendar.getTime(),
- DateFormatEnum.yyyyMMdd_sub);
- // 根据[年]的偏移量,以[最大日期]为基准,计算日期控件所需的最小日期
- calendar.add(Calendar.YEAR, yearOffset);
- String minDateString = formatDate(calendar.getTime(),
- DateFormatEnum.yyyyMMdd_sub);
- minmaxMap.put(MIN_DATE, minDateString);
- minmaxMap.put(MAX_DATE, maxDateString);
- return minmaxMap;
- }
- /**
- * 根据用户指定的[报表模式+查询日期]获取查询所需的日期以及数据表名后缀<br>
- * 同时将日历控件在三种报表模式下需要的日期格式,以及页面所需的日期提示文本计算出来<br>
- *
- * @return
- */
- public static Map<String, Object> getStatisDateAndTable(
- Map<String, Object> params) {
- if (null == params.get(REPORT_MODE)) {
- params.put(REPORT_MODE, ReportMode.day.toString());
- }
- Calendar calendar = null;
- // 如果没有指定查询日期,则以当前日期的前一天作为默认日期
- if (null == params.get(SELECT_DATE)) {
- calendar = Calendar.getInstance();
- calendar.add(Calendar.DAY_OF_MONTH, -1);
- params.put(SELECT_DATE,
- formatDate(calendar.getTime(), DateFormatEnum.yyyyMMdd_sub));
- }
- // 查询所需的统计日期
- String statisDate = null;
- // 数据表名后缀
- String statisTable = null;
- // 日历控件[天]日期
- String selectDate_D = null;
- // 日历控件[周]日期
- String selectDate_W = null;
- // 日历控件[月]日期
- String selectDate_M = null;
- // 页面日期提示信息
- String pageDateTip = null;
- // 用户指定的查询日期
- String selectDate = params.get(SELECT_DATE).toString();
- // 用户指定报表模式
- ReportMode reportMode = reportModeDict.get(params.get(REPORT_MODE).toString());
- // 获取各种日期格式
- DateFormatEnum[] dateFormatInfo = dateFormatDict.get(reportMode);
- // 原日期格式
- DateFormatEnum sourceDateFormat = dateFormatInfo[0];
- // 目标日期格式
- DateFormatEnum targetDateFormat = dateFormatInfo[1];
- // 页面日期格式
- DateFormatEnum pageDateFormat = dateFormatInfo[2];
- // 报表模式的值即为表名后缀
- statisTable = reportMode.getValue().toUpperCase();
- // 用户选择的日期:将字符转成Date
- Date sourceDate = formatDate(selectDate, sourceDateFormat);
- // 获取数据库所需统计日期格式
- statisDate = formatDate(sourceDate, targetDateFormat);
- // 获取页面日期提示所需日期格式
- pageDateTip = formatDate(sourceDate, pageDateFormat);
- // 获取日历控件在三种报表模式下各自需要的值
- if (ReportMode.month.equals(reportMode)) {
- // 只有月报的日期无法转换成日报或周报
- calendar = Calendar.getInstance();
- calendar.add(Calendar.DAY_OF_MONTH, -1);
- sourceDate = calendar.getTime();
- }
- selectDate_D = formatDate(sourceDate, DateFormatEnum.yyyyMMdd_sub);
- selectDate_W = formatDate(sourceDate, DateFormatEnum.yyyyMMddww_sub);
- selectDate_M = formatDate(sourceDate, DateFormatEnum.yyyyMM_sub);
- params.put(STATIS_DATE, statisDate);
- params.put(STATIS_TABLE, statisTable);
- params.put(PAGE_DATE, pageDateTip);
- params.put(SELECT_DATE_D, selectDate_D);
- params.put(SELECT_DATE_W, selectDate_W);
- params.put(SELECT_DATE_M, selectDate_M);
- return params;
- }
- /**
- * 根据用户选择的日期获取相邻两个月日期数据<br>
- * 并将日期转换成查询所需的格式
- *
- * @param params
- * @return
- */
- public static Map<String, Object> getLinkedTwoMonth(
- Map<String, Object> params) {
- String statis_Date = null;
- String statis_preDate = null;
- String select_Date = null;
- String select_preDate = null;
- Calendar calendar = null;
- // 如果月份数据为空,则以当前日期的前一天作为用户选择的月份数据
- if (null == params.get(SELECT_DATE)) {
- calendar = Calendar.getInstance();
- calendar.add(Calendar.DAY_OF_MONTH, -1);
- params.put(SELECT_DATE,
- formatDate(calendar.getTime(), DateFormatEnum.yyyyMM_sub));
- }
- // 根据用户选择的月份计算上一个月份日期
- select_Date = params.get(SELECT_DATE).toString();
- Date currDate = formatDate(select_Date, DateFormatEnum.yyyyMM_sub);
- statis_Date = formatDate(currDate, DateFormatEnum.yyyyMM);
- calendar = Calendar.getInstance();
- calendar.setTime(currDate);
- calendar.add(Calendar.MONTH, -1);
- statis_preDate = formatDate(calendar.getTime(), DateFormatEnum.yyyyMM);
- select_preDate = formatDate(calendar.getTime(),
- DateFormatEnum.yyyyMM_sub);
- params.put(SELECT_PREDATE, select_preDate);
- params.put(STATIS_DATE, statis_Date);
- params.put(STATIS_PREDATE, statis_preDate);
- return params;
- }
- /**
- * 将用户指定的查询开始于截至日期转换成查询所需的格式<br>
- * 如果查询截至日期为空,则取当前日期前一天作为默认截至日期
- *
- * @param params
- * @return
- */
- public static Map<String, Object> getLinkedTwoDate(
- Map<String, Object> params) {
- String statis_Date = null;
- String statis_preDate = null;
- String select_Date = null;
- String select_preDate = null;
- // 如果查询的开始于截至日期为空,则默认取当前的前1天作为截至日期
- if (null == params.get(SELECT_DATE)
- || null == params.get(SELECT_PREDATE)) {
- Calendar calendar = Calendar.getInstance();
- calendar.add(Calendar.DAY_OF_MONTH, -1);
- params.put(SELECT_DATE,
- formatDate(calendar.getTime(), DateFormatEnum.yyyyMMdd_sub));
- // 如果偏移量为空,则默认为15天
- int dayOffset = null == params.get(DAY_OFFSET) ? DateOffset.day_15
- .getValue() : Integer.parseInt(params.get(DAY_OFFSET)
- .toString());
- calendar.add(Calendar.DAY_OF_MONTH, -dayOffset);
- params.put(SELECT_PREDATE,
- formatDate(calendar.getTime(), DateFormatEnum.yyyyMMdd_sub));
- }
- // 将开始于截至日期格式转换成查询所需的格式
- select_Date = params.get(SELECT_DATE).toString();
- Date currDate = formatDate(select_Date, DateFormatEnum.yyyyMMdd_sub);
- statis_Date = formatDate(currDate, DateFormatEnum.yyyyMMdd);
- select_preDate = params.get(SELECT_PREDATE).toString();
- currDate = formatDate(select_preDate, DateFormatEnum.yyyyMMdd_sub);
- statis_preDate = formatDate(currDate, DateFormatEnum.yyyyMMdd);
- params.put(STATIS_DATE, statis_Date);
- params.put(STATIS_PREDATE, statis_preDate);
- return params;
- }
- /**
- * 检查用户指定的查询时间是否有效<br>
- * 用户指定的查询时间只能在系统允许的最大时间和最小时间范围内
- *
- * @param params
- * @return
- */
- public static boolean isEffectiveDate(Map<String, Object> params) {
- if (null == params.get(STATIS_DATE) || null == params.get(MAX_DATE)
- || null == params.get(MIN_DATE)) {
- return false;
- }
- ReportMode reportMode = ReportMode.day;
- if(null != params.get(REPORT_MODE)) {
- reportMode = reportModeDict.get(params.get(REPORT_MODE).toString());
- }
- // [日/周/月/前X天]的报表统一检查日期是否符合要求
- // 也包含只查询月报,且查询相邻两个月的数据,主要针对会员规模分析这种情况
- String statisDateStr = params.get(STATIS_DATE).toString();
- String maxDateStr = params.get(MAX_DATE).toString().replace(SEPARATE_SUB, SEPARATE_EMPTY);
- String minDateStr = params.get(MIN_DATE).toString().replace(SEPARATE_SUB, SEPARATE_EMPTY);
- if(ReportMode.month.equals(reportMode)) {
- statisDateStr += minDateStr.substring(6); // 将最小日期最后的天数加到用户选择的月份数据上
- } else if(ReportMode.week.equals(reportMode)){
- statisDateStr = params.get(SELECT_DATE_D).toString().replace(SEPARATE_SUB, SEPARATE_EMPTY);
- }
- int statisDate = Integer.parseInt(statisDateStr);
- int maxDate = Integer.parseInt(maxDateStr);
- int minDate = Integer.parseInt(minDateStr);
- if(statisDate < minDate || statisDate > maxDate) {
- return false;
- }
- // 处理以天为查询维度,且查询时间包含开始与截至时间的情况
- // 主要针对流量路径统计这种跨度只能限定在15天的报表
- if(null != params.get(STATIS_PREDATE) && !ReportMode.month.equals(reportMode)) {
- String statisPreDateStr = params.get(STATIS_PREDATE).toString();
- int statisPreDate = Integer.parseInt(statisPreDateStr);
- // 查询开始日期不能大于截至日期
- if(statisPreDate > statisDate) {
- return false;
- }
- // 比较查询开始于截至日期之间跨度是否有效
- int dayOffset = null == params.get(DAY_OFFSET) ? DateOffset.day_15.getValue()
- : Integer.parseInt(params.get(DAY_OFFSET).toString());
- Date statisDateObj = formatDate(statisDateStr, DateFormatEnum.yyyyMMdd);
- Calendar calendar = Calendar.getInstance();
- calendar.setTime(statisDateObj);
- calendar.add(Calendar.DAY_OF_MONTH, -dayOffset);
- String legalPreDateStr = formatDate(calendar.getTime(), DateFormatEnum.yyyyMMdd);
- int legalPreDate = Integer.parseInt(legalPreDateStr);
- // 如果查询的开始日期小于有效的日期则不合法
- if(statisPreDate < legalPreDate) {
- return false;
- }
- }
- return true;
- }
- public static void main(String[] args) {
- /****** 根据偏移量计算最小最大日期 ***********/
- // 指定日期
- // Calendar cal = Calendar.getInstance();
- // cal.set(2010, 9, 18); // 2010-10-18 注意月份
- // System.out.println(getMinMaxDate(cal.getTime(), -1, -2));
- // 不指定日期,则默认取当前日期
- Map<String, Object> minMaxMap = getMinMaxDate(-1, -1);
- System.out.println(minMaxMap);
- /****************************/
- /********** 根据用户指定的[查询日期]和[报表模式]计算SQL所需的统计日期 *************/
- Map<String, Object> params = new HashMap<String, Object>();
- params.putAll(minMaxMap);
- params.put(REPORT_MODE, ReportMode.week.toString());
- params.put(SELECT_DATE, "2012-04-06 第14周");
- getStatisDateAndTable(params);
- System.out.println(params);
- // 日期是否合法
- System.out.println(isEffectiveDate(params));
- params.put(REPORT_MODE, ReportMode.month.toString());
- params.put(SELECT_DATE, "2012-03");
- getStatisDateAndTable(params);
- System.out.println(params);
- // 日期是否合法
- System.out.println(isEffectiveDate(params));
- params.put(REPORT_MODE, ReportMode.day.toString());
- params.put(SELECT_DATE, "2013-04-06");
- getStatisDateAndTable(params);
- System.out.println(params);
- // 日期是否合法
- System.out.println(isEffectiveDate(params));
- params.put(REPORT_MODE, ReportMode.day7.toString());
- params.put(SELECT_DATE, "2013-04-05");
- getStatisDateAndTable(params);
- System.out.println(params);
- // 日期是否合法
- System.out.println(isEffectiveDate(params));
- // 不指定日期则取当前日期前一天作为统计日期
- params.remove(REPORT_MODE);
- params.remove(SELECT_DATE);
- getStatisDateAndTable(params);
- System.out.println(params);
- // 日期是否合法
- System.out.println(isEffectiveDate(params));
- // 对于只有月报,且是查询相邻两个月的数据
- // 只需要计算两个月份日期即可
- Map<String, Object> params1 = new HashMap<String, Object>();
- params1.putAll(minMaxMap);
- params1.put(REPORT_MODE, ReportMode.month.toString());
- params1.put(SELECT_DATE, "2013-04");
- getLinkedTwoMonth(params1);
- System.out.println(params1);
- // 日期是否合法
- System.out.println(isEffectiveDate(params1));
- // 对于只有日报,且是查询相邻不超过15天的数据
- Map<String, Object> params2 = new HashMap<String, Object>();
- params2.putAll(minMaxMap);
- params2.put(SELECT_DATE, "2013-01-28");
- params2.put(SELECT_PREDATE, "2013-01-22");
- getLinkedTwoDate(params2);
- System.out.println(params2);
- // 日期是否合法
- System.out.println(isEffectiveDate(params2));
- }
- }
转载地址:https://blog.csdn.net/courage89/article/details/8888724 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
留言是一种美德,欢迎回访!
[***.207.175.100]2023年05月17日 11时29分49秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
最新文章
「译」通过Fragment处理配置变化
2019-09-06 22:50:45
Android M Dialer完全总结
2019-09-06 22:50:45
「译」Fragment事务与Activity状态丢失
2019-09-06 22:50:44
「深入Java」Generics泛型
2019-09-06 22:50:44
「译」Android文本测量
2019-09-06 22:50:43
「深入Java」Annotation注解
2019-09-06 22:50:43
Handler官方范例AsyncQueryHandler源码解析
2019-09-06 22:50:42
「打造自己的Library」SharedPreferences篇
2019-09-06 22:50:41
光速上手Shell——简单批量文件操作为例
2019-09-06 22:50:41
「深入Java」类型信息:RTTI和反射
2019-09-06 22:50:40
「技术亦人生」端泽的Android学习百宝箱
2019-09-06 22:50:40
「译」Android最佳实践指南——GitHub Star 7000+
2019-09-06 22:50:39
网卡配置释义
2019-09-06 22:50:38
Linux系统显示中文乱码和系统菜单乱码解法
2019-09-06 22:50:38
win7发送wifi热点的技巧
2019-09-06 22:50:37
windows server系统用户与用户组管理
2019-09-06 22:50:37
win7出现任务栏不见了,各个进程莫名被终止解决办法
2019-09-06 22:50:36
win7无法睡眠解决办法之一
2019-09-06 22:50:36
Tomcat连接不上数据库原因之一
2019-09-06 22:50:35
Ubuntu 12.04如何使用root登录?
2019-09-06 22:50:35