记一次calendar二月份的坑

本文探讨了在Java中使用Calendar类处理特定日期范围时遇到的二月日期处理问题,尤其是在涉及二月份的边界条件时。通过实例展示了当开始和结束日期设定在二月时,由于Calendar内部的日期调整机制,可能导致预期外的结果。文章提供了详细的代码示例及解决方案,确保在处理日期范围时能够准确覆盖所有月份。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

记一次calendar二月份的坑

需求是这样的:页面上传一个开始期间,一个结束期间,我需要根据开始和结束期间去数据库取数,又不想用大于等于和小于等于期间取数,因为需要使用函数对日期类型做转换,可能对性能会有影响,所以就计算出一共有哪些期间。例如:
strartPeriod=2020-01, endPeriod=2020-05
查询应该得到的结果是[2020-01,2020-02,2020-03,2020-04,2020-05]

代码实现如下:

 private static List<String> getTerm(VATStatisticsSearchRequest reportSearchRequest) {
    String startPeriod = reportSearchRequest.getStartPeriod();
    String[] startYM = startPeriod.split("-");
    String endPeriod = reportSearchRequest.getEndPeriod();
    String[] endYM = endPeriod.split("-");
    Calendar calendar = Calendar.getInstance();
    calendar.set(Calendar.YEAR, Integer.parseInt(startYM[0]));
    // 查看Calendar.MONTH的注释可知,1月份是0,所以月份需要-1设置才是正确的
    calendar.set(Calendar.MONTH, Integer.parseInt(startYM[1]) - 1);
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM");
    List<String> terms = new ArrayList<>();
    while (calendar.get(Calendar.YEAR) == Integer.parseInt(endYM[0])
        && calendar.get(Calendar.MONTH) <= Integer.parseInt(endYM[1]) - 1) {
      String timeStr = simpleDateFormat.format(calendar.getTime());
      terms.add(timeStr);
      calendar.add(Calendar.MONTH, 1);
    }
    return terms;
  }

写main方法测试结果也是正确的,唯独startPeriod=2020-02,endePeriod=2020-02就有问题了,输出的list为空集合。
起初很是费解,其它任何一个月份都没问题,就只有2月份有问题,并且任何一年的二月份都有问题,这就很奇怪了,并且这个代码已经运行过一段时间,也没出现过这种情况。后来网上查了一下原话是这样的:
比如你选择的时间是2019年1月31日,然后这个时候你对month进行修改改为2月你会发现你得到的month值是3月份,原因是2月份没有31天然后calendar会将时间是自动换算成3月份。
一看今天日期果然到了月底,这个方法中没有对日期的设置,而Calendar.getInstance()正好会获取当前的时间,日期没有设置的话就会拿当前日期,所以就会出现2月份打印不出来的情况。奇怪的现象终于解释通了。长叹一口气~~~

后边经过改造后的代码如下(设置了当前日期为1号):

private static List<String> getTerm(VATStatisticsSearchRequest reportSearchRequest) {
    String startPeriod = reportSearchRequest.getStartPeriod();
    String[] startYM = startPeriod.split("-");
    String endPeriod = reportSearchRequest.getEndPeriod();
    String[] endYM = endPeriod.split("-");
    Calendar calendar = Calendar.getInstance();
    calendar.set(Calendar.YEAR, Integer.parseInt(startYM[0]));
    calendar.set(Calendar.MONTH, Integer.parseInt(startYM[1]) - 1);
    calendar.set(Calendar.DAY_OF_MONTH, 1);
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM");
    List<String> terms = new ArrayList<>();
    while (calendar.get(Calendar.YEAR) == Integer.parseInt(endYM[0])
        && calendar.get(Calendar.MONTH) <= Integer.parseInt(endYM[1]) - 1) {
      String timeStr = simpleDateFormat.format(calendar.getTime());
      terms.add(timeStr);
      calendar.add(Calendar.MONTH, 1);
    }
    return terms;
  }

就不会出现离奇的"二月红"了 !

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值