

- /**
- * 根据ProductSpec和date查询
- * 查询条件: 地区,ProductSpec,date
- * @param renduiPriceDailyDTO
- * @return
- */
- @PostMapping(value = "/daily/getByProductSpecAndDate")
- public Result> getByProductSpecAndDate(@RequestBody RenduiPriceDailyDTO renduiPriceDailyDTO){
- if(StringUtils.isBlank(renduiPriceDailyDTO.getSiteId())){
- return Result.error("地区不能为空!");
- }
- if(StringUtils.isBlank(renduiPriceDailyDTO.getProductSpec())){
- return Result.error("productSpec不能为空!");
- }
- if(renduiPriceDailyDTO.getDate() == null){
- return Result.error("日期不能为空,日期格式为:yyyy-MM-dd!");
- }
- return renduiPriceDailyService.getByProductSpecAndDate(renduiPriceDailyDTO);
- }
在校验一个String类型的变量是否为空时,可以使用StringUtils.isBlank方法,它可以校验三种情况:是否为null、是否为""、是否为空字符串(引号中间有空格)" "、制表符、换行符、换页符和回车。
- StringUtils.isEmpty("yyy") = false
- StringUtils.isEmpty("") = true
- StringUtils.isEmpty(" ") = false
-
- StringUtils.isBlank("yyy") = false
- StringUtils.isBlank("") = true
- StringUtils.isBlank(" ") = true
- /**
- * 根据ProductSpec和date查询
- * 查询条件: 地区,ProductSpec,date
- * @param renduiPriceDailyDTO
- * @return
- */
- Result> getByProductSpecAndDate(RenduiPriceDailyDTO renduiPriceDailyDTO);
- }
- @Override
- public Result> getByProductSpecAndDate(RenduiPriceDailyDTO renduiPriceDailyDTO) {
- //1.获取该日期的每日统计结果
- long date = renduiPriceDailyDTO.getDate().atStartOfDay().toInstant(ZoneOffset.of("+8")).toEpochMilli();
- Document daily = renduiPriceDailyManager.queryByProductSpec(renduiPriceDailyDTO.getSiteId(), renduiPriceDailyDTO.getProductSpec(), date);
- if(daily == null){
- return Result.error("当前没有报价,暂无统计");
- }
- //今开
- if (daily.get("openingPrice") != null) {
- daily.put("openingPrice",daily.get("openingPrice"));
- daily.put("openingPriceTax",daily.get("openingPriceTax"));
- }else {
- daily.put("openingPrice",0);
- daily.put("openingPriceTax",0);
- }
- //2.查询该日期前一天的每日统计结果
- long yesterday = renduiPriceDailyDTO.getDate().minusDays(1).atStartOfDay().toInstant(ZoneOffset.of("+8")).toEpochMilli();
- Document yesterdayDaily = renduiPriceDailyManager.queryByProductSpec(renduiPriceDailyDTO.getSiteId(), renduiPriceDailyDTO.getProductSpec(), yesterday);
- if(yesterdayDaily == null){
- daily.put("closePrice",0);
- daily.put("closePriceTax",0);
- daily.put("riseAndFall",0);
- daily.put("riseAndFallTax",0);
- daily.put("riseRange",0.00);
- daily.put("riseRangeTax",0.00);
- return Result.OK(daily);
- }
- //3.计算
- //涨跌 当前价 - 昨天均价
- Float riseAndFall = Float.valueOf(daily.get("lastprice").toString()) - Float.valueOf(yesterdayDaily.get("price").toString());
- Float riseAndFallTax = Float.valueOf(daily.get("lastpriceTax").toString()) - Float.valueOf(yesterdayDaily.get("priceTax").toString());
- //涨幅 涨跌 / 昨天均价
- Float riseRange = Double.valueOf(AccurateCalculation.div(riseAndFall,Double.valueOf(yesterdayDaily.get("price").toString()),2)).floatValue() * 100;
- Float riseRangeTax = Double.valueOf(AccurateCalculation.div(riseAndFallTax,Double.valueOf(yesterdayDaily.get("priceTax").toString()),2)).floatValue() * 100;
- daily.put("riseAndFall",riseAndFall);
- daily.put("riseAndFallTax",riseAndFallTax);
- daily.put("riseRange",riseRange);
- daily.put("riseRangeTax",riseRangeTax);
- //昨收
- daily.put("closePrice",yesterdayDaily.get("closePrice"));
- daily.put("closePriceTax",yesterdayDaily.get("closePriceTax"));
- return Result.OK(daily);
- }
atStartOfDay()
long date = renduiPriceDailyDTO.getDate().atStartOfDay().toInstant(ZoneOffset.of("+8")).toEpochMilli();
java.time.LocalDate.atStartOfDay()方法将此日期与午夜时间组合在一起,以便在此日期开始时创建LocalDateTime。
声明
public LocalDateTime atStartOfDay()
返回值
此日期开始时的午夜的本地日期时间,不为null。
示例
- package com.yiibai;
-
- import java.time.LocalDate;
- import java.time.LocalDateTime;
-
- public class LocalDateDemo {
- public static void main(String[] args) {
-
- LocalDate date = LocalDate.parse("2017-02-03");
- System.out.println(date);
- LocalDateTime date1 = date.atStartOfDay();
- System.out.println(date1);
- }
- }
-
-
结果
- 2017-02-03
- 2017-02-03T00:00
Java8出现的 Instant 类似于 Date ,LocalDateTime 类似于 Calendar,DateTimeFormatter 类似于 SimpleDateFormat,由于 SimpleDateFormat 是线程不安全的(一般使用 SimpleDateFormat 的时会把它定义成静态变量,从而避免频繁地创建它的对象实例,但 SimpleDateFormat 内部使用 Calendar 去完成日期的转换,多线程情况下可能会出现线程不安全情况),推荐使用 Instant代替 Date,LocalDateTime 代替 Calendar,DateTimeFormatter 代替 SimpleDateFormat
- // 输出当前时间:2019-04-24T19:41:21.858
- LocalDateTime now = LocalDateTime.now();
- System.out.println(now);
-
- // 格式化时间,输出:2019年04月24日 19:49:25
- LocalDateTime time = LocalDateTime.now();
- String timeStr = time.format(DateTimeFormatter.ofPattern("yyyy年年MM月dd日 HH:mm:ss"));
- System.out.println(timeStr);
-
- // 当前时间增加20分钟
- LocalDateTime afterPlusTime = LocalDateTime.now().plus(20, ChronoUnit.MINUTES);
- System.out.println(afterPlusTime);
-
- // 创建开始和结束时间,并计算中间差值
- LocalDateTime start = LocalDateTime.of(1992, 8, 13, 0, 0, 0);
- LocalDateTime end = LocalDateTime.of(2019, 4, 25, 0, 0);
- long diff = LocalDateTimeUtils.betweenTwoTime(start, end, ChronoUnit.YEARS);
- System.out.println(diff+"年"); // 26
-
- boolean b = start.isAfter(end);
- System.out.println(b); // false
-
- //获取秒数 (东8区,也就是北京时间)
- Long second = LocalDateTime.now().toEpochSecond(ZoneOffset.of("+8"));
- //获取毫秒数(东8区,也就是北京时间)
- Long milliSecond = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
- Instant now = Instant.now(); // 2019-04-24T12:30:34.349Z
- long currentSecond = now.getEpochSecond(); // 秒数:1556109034
- long currentMilli = now.toEpochMilli(); // 毫秒数:1556109034349
-
- Instant afterPlusSecondInstant = now.plusSeconds(1000); // 秒数增加1000
- boolean b = now.isBefore(afterPlusSecondInstant); // 比较
- // 输出:2019年04月24日 20:53:23
- DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss");
- LocalDateTime time = LocalDateTime.now();
- String formatResult = time.format(df);
-
- // 输出:20190424
- LocalDateTime time = LocalDateTime.now();
- String formatResult = time.format(DateTimeFormatter.BASIC_ISO_DATE);
- ISO_DATE --> 2019-04-24
- ISO_LOCAL_DATE --> 2019-04-24
- ISO_LOCAL_TIME --> 20:59:48.42
- ISO_TIME --> 21:00:38.256
- ISO_LOCAL_DATE_TIME --> 2019-04-24T21:01:11.083
- .......
格式转化
- Instant instant = Instant.now();
- Date date = Date.from(instant); // Instant转换为Date
- Instant instant2 = date.toInstant(); // Date转换为Instant
-
- // Date 与 LocalDateTime 的转换是通过 Instant 中间的转换来进行的
- Date date = new Date();
- LocalDateTime localDateTime = LocalDateTime.ofInstant(date.toInstant(),ZoneId.systemDefault()); // Date转换为LocalDateTime
-
- LocalDateTime localDateTime = LocalDateTime.now();
- Instant instant = localDateTime.atZone(ZoneId.systemDefault()).toInstant();
- Date date = Date.from(instant); // LocalDateTime转换为Date


