在项目开发中经常会遇到时间参数,比如开始时间结束时间;但是往往会出现一个问题那就是时间的格式问题,当前后端格式不一致的时候就导致参数无法接收。这就要写一个兼容很多格式的转换器。那有没有更简便的方式呢,例如我们通过间隔来计算开始与结束时间,只要传一个简单的代码码就可以呢。

  • 修饰符
代码(大写) 含义 描述
B before 前N个单位 (不包含当前)
P past 过去N个单位(包含当前)
C current 当前
  • 时间精度
单位 代码 大小写
毫秒 S 大写
s 小写
m 小写
H 大写
d 小写
M 大写
y 小写
W 大写
  • 传值方式

    修饰符和时间精度配合再加上单位间隔数量

描述 表达式
过去2个月 PM2
前7天 Bd7
当年 Cy

时间传参DTO类

import java.util.Date;import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;@Schema(name = "时间区段参数", description = "时间区段参数DTO")
@Getter
@Setter
@Accessors(chain = true)
public class DateSegmentDTO {@Schema(description = "开始时间")private Date start;@Schema(description = "结束时间")private Date end;@Schema(description = "时间区段代码")private String stepCode;
}

时间区间工具类

时间区间是[start,end) 包含开始不包含结束,条件应为 >= start , < end

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;import org.apache.commons.lang3.Validate;
import org.springframework.util.Assert;import com.qjwy.system.dto.DateSegmentDTO;/*** 时间区间工具* * 本工具旨在降低时间区间传参的复杂度,通过三个参数控制开始时间和结束时间的参数* * Date start; Date end; String stepCode;* * * @author:三石* @since:1.0*/
public class DurationUtils {private DurationUtils() {}// 所有修饰和精度的组合private static final List<String> COMBINATION = new ArrayList<String>();static {for (MODIFY_TYPE modifyType : MODIFY_TYPE.values()) {for (DURATION_TYPE durationType : DURATION_TYPE.values()) {COMBINATION.add(modifyType.name() + durationType.name());}}}/*** 注入时间* * @param date    指定的时间* @param segment 时间参数封装*/public static void injectDateTime(Date date, DateSegmentDTO segment) {Date start = segment.getStart();Date end = segment.getEnd();String stepCode = segment.getStepCode();if (start == null && end == null) {Assert.notNull(stepCode, "时间区间参数不能同时为null");String expression = stepCode.substring(0, 2);Assert.isTrue(COMBINATION.contains(expression), "不支持的组合:" + expression + ",目前可支持的组合" + COMBINATION);String[] codes = expression.split("");MODIFY_TYPE modifyType = MODIFY_TYPE.valueOf(codes[0]);DURATION_TYPE durationType = DURATION_TYPE.valueOf(codes[1]);Date[] se = modifyType.getRuleFunction().calc(//date, //durationType.getField(), //stepCode.length() >= 3 ? Integer.parseInt(stepCode.substring(2)) : 0, //durationType.getSmallerFields()//);segment.setStart(se[0]).setEnd(se[1]);}}/*** 时间区间类型*/enum DURATION_TYPE {S("毫秒", Calendar.MILLISECOND, new int[] {}), //s("秒", Calendar.SECOND, new int[] { Calendar.MILLISECOND }), //m("分", Calendar.MINUTE, new int[] { Calendar.MILLISECOND, Calendar.SECOND }), //H("小时", Calendar.HOUR_OF_DAY, new int[] { Calendar.MILLISECOND, Calendar.SECOND, Calendar.MINUTE }), //d("日", Calendar.DAY_OF_MONTH, new int[] { Calendar.MILLISECOND, Calendar.SECOND, Calendar.MINUTE, Calendar.HOUR_OF_DAY }), //M("月", Calendar.MONTH, new int[] { Calendar.MILLISECOND, Calendar.SECOND, Calendar.MINUTE, Calendar.HOUR_OF_DAY, Calendar.DAY_OF_MONTH }), //y("年", Calendar.YEAR, new int[] { Calendar.MILLISECOND, Calendar.SECOND, Calendar.MINUTE, Calendar.HOUR_OF_DAY, Calendar.DAY_OF_MONTH, Calendar.MONTH }), //W("周", Calendar.WEEK_OF_YEAR, new int[] { Calendar.MILLISECOND, Calendar.SECOND, Calendar.MINUTE, Calendar.HOUR_OF_DAY, Calendar.DAY_OF_WEEK });// 精度private String accuracy;// 当前时间域private int field;// 更小的单位的时间域private int[] smallerFields;private DURATION_TYPE(String accuracy, int field, int[] smallerFields) {this.accuracy = accuracy;this.field = field;this.smallerFields = smallerFields;}public String getAccuracy() {return accuracy;}public int getField() {return field;}public int[] getSmallerFields() {return smallerFields;}}/*** 时间区间修饰类型*/enum MODIFY_TYPE {B("before", "前N个,不包含当前", //(date, field, step, smallerunits) -> {Date start = date;Date end = date;start = add(start, field, -step);Calendar instance = Calendar.getInstance();for (int unit : smallerunits) {int minimum = instance.getMinimum(unit);// 设置周一为每周中第一天if (unit == Calendar.DAY_OF_WEEK) {minimum = Calendar.MONDAY;}start = set(start, unit, minimum);end = set(end, unit, minimum);}return new Date[] { start, end };}//), //P("past", "过去N个,包含当前", //(date, field, step, smallerunits) -> {Date start = date;Date end = date;start = add(start, field, -step);return new Date[] { start, end };}//), //C("current", "当前", //(date, field, step, smallerunits) -> {Date start = date;Date end = date;Calendar instance = Calendar.getInstance();for (int unit : smallerunits) {int minimum = instance.getMinimum(unit);// 设置周一为每周中第一天if (unit == Calendar.DAY_OF_WEEK) {minimum = Calendar.MONDAY;}start = set(start, unit, minimum);}return new Date[] { start, end };}//);// 含义private String meaning;// 描述private String desc;// 计算规则private RuleFunction ruleFunction;private MODIFY_TYPE(String meaning, String desc, RuleFunction ruleFunction) {this.meaning = meaning;this.desc = desc;this.ruleFunction = ruleFunction;}public String getMeaning() {return meaning;}public String getDesc() {return desc;}public RuleFunction getRuleFunction() {return ruleFunction;}}/*** 时间规则函数*/@FunctionalInterfaceprivate interface RuleFunction {Date[] calc(Date date, int field, int step, int[] smallerunits);}/*** 验证date不为null* * @param date 时间*/private static void validateDateNotNull(final Date date) {Validate.notNull(date, "date");}/*** 将指定字段设置为返回新对象的日期。使用非宽松解释* * * <p>* 不会改变原来的 {@code Date}* </p>** @param date          日期,不为空* @param calendarField 要添加到其中的日历字段* @param amount        要加的量* @return 新的{@code Date}与添加的时间量* @throws IllegalArgumentException 当date为null时*/private static Date set(final Date date, final int calendarField, final int amount) {validateDateNotNull(date);// getInstance()返回一个新对象,因此这个方法是线程安全的final Calendar c = Calendar.getInstance();// 设置一周的开始为周一c.setFirstDayOfWeek(Calendar.MONDAY);c.setLenient(false);c.setTime(date);c.set(calendarField, amount);return c.getTime();}/*** 新创建一个日期对象,并设定日期* <p>* 不会改变原来的 {@code Date}* </p>* * @param date          日期,不为空* @param calendarField 要添加到其中的日历字段* @param amount        要加的量,可以是负的* @return 新的{@code Date}与添加的时间量* @throws NullPointerException 当date为null时*/private static Date add(final Date date, final int calendarField, final int amount) {validateDateNotNull(date);final Calendar c = Calendar.getInstance();// 设置一周的开始为周一c.setFirstDayOfWeek(Calendar.MONDAY);c.setTime(date);c.add(calendarField, amount);return c.getTime();}
}

