高峰出行日收费规则
This commit is contained in:
parent
d1e8cf67cc
commit
b3dd06f1c7
@ -9,6 +9,6 @@ import com.cdzy.orders.model.entity.EbikeOrderDetails;
|
|||||||
* @author attiya
|
* @author attiya
|
||||||
* @since 2025-04-25
|
* @since 2025-04-25
|
||||||
*/
|
*/
|
||||||
public interface EbikeOrderPaymentItemsMapper extends BaseMapper<EbikeOrderDetails> {
|
public interface EbikeOrderDetailsMapper extends BaseMapper<EbikeOrderDetails> {
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
package com.cdzy.orders.model.dto.res;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author attiya
|
||||||
|
* @since 2025-04-27
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class TimeSegment implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
LocalDateTime start;
|
||||||
|
LocalDateTime end;
|
||||||
|
}
|
||||||
@ -2,7 +2,7 @@ package com.cdzy.orders.service.impl;
|
|||||||
|
|
||||||
import com.mybatisflex.spring.service.impl.ServiceImpl;
|
import com.mybatisflex.spring.service.impl.ServiceImpl;
|
||||||
import com.cdzy.orders.model.entity.EbikeOrderDetails;
|
import com.cdzy.orders.model.entity.EbikeOrderDetails;
|
||||||
import com.cdzy.orders.mapper.EbikeOrderPaymentItemsMapper;
|
import com.cdzy.orders.mapper.EbikeOrderDetailsMapper;
|
||||||
import com.cdzy.orders.service.EbikeOrderDetailsService;
|
import com.cdzy.orders.service.EbikeOrderDetailsService;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
@ -13,6 +13,6 @@ import org.springframework.stereotype.Service;
|
|||||||
* @since 2025-04-25
|
* @since 2025-04-25
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
public class EbikeOrderDetailsServiceImpl extends ServiceImpl<EbikeOrderPaymentItemsMapper, EbikeOrderDetails> implements EbikeOrderDetailsService {
|
public class EbikeOrderDetailsServiceImpl extends ServiceImpl<EbikeOrderDetailsMapper, EbikeOrderDetails> implements EbikeOrderDetailsService {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,11 +6,13 @@ import com.cdzy.common.model.JsonResult;
|
|||||||
import com.cdzy.common.model.ResGPSDto;
|
import com.cdzy.common.model.ResGPSDto;
|
||||||
import com.cdzy.orders.component.EbikeCoreHandler;
|
import com.cdzy.orders.component.EbikeCoreHandler;
|
||||||
import com.cdzy.orders.enums.*;
|
import com.cdzy.orders.enums.*;
|
||||||
|
import com.cdzy.orders.mapper.EbikeOrderDetailsMapper;
|
||||||
import com.cdzy.orders.mapper.UserOrdersMapper;
|
import com.cdzy.orders.mapper.UserOrdersMapper;
|
||||||
import com.cdzy.orders.model.dto.req.ReqBikeDto;
|
import com.cdzy.orders.model.dto.req.ReqBikeDto;
|
||||||
import com.cdzy.orders.model.dto.req.ReqOrderDto;
|
import com.cdzy.orders.model.dto.req.ReqOrderDto;
|
||||||
import com.cdzy.orders.model.dto.res.RedisPoint;
|
import com.cdzy.orders.model.dto.res.RedisPoint;
|
||||||
import com.cdzy.orders.model.dto.res.RspBikeDto;
|
import com.cdzy.orders.model.dto.res.RspBikeDto;
|
||||||
|
import com.cdzy.orders.model.dto.res.TimeSegment;
|
||||||
import com.cdzy.orders.model.entity.EbikeOrderDetails;
|
import com.cdzy.orders.model.entity.EbikeOrderDetails;
|
||||||
import com.cdzy.orders.model.entity.EbikeUserOrders;
|
import com.cdzy.orders.model.entity.EbikeUserOrders;
|
||||||
import com.cdzy.orders.service.UserOrdersService;
|
import com.cdzy.orders.service.UserOrdersService;
|
||||||
@ -20,6 +22,8 @@ import com.cdzy.orders.uitls.TimeUtils;
|
|||||||
import com.ebike.feign.clients.MaintenanceFeignClient;
|
import com.ebike.feign.clients.MaintenanceFeignClient;
|
||||||
import com.ebike.feign.clients.OperateFeignClient;
|
import com.ebike.feign.clients.OperateFeignClient;
|
||||||
import com.ebike.feign.model.res.ResFeignEbikeSysRcostsetDto;
|
import com.ebike.feign.model.res.ResFeignEbikeSysRcostsetDto;
|
||||||
|
import com.ebike.feign.model.res.ResFeignEbikeSysRcostsetTimePeriodDto;
|
||||||
|
import com.ebike.feign.model.res.ResFeignEbikeSysRcostsetWeekDto;
|
||||||
import com.ebike.feign.model.res.ResFeignOrderPaymentDto;
|
import com.ebike.feign.model.res.ResFeignOrderPaymentDto;
|
||||||
import com.ebike.feign.model.rsp.FeignEbikeBikeInfoDto;
|
import com.ebike.feign.model.rsp.FeignEbikeBikeInfoDto;
|
||||||
import com.ebike.feign.model.rsp.FeignEbikeEcuInfo;
|
import com.ebike.feign.model.rsp.FeignEbikeEcuInfo;
|
||||||
@ -64,6 +68,9 @@ public class UserOrdersServiceImpl extends ServiceImpl<UserOrdersMapper, EbikeUs
|
|||||||
@Resource
|
@Resource
|
||||||
EbikeCoreHandler ebikeCoreHandler;
|
EbikeCoreHandler ebikeCoreHandler;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
EbikeOrderDetailsMapper orderDetailsMapper;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
public Long saveRide(ReqOrderDto orderDto) {
|
public Long saveRide(ReqOrderDto orderDto) {
|
||||||
@ -370,13 +377,14 @@ public class UserOrdersServiceImpl extends ServiceImpl<UserOrdersMapper, EbikeUs
|
|||||||
//时长费用计算
|
//时长费用计算
|
||||||
Character timeDivisionCharging = feignEbikeSysRcostsetDto.getTimeDivisionCharging();
|
Character timeDivisionCharging = feignEbikeSysRcostsetDto.getTimeDivisionCharging();
|
||||||
BigDecimal decimal = switch (timeDivisionCharging) {
|
BigDecimal decimal = switch (timeDivisionCharging) {
|
||||||
case TIME_SLOT -> timeSlotCostCalculation(list,minutes, userOrders, feignEbikeSysRcostsetDto,userOrders.getOrderId());
|
case TIME_SLOT -> timeSlotCostCalculation(list, minutes, userOrders, feignEbikeSysRcostsetDto);
|
||||||
case WEEK -> weekCostCalculation(list,minutes, userOrders, feignEbikeSysRcostsetDto,userOrders.getOrderId());
|
case WEEK -> weekCostCalculation(list, userOrders, feignEbikeSysRcostsetDto);
|
||||||
default -> defaultCostCalculation(list,minutes, feignEbikeSysRcostsetDto,userOrders.getOrderId());
|
default -> defaultCostCalculation(list, userOrders, feignEbikeSysRcostsetDto, userOrders.getOrderId());
|
||||||
};
|
};
|
||||||
totalAmount = totalAmount.add(decimal);
|
totalAmount = totalAmount.add(decimal);
|
||||||
userOrders.setStatus(OrderStatus.PENDING_PAYMENT);
|
userOrders.setStatus(OrderStatus.PENDING_PAYMENT);
|
||||||
userOrders.setTotalAmount(totalAmount);
|
userOrders.setTotalAmount(totalAmount);
|
||||||
|
orderDetailsMapper.insertBatch(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -387,53 +395,129 @@ public class UserOrdersServiceImpl extends ServiceImpl<UserOrdersMapper, EbikeUs
|
|||||||
* @param feignEbikeSysRcostsetDto 计费规则
|
* @param feignEbikeSysRcostsetDto 计费规则
|
||||||
* @return 计费后总金额
|
* @return 计费后总金额
|
||||||
*/
|
*/
|
||||||
BigDecimal timeSlotCostCalculation(List<EbikeOrderDetails> list, long minutes, EbikeUserOrders userOrders, ResFeignEbikeSysRcostsetDto feignEbikeSysRcostsetDto,long orderId) {
|
BigDecimal timeSlotCostCalculation(List<EbikeOrderDetails> list, long minutes, EbikeUserOrders userOrders, ResFeignEbikeSysRcostsetDto feignEbikeSysRcostsetDto) {
|
||||||
|
List<ResFeignEbikeSysRcostsetTimePeriodDto> ebikeSysRcostsetTimePeriodDtos = feignEbikeSysRcostsetDto.getEbikeSysRcostsetTimePeriodDtos();
|
||||||
|
//TODO:时间是否跨天、划分不同自然时间段,每一段才判断在高峰时间段内有多长时间,并判断是否在高峰时间内起步
|
||||||
return new BigDecimal(0);
|
return new BigDecimal(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 按照时间段计费
|
* 按照时间段计费
|
||||||
*
|
*
|
||||||
* @param minutes (骑行总分钟
|
|
||||||
* @param userOrders 订单信息
|
* @param userOrders 订单信息
|
||||||
* @param feignEbikeSysRcostsetDto 计费规则
|
* @param feignEbikeSysRcostsetDto 计费规则
|
||||||
* @return 计费后总金额
|
* @return 计费后总金额
|
||||||
*/
|
*/
|
||||||
BigDecimal weekCostCalculation(List<EbikeOrderDetails> list, long minutes, EbikeUserOrders userOrders, ResFeignEbikeSysRcostsetDto feignEbikeSysRcostsetDto,long orderId) {
|
BigDecimal weekCostCalculation(List<EbikeOrderDetails> list,EbikeUserOrders userOrders, ResFeignEbikeSysRcostsetDto feignEbikeSysRcostsetDto) {
|
||||||
return new BigDecimal(0);
|
BigDecimal decimal = new BigDecimal(0);
|
||||||
|
LocalDateTime startTime = userOrders.getStartTime();
|
||||||
|
LocalDateTime endTime = userOrders.getEndTime();
|
||||||
|
boolean crossDay = TimeUtils.isCrossDay(startTime, endTime);
|
||||||
|
Long orderId = userOrders.getOrderId();
|
||||||
|
if (!crossDay) {
|
||||||
|
//未跨天
|
||||||
|
TimeSegment timeSegment = new TimeSegment(startTime, endTime);
|
||||||
|
boolean checked = checkWeek(timeSegment, feignEbikeSysRcostsetDto);
|
||||||
|
BigDecimal dailiedFee = dailyFee(timeSegment, feignEbikeSysRcostsetDto, true, checked, list, orderId);
|
||||||
|
decimal = decimal.add(dailiedFee);
|
||||||
|
} else {
|
||||||
|
//跨天
|
||||||
|
List<TimeSegment> timeSegments = TimeUtils.splitByDays(startTime, endTime);
|
||||||
|
for (int i = 0; i < timeSegments.size(); i++) {
|
||||||
|
TimeSegment timeSegment = timeSegments.get(i);
|
||||||
|
boolean checked = checkWeek(timeSegment, feignEbikeSysRcostsetDto);
|
||||||
|
BigDecimal dailiedFee = dailyFee(timeSegment, feignEbikeSysRcostsetDto, i < 1, checked, list, orderId);
|
||||||
|
decimal = decimal.add(dailiedFee);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return decimal;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 按照时间段计费(默认
|
* 根据自然时间段计算高峰出行日费用
|
||||||
*
|
*
|
||||||
* @param minutes (骑行总分钟
|
* @param timeSegment 时间段
|
||||||
* @param feignEbikeSysRcostsetDto 计费规则
|
* @param feignEbikeSysRcostsetDto 计算规则
|
||||||
* @return 计费后总金额
|
* @return 金额
|
||||||
*/
|
*/
|
||||||
BigDecimal defaultCostCalculation(List<EbikeOrderDetails> list, long minutes, ResFeignEbikeSysRcostsetDto feignEbikeSysRcostsetDto,long orderId) {
|
BigDecimal dailyFee(TimeSegment timeSegment, ResFeignEbikeSysRcostsetDto feignEbikeSysRcostsetDto, boolean isStart, boolean isWeek, List<EbikeOrderDetails> list, long orderId) {
|
||||||
BigDecimal decimal = new BigDecimal(0);
|
BigDecimal decimal = new BigDecimal(0);
|
||||||
Integer startupDuration = feignEbikeSysRcostsetDto.getStartupDuration();
|
List<ResFeignEbikeSysRcostsetWeekDto> weekDtos = feignEbikeSysRcostsetDto.getEbikeSysRcostsetWeekDtos();
|
||||||
BigDecimal startupCost = feignEbikeSysRcostsetDto.getStartupCost();
|
LocalDateTime startTime = timeSegment.getStart();
|
||||||
EbikeOrderDetails orderDetails = new EbikeOrderDetails();
|
String weekNumber = TimeUtils.getDayOfWeekNumber(startTime);
|
||||||
orderDetails.setOrderId(orderId);
|
LocalDateTime endTime = timeSegment.getEnd();
|
||||||
orderDetails.setItemAmount(startupCost);
|
long minutes = TimeUtils.betweenMinutes(startTime, endTime);
|
||||||
orderDetails.setItemType(OrderDetailsType.STARTING_FEE);
|
BigDecimal minutesNew = BigDecimal.valueOf(minutes);
|
||||||
orderDetails.setItemName("起步费用");
|
if (isWeek) {
|
||||||
orderDetails.setCalculationRule(JSONObject.toJSONString(feignEbikeSysRcostsetDto));
|
//高峰日出现计算
|
||||||
list.add(orderDetails);
|
for (ResFeignEbikeSysRcostsetWeekDto weekCostCalculation : weekDtos) {
|
||||||
decimal = decimal.add(startupCost);
|
//根据符合要求的规则计算费用
|
||||||
//超出起步时长计费
|
if (weekCostCalculation.getWeek().contains(weekNumber)) {
|
||||||
if (minutes > startupDuration) {
|
if (isStart) {
|
||||||
BigDecimal minutesNew = BigDecimal.valueOf(minutes);
|
EbikeOrderDetails orderDetails = new EbikeOrderDetails();
|
||||||
BigDecimal startupDurationNew = BigDecimal.valueOf(startupDuration);
|
orderDetails.setOrderId(orderId);
|
||||||
//超出时长
|
orderDetails.setItemAmount(weekCostCalculation.getStartupCost());
|
||||||
BigDecimal subtract = minutesNew.subtract(startupDurationNew);
|
orderDetails.setItemType(OrderDetailsType.TRAVEL_EXPENSES_ON_PEAK_DAYS);
|
||||||
|
orderDetails.setItemName("高峰日出行费用-起步费用");
|
||||||
|
orderDetails.setCalculationRule(JSONObject.toJSONString(feignEbikeSysRcostsetDto));
|
||||||
|
list.add(orderDetails);
|
||||||
|
Integer startupDuration = weekCostCalculation.getStartupDuration();
|
||||||
|
if (minutes > startupDuration) {
|
||||||
|
|
||||||
|
BigDecimal startupDurationNew = BigDecimal.valueOf(startupDuration);
|
||||||
|
//超出时长(总时长减去起步时长
|
||||||
|
minutesNew = minutesNew.subtract(startupDurationNew);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//时长计费
|
||||||
|
BigDecimal durationCost = weekCostCalculation.getDurationCost();
|
||||||
|
//时长多久计费一次
|
||||||
|
Integer duration = weekCostCalculation.getDuration();
|
||||||
|
//总计费几次(向上取整
|
||||||
|
int ceil = NumberUtils.divideAndCeil(duration, minutesNew.intValue());
|
||||||
|
BigDecimal ceilCost = BigDecimal.valueOf(ceil);
|
||||||
|
//最终值
|
||||||
|
BigDecimal multiply = durationCost.multiply(ceilCost);
|
||||||
|
|
||||||
|
EbikeOrderDetails durationCostOrderDetails = new EbikeOrderDetails();
|
||||||
|
durationCostOrderDetails.setOrderId(orderId);
|
||||||
|
durationCostOrderDetails.setItemAmount(multiply);
|
||||||
|
durationCostOrderDetails.setItemType(OrderDetailsType.TRAVEL_EXPENSES_ON_PEAK_DAYS);
|
||||||
|
durationCostOrderDetails.setItemName("高峰日出行费用-时长计费");
|
||||||
|
durationCostOrderDetails.setCalculationRule(JSONObject.toJSONString(feignEbikeSysRcostsetDto));
|
||||||
|
list.add(durationCostOrderDetails);
|
||||||
|
decimal = decimal.add(multiply);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
//非高峰出行日计费
|
||||||
|
if (isStart) {
|
||||||
|
//起始计费
|
||||||
|
Integer startupDuration = feignEbikeSysRcostsetDto.getStartupDuration();
|
||||||
|
BigDecimal startupCost = feignEbikeSysRcostsetDto.getStartupCost();
|
||||||
|
EbikeOrderDetails orderDetails = new EbikeOrderDetails();
|
||||||
|
orderDetails.setOrderId(orderId);
|
||||||
|
orderDetails.setItemAmount(startupCost);
|
||||||
|
orderDetails.setItemType(OrderDetailsType.STARTING_FEE);
|
||||||
|
orderDetails.setItemName("起步费用");
|
||||||
|
orderDetails.setCalculationRule(JSONObject.toJSONString(feignEbikeSysRcostsetDto));
|
||||||
|
list.add(orderDetails);
|
||||||
|
decimal = decimal.add(startupCost);
|
||||||
|
//超出起步时长计费
|
||||||
|
if (minutes > startupDuration) {
|
||||||
|
BigDecimal startupDurationNew = BigDecimal.valueOf(startupDuration);
|
||||||
|
//超出时长
|
||||||
|
minutesNew = minutesNew.subtract(startupDurationNew);
|
||||||
|
}
|
||||||
|
}
|
||||||
//时长计费
|
//时长计费
|
||||||
BigDecimal durationCost = feignEbikeSysRcostsetDto.getDurationCost();
|
BigDecimal durationCost = feignEbikeSysRcostsetDto.getDurationCost();
|
||||||
//时长多久计费一次
|
//时长多久计费一次
|
||||||
Integer duration = feignEbikeSysRcostsetDto.getDuration();
|
Integer duration = feignEbikeSysRcostsetDto.getDuration();
|
||||||
//总计费几次(向上取整
|
//总计费几次(向上取整
|
||||||
int ceil = NumberUtils.divideAndCeil(duration, subtract.intValue());
|
int ceil = NumberUtils.divideAndCeil(duration, minutesNew.intValue());
|
||||||
BigDecimal ceilCost = BigDecimal.valueOf(ceil);
|
BigDecimal ceilCost = BigDecimal.valueOf(ceil);
|
||||||
//最终值
|
//最终值
|
||||||
BigDecimal multiply = durationCost.multiply(ceilCost);
|
BigDecimal multiply = durationCost.multiply(ceilCost);
|
||||||
@ -449,4 +533,36 @@ public class UserOrdersServiceImpl extends ServiceImpl<UserOrdersMapper, EbikeUs
|
|||||||
}
|
}
|
||||||
return decimal;
|
return decimal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查是否高峰期
|
||||||
|
*
|
||||||
|
* @param timeSegment 自然时间段
|
||||||
|
* @param feignEbikeSysRcostsetDto 计费规则
|
||||||
|
* @return 是否
|
||||||
|
*/
|
||||||
|
boolean checkWeek(TimeSegment timeSegment, ResFeignEbikeSysRcostsetDto feignEbikeSysRcostsetDto) {
|
||||||
|
List<ResFeignEbikeSysRcostsetWeekDto> weekDtos = feignEbikeSysRcostsetDto.getEbikeSysRcostsetWeekDtos();
|
||||||
|
LocalDateTime startTime = timeSegment.getStart();
|
||||||
|
String weekNumber = TimeUtils.getDayOfWeekNumber(startTime);
|
||||||
|
for (ResFeignEbikeSysRcostsetWeekDto weekCostCalculation : weekDtos) {
|
||||||
|
if (weekCostCalculation.getWeek().contains(weekNumber)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按照时间段计费(默认
|
||||||
|
*
|
||||||
|
* @param userOrders 订单信息
|
||||||
|
* @param feignEbikeSysRcostsetDto 计费规则
|
||||||
|
* @return 计费后总金额
|
||||||
|
*/
|
||||||
|
BigDecimal defaultCostCalculation(List<EbikeOrderDetails> list, EbikeUserOrders userOrders, ResFeignEbikeSysRcostsetDto feignEbikeSysRcostsetDto, long orderId) {
|
||||||
|
TimeSegment timeSegment = new TimeSegment(userOrders.getStartTime(), userOrders.getEndTime());
|
||||||
|
return dailyFee(timeSegment, feignEbikeSysRcostsetDto, true, false, list, orderId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,9 +1,13 @@
|
|||||||
package com.cdzy.orders.uitls;
|
package com.cdzy.orders.uitls;
|
||||||
|
|
||||||
|
import com.cdzy.orders.model.dto.res.TimeSegment;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
import java.time.temporal.ChronoUnit;
|
import java.time.temporal.ChronoUnit;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -72,8 +76,8 @@ public class TimeUtils {
|
|||||||
* 计算两个时间之间的分钟差
|
* 计算两个时间之间的分钟差
|
||||||
*/
|
*/
|
||||||
public static long betweenMinutes(LocalDateTime start, LocalDateTime end) {
|
public static long betweenMinutes(LocalDateTime start, LocalDateTime end) {
|
||||||
Objects.requireNonNull(start, "start time must not be null");
|
Objects.requireNonNull(start, "开始时间不能为空");
|
||||||
Objects.requireNonNull(end, "end time must not be null");
|
Objects.requireNonNull(end, "结束时间不能为空");
|
||||||
return ChronoUnit.MINUTES.between(start, end);
|
return ChronoUnit.MINUTES.between(start, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,4 +136,55 @@ public class TimeUtils {
|
|||||||
Objects.requireNonNull(time, "time must not be null");
|
Objects.requireNonNull(time, "time must not be null");
|
||||||
return time.atZone(zoneId != null ? zoneId : ZoneId.systemDefault());
|
return time.atZone(zoneId != null ? zoneId : ZoneId.systemDefault());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取星期几的数字字符串表示(ISO-8601 标准,周一=1 到 周日=7)
|
||||||
|
* @param dateTime 目标时间
|
||||||
|
* @return 1-7 的整数
|
||||||
|
*/
|
||||||
|
public static String getDayOfWeekNumber(LocalDateTime dateTime) {
|
||||||
|
return String.valueOf(dateTime.getDayOfWeek().getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断两个时间是否跨天
|
||||||
|
* @param time1 时间1
|
||||||
|
* @param time2 时间2
|
||||||
|
* @return true=跨天 | false=未跨天
|
||||||
|
*/
|
||||||
|
public static boolean isCrossDay(LocalDateTime time1, LocalDateTime time2) {
|
||||||
|
return !time1.toLocalDate().equals(time2.toLocalDate());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算两个时间的自然日间隔天数(忽略时间部分)
|
||||||
|
* @param start 开始时间
|
||||||
|
* @param end 结束时间
|
||||||
|
* @return 间隔自然日天数(end >= start 返回正数,反之返回负数)
|
||||||
|
*/
|
||||||
|
public static long daysBetween(LocalDateTime start, LocalDateTime end) {
|
||||||
|
return ChronoUnit.DAYS.between(
|
||||||
|
start.toLocalDate(),
|
||||||
|
end.toLocalDate()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按自然日拆分时间段
|
||||||
|
* @param start 开始时间
|
||||||
|
* @param end 结束时间
|
||||||
|
* @return 时间段列表
|
||||||
|
*/
|
||||||
|
public static List<TimeSegment> splitByDays(LocalDateTime start, LocalDateTime end) {
|
||||||
|
List<TimeSegment> segments = new ArrayList<>();
|
||||||
|
LocalDateTime currentStart = start;
|
||||||
|
while (currentStart.isBefore(end)) {
|
||||||
|
LocalDateTime nextDay = currentStart.plusDays(1).truncatedTo(ChronoUnit.DAYS);
|
||||||
|
LocalDateTime segmentEnd = nextDay.isBefore(end) ? nextDay : end;
|
||||||
|
segments.add(new TimeSegment(currentStart, segmentEnd));
|
||||||
|
currentStart = segmentEnd;
|
||||||
|
}
|
||||||
|
return segments;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user