- /**
- * 查询分钟维度价格统计(曲线图的数据接口)
- * @param
- * @return
- */
- @AutoLog(value = "/prices/statistics")
- @ApiOperation(value = "/prices/statistics", notes = "/prices/statistics")
- @GetMapping(value = "/prices/statistics")
- public Result> statisticsPrice(@RequestParam(value = "productSpec") String productSpec, @RequestParam(value = "siteId")String siteId, @RequestParam(value = "from")String from, @RequestParam(value = "to")String to) {
- boolean fromBeforeTo = DateCommonUtil.getDateFromStr(from).before(DateCommonUtil.getDateFromStr(to));
- if(!fromBeforeTo){
- return Result.error("开始时间不能大于结束时间");
- }
- return service.statisticsPrice(productSpec, siteId, from, to);
- }
Result> statisticsPrice(String productSpec, String siteId, String from, String to);
- @Override
- public Result> statisticsPrice(String productSpec, String siteId, String from, String to) {
- long dateDiff = DateUtil.betweenDay(DateCommonUtil.getDateFromStr(from), DateCommonUtil.getDateFromStr(to), false);
- boolean isSameDay = DateUtil.isSameDay(DateCommonUtil.getDateFromStr(from), DateCommonUtil.getDateFromStr(to));
- if (dateDiff <= 0 && isSameDay) {
- return Result.OK(statisticsMinutely2(productSpec, siteId, from, to));
- } else {
- return Result.OK(statisticsDaily(productSpec, siteId, from, to, dateDiff));
- }
- }
- private Map
statisticsMinutely2(String productSpec, String siteId, String from, String to) { - Map
map = new HashMap<>(); - map.put("rangeAvgPrice",0);
- long FIVE_MINUTES = 5 * 60000;
- long fromTime = DateCommonUtil.getTimeFromStr(from);
- long toTime = DateCommonUtil.getTimeFromStr(to);
- List
minutely = renduiPriceMinutelyManager.queryByProductSpec(productSpec, siteId, fromTime, toTime); - List
results = new ArrayList<>(); - long minuteDiff = DateUtil.between(DateCommonUtil.getDateFromStr(from), DateCommonUtil.getDateFromStr(to), DateUnit.MINUTE);
- int window = (int) minuteDiff / 5;
- // 如果为空
- if (minutely.size() == 0) {
- PriceStatisticsVO lastPrice = getLastPrice(productSpec, siteId, fromTime);
- long t = fromTime;
- while (t <= toTime) {
- PriceStatisticsVO p = new PriceStatisticsVO();
- BeanUtil.copyProperties(lastPrice, p);
- p.setTimestamp(t);
- results.add(lastPrice);
- t += 5 * 60000;
- }
- map.put("list",results);
- return map;
- }
-
- PriceStatisticsVO firstPrice = new PriceStatisticsVO();
- BeanUtil.copyProperties(minutely.get(0), firstPrice);
- // 补充左边的数据
- long fistTime = firstPrice.getTimestamp();
- PriceStatisticsVO formerPrice = null;
- if (fistTime > fromTime) {
- PriceStatisticsVO latestPrice = getLastPrice(productSpec, siteId, fromTime);
- long t = fromTime;
- int i = 0;
- while (t < fistTime) {
- PriceStatisticsVO p = new PriceStatisticsVO();
- BeanUtil.copyProperties(latestPrice, p);
- p.setTimestamp(t);
-
- results.add(p);
- formerPrice = p;
- i ++;
- t += FIVE_MINUTES;
- }
- }
-
- // 补充中间数据
-
- for (int i = 0; i < minutely.size(); i ++) {
- Document m = minutely.get(i);
- PriceStatisticsVO price = new PriceStatisticsVO();
- BeanUtil.copyProperties(m, price);
- // 补充中间数据
- if (formerPrice != null && price.getTimestamp() - formerPrice.getTimestamp() > FIVE_MINUTES) {
- long t = formerPrice.getTimestamp() + FIVE_MINUTES;
- while ( t < price.getTimestamp()) {
- PriceStatisticsVO p = new PriceStatisticsVO();
- BeanUtil.copyProperties(formerPrice, p);
- p.setTimestamp(t);
- results.add(p);
- t += FIVE_MINUTES;
- }
- }
- results.add(price);
- formerPrice = price;
- }
-
- if (formerPrice != null && formerPrice.getTimestamp() < toTime) {
- long t = formerPrice.getTimestamp() + FIVE_MINUTES;
- while ( t < toTime) {
- PriceStatisticsVO p = new PriceStatisticsVO();
- BeanUtil.copyProperties(formerPrice, p);
- p.setTimestamp(t);
- results.add(p);
- t += FIVE_MINUTES;
- }
- }
- map.put("list",results);
- return map;
- }
需求
求出 当前天, 与指定日期之间相差的天数, 指定日期一定在 当前天之前即 当前天为 01-23 , 指定日期应该为 01-22
解决方案
使用hutools工具包中提供的计算两个日期之间相差天数的方法
betweenDay()
三个参数: betweenDay(Date,Date,Boolean)
- // 使用方式
- // cn.hutool.core.date.DateUtil.betweenDay(currentDate, targetTime, true);
- // 源码
- /**
- * 判断两个日期相差的天数
- *
- *
- * 有时候我们计算相差天数的时候需要忽略时分秒。
- * 比如:2016-02-01 23:59:59和2016-02-02 00:00:00相差一秒
- * 如果isReset为
false相差天数为0。 - * 如果isReset为
true相差天数将被计算为1 - *
- *
- * @param beginDate 起始日期
- * @param endDate 结束日期
- * @param isReset 是否重置时间为起始时间
- * @return 日期差
- * @since 3.0.1
- */
- public static long betweenDay(Date beginDate, Date endDate, boolean isReset) {
- if (isReset) {
- beginDate = beginOfDay(beginDate);
- endDate = beginOfDay(endDate);
- }
- return between(beginDate, endDate, DateUnit.DAY);
- }
- private Map
statisticsDaily(String productSpec, String siteId, String from, String to, long dateDiff) { - List
result = new ArrayList<>(); - //按天统计
- long fromTime = 0;
- List
avgList = new ArrayList<>(); - Map
map = new HashMap<>(); - for (int i = 0; i < dateDiff + 1; i++) {
- if (i == 0) {
- fromTime = DateCommonUtil.getTimeFromStr(from);
- }
- long toTime = DateCommonUtil.dayAfterInterval(DateCommonUtil.dateFromTimestamp(fromTime), 1).getTime();
- List
daily = renduiPriceDailyManager.queryByProductSpec(productSpec, siteId, fromTime, toTime); - Float avgPrice = daily.stream().map(document -> document.get("price") == null ? 0 : Float.parseFloat(document.get("price").toString()))
- .collect(Collectors.averagingDouble(price -> price)).floatValue();
- //当avgPrice > 0
- if(avgPrice.compareTo(new Float(0.00f)) == 1 ){
- avgList.add(avgPrice);
- }
- PriceStatisticsVO statisticsVO = new PriceStatisticsVO();
- statisticsVO.setProductSpec(productSpec);
- statisticsVO.setPrice(Float.valueOf("0.00"));
- statisticsVO.setPriceTax(Float.valueOf("0.00"));
- statisticsVO.setSatisticsTime(DateCommonUtil.strFromTimestamp(fromTime));
- if (CollectionUtil.isEmpty(daily)) {
- setDailyEmptyVal(productSpec, siteId, fromTime, i, statisticsVO);
- } else {
- BeanUtil.copyProperties(daily.get(daily.size() - 1), statisticsVO);
- }
- fromTime = toTime;
- result.add(statisticsVO);
- }
-
- for (int i = 0; i < result.size(); i++) {
- //将空值替换为上个周期的数据 ,因为前面保证了第一条数据一定有值所以不会出现数组越界问题
- if (result.get(i).getProductSpec() != null && result.get(i).getProductSpec().equals(EMPTY_MARK)) {
- PriceStatisticsVO statisticsVO = getNotEmptyOne(i - 1, result);
- String statisticTime = result.get(i).getSatisticsTime();
- BeanUtil.copyProperties(statisticsVO, result.get(i));
- result.get(i).setSatisticsTime(statisticTime);
- }
- }
- Float rangeAvgPrice = avgList.stream().collect(Collectors.averagingDouble(avg -> avg)).floatValue();
- map.put("rangeAvgPrice",rangeAvgPrice);
- map.put("list",result);
- return map;
- }
- /**
- * 大盘价曲线图
- * 根据范围查询
- * 查询条件 productSpec,siteId,from,to
- * @param bigDishPriceDTO
- * @return
- */
- @PostMapping(value = "/bigDishPrice/rangeQueryBigDishPrice")
- public Result> rangeQueryBigDishPrice(@RequestBody BigDishPriceDTO bigDishPriceDTO){
- if(StringUtils.isBlank(bigDishPriceDTO.getProductSpec())){
- return Result.error("查询条件不能为空!");
- }
- if(StringUtils.isBlank(bigDishPriceDTO.getSiteId())){
- return Result.error("地区不能为空!");
- }
- if(bigDishPriceDTO.getTo().compareTo(LocalDateTime.now().plusMinutes(1)) == 1){
- return Result.error("结束时间需小于当前时间!");
- }
- if(bigDishPriceDTO.getFrom().compareTo(bigDishPriceDTO.getTo()) >= 0){
- return Result.error("开始时间需小于结束时间!");
- }
- return bigDishPriceService.rangeQueryBigDishPrice(bigDishPriceDTO);
- }
- /**
- * 大盘价曲线图
- * 根据范围查询
- * 查询条件 productSpec,siteId,from,to
- * @param bigDishPriceDTO
- * @return
- */
- Result> rangeQueryBigDishPrice(BigDishPriceDTO bigDishPriceDTO);
- @Override
- public Result> rangeQueryBigDishPrice(BigDishPriceDTO bigDishPriceDTO) {
- Duration duration = Duration.between(bigDishPriceDTO.getFrom(),bigDishPriceDTO.getTo());
- //当前查询范围大于1天
- if(duration.toDays() > 1){
- return Result.OK(replenishDayData(bigDishPriceDTO.getProductSpec(),bigDishPriceDTO.getSiteId(),bigDishPriceDTO.getFrom(),bigDishPriceDTO.getTo(),duration.toDays()));
- }
- //1.查询范围内大盘价
- long fromTime = bigDishPriceDTO.getFrom().toInstant(ZoneOffset.of("+8")).toEpochMilli();
- long toTime = bigDishPriceDTO.getTo().toInstant(ZoneOffset.of("+8")).toEpochMilli();
- List
priceList = renduiPriceMinutelyManager.queryByProductSpec(bigDishPriceDTO.getProductSpec(), bigDishPriceDTO.getSiteId(), fromTime, toTime); - List
result = new ArrayList<>(); - // 如果为空取之前的最后一条大盘价
- if (priceList.size() == 0 || priceList == null) {
- Document doc = renduiPriceMinutelyManager.queryLastDataBy(bigDishPriceDTO.getProductSpec(), bigDishPriceDTO.getSiteId(), fromTime);
- if(doc == null){
- return Result.OK();
- }
- doc.put("price",Float.parseFloat(doc.get("price").toString()));
- doc.put("priceTax",Float.parseFloat(doc.get("priceTax").toString()));
- PriceStatisticsVO lastPrice = JSONObject.parseObject(JSON.toJSONString(doc), PriceStatisticsVO.class);
- long from = fromTime;
- while (from <= toTime) {
- PriceStatisticsVO p = new PriceStatisticsVO();
- BeanUtil.copyProperties(lastPrice, p);
- p.setTimestamp(from);
- p.setSatisticsTime(LocalDateTime.ofInstant(Instant.ofEpochMilli(from),ZoneOffset.of("+8")).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
- result.add(p);
- from = from + 5 * 60 * 1000;
- }
- return Result.OK(result);
- }
- //2.补充左边的数据
- Document firstDoc = priceList.get(0);
- firstDoc.put("price",Float.parseFloat(firstDoc.get("price").toString()));
- firstDoc.put("priceTax",Float.parseFloat(firstDoc.get("priceTax").toString()));
- PriceStatisticsVO firstPrice = JSONObject.parseObject(JSON.toJSONString(firstDoc), PriceStatisticsVO.class);
- PriceStatisticsVO flagPrice = null;
- if(firstPrice.getTimestamp() > fromTime){
- Document doc = renduiPriceMinutelyManager.queryLastDataBy(bigDishPriceDTO.getProductSpec(), bigDishPriceDTO.getSiteId(), fromTime);
- //如果之前没有数据则
- PriceStatisticsVO lastPrice;
- if(doc == null){
- lastPrice = firstPrice;
- }else {
- doc.put("price",Float.parseFloat(doc.get("price").toString()));
- doc.put("priceTax",Float.parseFloat(doc.get("priceTax").toString()));
- lastPrice = JSONObject.parseObject(JSON.toJSONString(doc), PriceStatisticsVO.class);
- }
- long from = fromTime;
- while (from < firstPrice.getTimestamp()) {
- PriceStatisticsVO p = new PriceStatisticsVO();
- BeanUtil.copyProperties(lastPrice, p);
- p.setTimestamp(from);
- p.setSatisticsTime(LocalDateTime.ofInstant(Instant.ofEpochMilli(from),ZoneOffset.of("+8")).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
- result.add(p);
- from = from + 5 * 60 * 1000;
- flagPrice = p;
- }
- }
- //3.补充中间的数据
- for (Document document : priceList) {
- document.put("price",Float.parseFloat(document.get("price").toString()));
- document.put("priceTax",Float.parseFloat(document.get("priceTax").toString()));
- PriceStatisticsVO price = JSONObject.parseObject(JSON.toJSONString(document), PriceStatisticsVO.class);
- if(flagPrice != null && price.getTimestamp() - flagPrice.getTimestamp() >= 5 * 60 * 1000){
- //+ 5 分钟
- long from = flagPrice.getTimestamp() + 5 * 60 * 1000;
- while (from < price.getTimestamp()){
- PriceStatisticsVO p = new PriceStatisticsVO();
- BeanUtil.copyProperties(price, p);
- p.setTimestamp(from);
- p.setSatisticsTime(LocalDateTime.ofInstant(Instant.ofEpochMilli(from),ZoneOffset.of("+8")).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
- result.add(p);
- from = from + 5 * 60 * 1000;
- }
- }
- price.setSatisticsTime(LocalDateTime.ofInstant(Instant.ofEpochMilli(price.getTimestamp()),ZoneOffset.of("+8")).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
- result.add(price);
- flagPrice = price;
- }
- //4.补充右边的数据
- if(flagPrice != null && flagPrice.getTimestamp() < toTime){
- //+ 5 分钟
- long from = flagPrice.getTimestamp() + 5 * 60 * 1000;
- while (from < toTime){
- PriceStatisticsVO p = new PriceStatisticsVO();
- BeanUtil.copyProperties(flagPrice, p);
- p.setTimestamp(from);
- p.setSatisticsTime(LocalDateTime.ofInstant(Instant.ofEpochMilli(from),ZoneOffset.of("+8")).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
- result.add(p);
- from = from + 5 * 60 * 1000;
- }
- }
- return Result.OK(result);
- }
- /**
- * 根据范围计算基差
- * 计算规则:市场价 - 大盘价
- * @param bigDishPriceDTO
- * @return
- */
- @PostMapping(value = "/bigDishPrice/rangeQueryBasicDiff")
- public Result> rangeQueryBasicDiff(@RequestBody BigDishPriceDTO bigDishPriceDTO){
- if(StringUtils.isBlank(bigDishPriceDTO.getProductSpec()) || StringUtils.isBlank(bigDishPriceDTO.getBigDishProductSpec())){
- return Result.error("查询条件不能为空!");
- }
- if(StringUtils.isBlank(bigDishPriceDTO.getSiteId()) || StringUtils.isBlank(bigDishPriceDTO.getBigDishSiteId())){
- return Result.error("地区不能为空!");
- }
- if(bigDishPriceDTO.getTo().compareTo(LocalDateTime.now().plusMinutes(1)) == 1){
- return Result.error("结束时间需小于当前时间!");
- }
- if(bigDishPriceDTO.getFrom().compareTo(bigDishPriceDTO.getTo()) >= 0){
- return Result.error("开始时间需小于结束时间!");
- }
- return bigDishPriceService.rangeQueryBasicDiff(bigDishPriceDTO);
- }
- /**
- * 根据范围查询基差
- * 计算规则:市场价 - 大盘价
- * @param bigDishPriceDTO
- * @return
- */
- Result> rangeQueryBasicDiff(BigDishPriceDTO bigDishPriceDTO);
serviceImpl层
- @Override
- public Result> rangeQueryBasicDiff(BigDishPriceDTO bigDishPriceDTO) {
- //计算公式 市场价 - 大盘价
- //1.存储结果
- List
result = new ArrayList<>(); - Duration duration = Duration.between(bigDishPriceDTO.getFrom(),bigDishPriceDTO.getTo());
- //当前查询范围大于1天
- if(duration.toDays() > 1){
- //2.根据时间补齐市场价的数据
- List
priceList = replenishDayData(bigDishPriceDTO.getProductSpec(), bigDishPriceDTO.getSiteId(), bigDishPriceDTO.getFrom(), bigDishPriceDTO.getTo(),duration.toDays()); - //3.根据时间补齐大盘价的数据
- List
bigDishPriceList = replenishDayData(bigDishPriceDTO.getBigDishProductSpec(), bigDishPriceDTO.getBigDishSiteId(), bigDishPriceDTO.getFrom(), bigDishPriceDTO.getTo(),duration.toDays()); - Map
bigDishPriceMap = bigDishPriceList.stream().collect(Collectors.toMap(priceStatisticsVO -> priceStatisticsVO.getSatisticsTime(), o -> o.getPrice())); - //4.计算存储结果
- priceList.forEach(p -> {
- PriceStatisticsVO priceStatisticsVO = new PriceStatisticsVO();
- //基差 = 市场价 - 大盘价
- Float basicDiff = p.getPrice() - bigDishPriceMap.get(p.getSatisticsTime());
- basicDiff = new BigDecimal(basicDiff).setScale(2,RoundingMode.HALF_UP).floatValue();
- priceStatisticsVO.setPrice(basicDiff);
- priceStatisticsVO.setSatisticsTime(p.getSatisticsTime());
- priceStatisticsVO.setTimestamp(p.getTimestamp());
- result.add(priceStatisticsVO);
- });
- return Result.OK(result);
- }
- //2.根据时间补齐市场价的数据
- List
priceList = replenishData(bigDishPriceDTO.getProductSpec(), bigDishPriceDTO.getSiteId(), bigDishPriceDTO.getFrom(), bigDishPriceDTO.getTo()); - if(priceList == null || priceList.size() == 0){
- return Result.OK();
- }
- //3.根据时间补齐大盘价的数据
- List
bigDishPriceList = replenishData(bigDishPriceDTO.getBigDishProductSpec(), bigDishPriceDTO.getBigDishSiteId(), bigDishPriceDTO.getFrom(), bigDishPriceDTO.getTo()); - if(bigDishPriceList == null || bigDishPriceList.size() == 0){
- return Result.OK();
- }
- Map
bigDishPriceMap = bigDishPriceList.stream().collect(Collectors.toMap(priceStatisticsVO -> priceStatisticsVO.getSatisticsTime(), o -> o.getPrice())); - //4.计算存储结果
- priceList.forEach(p -> {
- PriceStatisticsVO priceStatisticsVO = new PriceStatisticsVO();
- //基差 = 市场价 - 大盘价
- Float basicDiff = p.getPrice() - bigDishPriceMap.get(p.getSatisticsTime());
- basicDiff = new BigDecimal(basicDiff).setScale(2,RoundingMode.HALF_UP).floatValue();
- priceStatisticsVO.setPrice(basicDiff);
- priceStatisticsVO.setSatisticsTime(p.getSatisticsTime());
- priceStatisticsVO.setTimestamp(p.getTimestamp());
- result.add(priceStatisticsVO);
- });
- return Result.OK(result);
- }