测试

 public static void main(String[] args) throws ParseException {DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");Date date = format.parse("2022-07-16 09:30:25 321");DateSegmentDTO dto1 = new DateSegmentDTO().setStepCode("Py1");DurationUtils.injectDateTime(date, dto1);System.out.println("过去1年:Py1");System.out.println(format.format(dto1.getStart()));System.out.println(format.format(dto1.getEnd()));DateSegmentDTO dto2 = new DateSegmentDTO().setStepCode("By2");DurationUtils.injectDateTime(date, dto2);System.out.println("前两年:By2");System.out.println(format.format(dto2.getStart()));System.out.println(format.format(dto2.getEnd()));DateSegmentDTO dto3 = new DateSegmentDTO().setStepCode("Cy");DurationUtils.injectDateTime(date, dto3);System.out.println("当年:Cy");System.out.println(format.format(dto3.getStart()));System.out.println(format.format(dto3.getEnd()));DateSegmentDTO dto4 = new DateSegmentDTO().setStepCode("PW1");DurationUtils.injectDateTime(date, dto4);System.out.println("过去1周:PW1");System.out.println(format.format(dto4.getStart()));System.out.println(format.format(dto4.getEnd()));DateSegmentDTO dto5 = new DateSegmentDTO().setStepCode("Bd7");DurationUtils.injectDateTime(date, dto5);System.out.println("前7天:Bd7");System.out.println(format.format(dto5.getStart()));System.out.println(format.format(dto5.getEnd()));}

测试结果

过去1年:Py1
2021-07-16 09:30:25 321
2022-07-16 09:30:25 321
前两年:By2
2020-01-01 00:00:00 000
2022-01-01 00:00:00 000
当年:Cy
2022-01-01 00:00:00 000
2022-07-16 09:30:25 321
过去1周:PW1
2022-07-09 09:30:25 321
2022-07-16 09:30:25 321
前7天:Bd7
2022-07-09 00:00:00 000
2022-07-16 00:00:00 000

java时间工具类;获取当前,过去N个单位,前N个单位(不包含当前)年月日时分秒毫秒的开始与结束时间相关推荐

  1. java时间格式年月日时分秒_java日期格式(年月日时分秒毫秒)

    java日期格式(年月日时分秒毫秒) 2020-08-13 07:09 阅读数 79 package test.remote.tools.combine; import java.text.Simpl ...

  2. android获取年月日时分秒毫秒,Android获取两个日期其间间隔的天数

    /** * 获取两个日期之间的间隔天数 * @return */ public static int getGapCount(Date startDate, Date endDate) { Calen ...

  3. JAVA 计算年月日时分秒毫秒

    /**计算年月日时分秒毫秒**/ public static String Millisecond(String begins,String ends,String appointmentNo,Str ...

  4. Java时间工具类(获取上个月、获取月份1月1号时间戳、获取月份最后一天时间戳...)

    在开发中我们经常还会用到日期时间,以下是一个日期时间工具类,包含: 获取每月月初时间戳 获取每月15号时间戳 获取每月月末时间戳 获取当前被格式化后的日期 从这些方法中你可以改写出你需要的方法 PS: ...

  5. java获取当前年月日(java获取当前年月日时分秒毫秒)

    java如何获取当前时间 年月日 时分秒 //得到long类型当前时间 long l = System.currentTimeMillis(); //new日期对象 Date date = new D ...

  6. Java获取时间格式(年月日时分秒毫秒)

    Java中描述日期时间调用Date类型,该类型存储有时间的年月日.时分秒信息. Date系统时间是以 1970年0时0分0秒 开始计时. 其中: 需要获取的时间单位 格式 年 YYYY or yyyy ...

  7. android根据毫秒获取时分秒,如何获取年月日时分秒毫秒

    // 获取当前时间 getNowTime: function () { let dateTime let yy = new Date().getFullYear() $("#aa" ...

  8. js获取年月日时分秒星期,并且动态展示时间

    // 格式化时间 年月日 function formatDate(date) {var myyear = date.getFullYear();var mymonth = date.getMonth( ...

  9. 06.01、js之日期获取方法-年月日时分秒毫秒星期

    日期获取方法 获取方法用于获取日期的某个部分(来自日期对象的信息).下面是最常用的方法(以字母顺序排序): 方法 描述 getTime()-毫秒 获取时间(从 1970 年 1 月 1 日至今) ge ...

最新文章

  1. FEAST:快速准确的微生物来源追溯工具
  2. 使用 EclEmma 来显示代码覆盖率
  3. 约瑟夫问题(丢手帕问题)
  4. 【django之权限组件】
  5. SnapGene mac 5.3.1 中文分子生物学可视化工具及教程
  6. boost::signals2模块实现为类定义预析构函数的最小示例的测试程序
  7. 技术转管理的“苦”,我懂......
  8. upload file to server
  9. 【LeetCode】24. Swap Nodes in Pairs
  10. 详解Spring中@Autowire,@Value 注解实现原理
  11. Postman接口测试工具学习笔记(二)Postman进阶实践:获取天气预报实例
  12. procreate 笔刷_插画学习必备:2000款Procreate大师级笔刷,超级强大,免费领取
  13. 台电tbook10s官方固件_【11月1日】台电官方系统固件更新
  14. DrGraph - SVG模块之一:显示与节点选择
  15. Python进行拉勾网数据爬取框架与思路
  16. html修改progress背景色,html5 progress标签如何更改进度条颜色?progress进度条详解...
  17. 【工程实践】jsonlines 读取多行数据
  18. 掌握SQL Monitoring这些特性,SQL优化通通不在话下
  19. 常见的互联网名词 O2O、B2B、C2C等
  20. NB-IoT、eMTC、LoRa三种制式该如何选择?

热门文章

  1. 天空中的鸟类与飞行安全。
  2. html 链接到 appstore,怎么解决无法连接到appstore
  3. H3C路由器配置 L2tp + GRE
  4. mysql explain使用方法
  5. 谈谈计算机图像识别技术之身份证号码识别
  6. 模型参考自适应系统(一):MRAS问题
  7. three games 之 桌球
  8. 平面设计师美工面试试题集锦
  9. Hive的4种导入和3种导出方式
  10. PDO、DAO、ORM之间的区别