SpringBoot系列(二十)日期金额通用处理方法

金额处理方法 BigDecimal

1.1、判断金额是否相等

package com.fcors.fcors;

import org.junit.Test;

import java.math.BigDecimal;

public class DecimalTest {
    @Test
    public void DecimalDemo(){

        BigDecimal num1 = new BigDecimal("6");

        BigDecimal num2 = new BigDecimal("2");

        int IsEqual = num1.compareTo(num2);
        /* 返回值:大于小于等于0 */
        System.out.println(IsEqual);
    }
}

1.2 BigDecimal相减

package com.fcors.fcors;

import org.junit.Test;

import java.math.BigDecimal;

public class DecimalTest {
    @Test
    public void DecimalDemo(){

        BigDecimal num1 = new BigDecimal("6");

        BigDecimal num2 = new BigDecimal("2");

        BigDecimal b = num2.subtract(num1);
        /*输出为-4*/
        System.out.println(b);
    }
}

1.3、折扣的计算

折扣的公式:金额=原价*折扣,在实际的业务当中,金额是保留两位小数点的,如何处理取舍问题呢?

常用的取舍方式:

  • ROUND_UP:向上取整
  • ROUND_DOWN: 向下取整
  • ROUND_HALF_EVEN:银行家算法(IEEEE) :四舍六入五考虑,五后非空就进一,五后为空看奇偶,五前为偶应舍取,五前为奇要进一

在core下创建一个package,并命名为money

首先创建 IMoneyDisscount 接口

package com.lin.missyou.core.money;

import java.math.BigDecimal;

public interface IMoneyDiscount {
    BigDecimal discount(BigDecimal original, BigDecimal discount);
}

创建向上取整实现类HalfUpRound

package com.lin.missyou.core.money;

import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.math.RoundingMode;

//@Component
public class HalfUpRound implements IMoneyDiscount {
    @Override
    public BigDecimal discount(BigDecimal original, BigDecimal discount) {
        BigDecimal actualMoney = original.multiply(discount);
        BigDecimal finalMoney = actualMoney.setScale(2, RoundingMode.HALF_UP);
        return finalMoney;
    }
}

创建HalfEvenRound实现类

package com.lin.missyou.core.money;

import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.math.RoundingMode;

//@Component
public class HalfEvenRound implements IMoneyDiscount {
    @Override
    public BigDecimal discount(BigDecimal original, BigDecimal discount) {
        BigDecimal actualMoney = original.multiply(discount);
        BigDecimal finalMoney = actualMoney.setScale(2, RoundingMode.HALF_EVEN);
        return finalMoney;
    }
}

注意:当接口被多个类实现又加入容器IOC容器时,会报错。如何解决呢?可参考之前的教程。@Configuration或者加入@Primary等

扩展学习:关于DTO和Stream的妙用

首先创建OrderDTO和SkuInfoDTO

OrderDTO

@Getter
@Setter
public class OrderDTO {

    @DecimalMin(value="0.00", message = "不在合法范围内" )
    @DecimalMax(value="99999999.99", message = "不在合法范围内")
    private BigDecimal totalPrice;

    private BigDecimal finalTotalPrice;

    private Long couponId;

    private List<SkuInfoDTO> skuInfoList;

    private OrderAddressDTO address;
}

SkuInfoDTO

@Setter
@Getter
public class SkuInfoDTO {
    private Long id;
    private Integer count;
}

根据两个DTO的关系,Order中的skuInfoList是一个数组型,如何通过Stream把该Order对应的SkuId提取出来呢?

List<Long> skuIdList = orderDTO.getSkuInfoList()
                .stream()
                .map(SkuInfoDTO::getId)
                .collect(Collectors.toList());

日期处理Calendar

public static void main(String[] args) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
        System.out.println("当前时间是:" + sdf.format(new Date()));
        Calendar ca = Calendar.getInstance();
        System.out.println("当前年份:" + ca.get(Calendar.YEAR));
        System.out.println("当前月:" + ca.get(Calendar.MONTH));// 初始月份是从0开始,所以输出值比是几月份小1
        System.out.println("当前日期:" + ca.get(Calendar.DATE));
        System.out.println("当前年份第几个星期:" + ca.get(Calendar.WEEK_OF_YEAR));
        System.out.println("当前月份第几个星期:" + ca.get(Calendar.WEEK_OF_MONTH));
        System.out.println("当前年份第几天:" + ca.get(Calendar.DAY_OF_YEAR));
        System.out.println("当前月份第几天:" + ca.get(Calendar.DAY_OF_MONTH));
        System.out.println("当前星期第几天:" + ca.get(Calendar.DAY_OF_WEEK));
        System.out.println("当前月份第几个星期:" + ca.get(Calendar.DAY_OF_WEEK_IN_MONTH));
        System.out.println("当天第几个小时:" + ca.get(Calendar.HOUR_OF_DAY));
        System.out.println("当前小时第几分钟:" + ca.get(Calendar.MINUTE));
        System.out.println("当前分钟第几秒:" + ca.get(Calendar.SECOND));
        System.out.println("当前秒数第几毫秒:" + ca.get(Calendar.MILLISECOND));
    }

时间判断

public static Boolean isInTimeLine(Date date, Date start, Date end) {
        Long time = date.getTime();
        Long startTime = start.getTime();
        Long endTime = end.getTime();
        if (time > startTime && time < endTime) {
            return true;
        }
        return false;
    }

    //period 单位:秒
    public static Boolean isOutOfDate(Date startTime, Long period) {
        Long now = Calendar.getInstance().getTimeInMillis();
        Long startTimeStamp = startTime.getTime();
        Long periodMillSecond = period * 1000;
        if (now > (startTimeStamp + periodMillSecond)) {
            return true;
        }
        return false;
    }

    public static Boolean isOutOfDate(Date expiredTime) {
        Long now = Calendar.getInstance().getTimeInMillis();
        Long expiredTimeStamp = expiredTime.getTime();
        if(now > expiredTimeStamp){
            return true;
        }
        return false;
    }