Java T+1计算工具类

该博客介绍了一个通过@ConfigurationProperties实现的T+1日期计算工具类,该类从配置文件读取节假日和工作日,进行日期处理。在处理过程中遇到Calendar对象日期错乱的问题,采用long类型存储日期并利用stream进行处理。测试案例展示了类的正确使用。
摘要由CSDN通过智能技术生成

T+1日期计算。通过@ConfigurationProperties方式实现

前言:示例代码为T+1日期计算工具类,通过读取写入配置文件的节假日日期实时计算T+1日期;

TradingDayProperties.java

@ConfigurationProperties(prefix = "account.constant.trading")
public class TradingDayProperties {

    private String holidays;

    private String workdays;
}

TradingDayConfig.java

@Configuration
@EnableConfigurationProperties(TradingDayProperties.class)
public class TradingDayConfig {

    @Bean
    public TradingDayProperties tradingDayProperties(){
        log.info("初始化tradingDayProperties");
        return new TradingDayProperties();
    }
    @Bean(value = "tradingDayUtil",initMethod = "init")
    public TradingDayUtil getTradingDayUtils(){
        log.info("初始化tradingDayUtil");
        TradingDayUtil tradingDayUtil = new TradingDayUtil();
        tradingDayUtil.setParam(tradingDayProperties());
        return tradingDayUtil;
    }
}

TradingDayUtil.java

// @Todo 使用Calendar会出现日期错乱问题,错误发生类:java.util.GregorianCalendar 一旦调用到getTimeInMillis()函数时会发生触发updateTime()函数修改日期,未查明原应
@Data
@Slf4j
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class TradingDayUtil {
private TradingDayProperties param;

//    private List<Calendar[]> holidayArray = new ArrayList<>();
//
//    private List<Calendar[]> workdayArray = new ArrayList<>();

    private List<long[]> holidayArray = new ArrayList<>();

    private List<long[]> workdayArray = new ArrayList<>();
    private int[] a = {1, 7}; // 六日

    private SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");

    public void init(){
        try{
            String[] dayArray = param.getHolidays().split(",");
            for(String item: dayArray){
//                Calendar[] dateArray;
                long[] dateArray;
                String[] split = item.split("-");
                Long calendar = stringToCalendar(split[0]);
                calendar -= 24 * 60 * 1000;
//                dateArray = new Calendar[]{calendar, stringToCalendar(split[split.length - 1])};
                dateArray = new long[]{calendar,stringToCalendar(split[split.length - 1])};
                holidayArray.add(dateArray);
            }
            String[] workDayArray = param.getWorkdays().split(",");
            for (String item: workDayArray){
//                Calendar[] dateArray;
                long[] dateArray;
                String[] split = item.split("-");
                Long calendar = stringToCalendar(split[0]);
//                dateArray = new Calendar[]{stringToCalendar(split[0]), stringToCalendar(split[split.length - 1])};
                dateArray = new long[]{stringToCalendar(split[0]), stringToCalendar(split[split.length - 1])};
                workdayArray.add(dateArray);
            }
            log.info("节假日参数处理完成");
        }catch (Exception e){
            log.error("节假日参数处理异常",e);
        }
    }

    public Date getT1(){
        return getT1(new Date());
    }

    /**
     * 计算T+1
     * @param tradingDay
     * @return T+1日期
     */
    public Date getT1(Date tradingDay){
        log.info("T+1日期计算参数:{}", tradingDay);
        Calendar instance = Calendar.getInstance();
        instance.clear();
        instance.setTime(tradingDay);
        instance.set(Calendar.HOUR_OF_DAY, 0);
        instance.set(Calendar.MINUTE, 0);
        instance.set(Calendar.SECOND, 0);
        instance.set(Calendar.MILLISECOND,0);

        Calendar t1 = Calendar.getInstance();
//        Optional<Calendar[]> first = holidayArray.stream().filter(item -> item[0].getTimeInMillis() <= instance.getTimeInMillis() && item[1].getTimeInMillis() > instance.getTimeInMillis()).findFirst();
        Optional<long[]> first = holidayArray.stream().filter(item ->  (item[0] < instance.getTimeInMillis() && item[1] > instance.getTimeInMillis()) || (item[0] == instance.getTimeInMillis() || item[1] == instance.getTimeInMillis())).findFirst();
        // 交易日期发生在节假日或节假日前一天, T+1 日期为节假日结束后一天
        if (first.isPresent()){
//            Date time = first.get()[1].getTime();
            Date time = new Date(first.get()[1]);
            t1.setTime(time);
            t1.add(Calendar.DAY_OF_MONTH, 1);
        }else{
            // 交易日第二天如果在周六日且不为加班日则下周一才是T+1
            t1 = instance;
            t1.add(Calendar.DAY_OF_YEAR, 1);
            int weekDay = t1.get(Calendar.DAY_OF_WEEK);
            if (!isInWorkdays(t1.getTimeInMillis()) && ArrayUtils.contains(a, weekDay)) {
                t1.add(Calendar.DAY_OF_MONTH,weekDay == 1 ? 1 : 9 - weekDay);
            }
        }
        log.info("T+1日期计算结果:{}", t1.getTime());
        return t1.getTime();
    }

    /**
     * 判断是否加班日
     * @param calendar
     * @return
     */
    private boolean isInWorkdays(long calendar){
//        Optional<Calendar[]> first = workdayArray.stream().filter(item -> !calendar.before(item[0]) && !item[1].after(calendar)).findFirst();
        Optional<long[]> first = workdayArray.stream().filter(item -> item[0]  == calendar).findFirst();
        return first.isPresent();
    }

    /**
     * 字符串转时间戳
     * @param date  yyyyMMdd
     * @return long 时间戳
     */
    private long stringToCalendar(String date)  {
        Calendar instance = Calendar.getInstance();
        instance.clear();
        instance.set(Integer.parseInt(date.substring(0,4)),Integer.parseInt(date.substring(4,6)) - 1,Integer.parseInt(date.substring(6,8)), 0, 0, 0);
        return instance.getTimeInMillis();
    }

}

bootstrap.yml

account:
  constant:
    trading:
      holidays: 20210731-20210930,
      workdays: 20210727

使用

@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
@Slf4j
public class TradingTest {

    @Autowired
    private TradingDayUtil tradingDayUtil;

    @Test
    public void test1(){
        Calendar instance = Calendar.getInstance();
        instance.set(Calendar.DAY_OF_MONTH, 23);
        log.info("" + tradingDayUtil.getT1(instance.getTime()));
    }
}

启动测试

2021-07-21 14:22:34.872  INFO: 初始化tradingDayUtil
2021-07-21 14:22:34.873  INFO: 初始化tradingDayProperties
2021-07-21 14:22:34.878  INFO: 节假日参数处理完成
2021-07-21 14:22:41.726  INFO: Mon Jul 26 00:00:00 GMT+08:00 2021

注解说明

@EnableConfigurationProperties:启用对{@ConfigurationProperties}注释bean的支持。

@ConfigurationProperties:外部化配置的注释。 将其添加到类定义或  

{ @Configuration}类中的{@Bean}方法

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值