一、BUG评级

  1. BUG发现难度:★★★☆☆ (难度主要在偶然性上)
  2. BUG无法复现概率:★★★★☆ (如果开发喜欢下午改BUG的话,100%无法复现)
  3. BUG无法复现时,被开发鄙视程度:★★★★★
  4. BUG修复,烧脑程度:★☆☆☆☆

二、需求概述

前端页面有一个选择年+月的下拉框,要求系统上线前的月份不展示。
如:2020-11开始有数据,到2021-03月,应该有如下的选项:
在这里插入图片描述

三、开发实现

由后台计算并返回选项列表,前端仅负责展示。(我知道这样可能并不合适,请忽略继续往下看)

四、测试人员发现并跟踪BUG

BUG标题:当前时间是2021-03,xxx下拉框,没有正常显示‘2021-03’这个选项(即:上图中的最后一个选项没有)
--------跟踪记录:
2021年3月08日 09:21 测试A:新增
2021年3月08日 11:12 前端B:该下拉框选项由后端接口返回,前端只负责展示,转派‘后端C’
2021年3月08日 13:33 后端C:无法复现,请提供详细信息,如客户号,帐号等等。
2021年3月08日 15:12 测试A:~~~~上午用过的 帐号都试了,确实无法复现。继续观察

2021年3月12日 10:35 测试A:reopen,又出现啦。客户号 xxx,帐号xxx,附件:xxx.png
2021年3月12日 10:42 后端C:really?无法复现啊?是不是浏览器兼容性问题?
2021年3月12日 10:45 测试A:稍等,可能是好像眼花了,不对,请看截图
2021年3月12日 10:46 后端C:我那天看到你在跟UI学PS~~~
2021年3月12日 10:47 测试A:有截图为证,下面是rpc的日志:
2021年3月12日 10:32 result1 = [2020-11, 2020-12, 2021-01, 2021-02] <---- 少一个月!!!!
2021年3月12日 10:41 result1 = [2020-11, 2020-12, 2021-01, 2021-02, 2021-03] <---- 正常
2021年3月12日 10:44 result1 = [2020-11, 2020-12, 2021-01, 2021-02, 2021-03] <---- 正常
2021年3月12日 10:44 result1 = [2020-11, 2020-12, 2021-01, 2021-02, 2021-03] <---- 正常
2021年3月12日 10:45 result1 = [2020-11, 2020-12, 2021-01, 2021-02, 2021-03] <---- 正常
2021年3月12日 11:33 后端C:确认是后台问题,已修复,代码已提交。验证时,请在 每天10:40:02 这个时间点 之前 之后 分别测试

五、Code review

下面用main函数模拟出错的代码段

// 页面需求,一个时间下拉框,显示年月。
// 要求第一条数据是后台第一条数据的年月,第二条是第一条月份+1,直到当前时间年月
public static void main(String[] args) {
    // 数据库的 firstLogTime  是 2020-11-12 10:40:02.347 , 这里直接写死
    long firstLogTime = 1605148802347l; // 时间戳
    List<String> result1 = errorCode(firstLogTime);
    // 修改前(测试时间,2021年的3月份)
    // 10:40:02 之前执行 result1 = [2020-11, 2020-12, 2021-01, 2021-02]  少一个月!!!!
    // 10:40:02 之前执行 result1 = [2020-11, 2020-12, 2021-01, 2021-02, 2021-03]
    System.out.println("result1 = " + result1);
private static List<String> errorCode(long firstLogTime) {
    List<String> result = new ArrayList<>();
    LocalDateTime localDateTime =
            LocalDateTime.ofInstant(Instant.ofEpochMilli(firstLogTime), ZoneId.systemDefault())
                    .withDayOfMonth(1);
    LocalDateTime now = LocalDateTime.now().withDayOfMonth(1);  // 2020-11-15 09:01:02.347 如果是在10点40分前
    // 年月
    final DateTimeFormatter monthFormat = DateTimeFormatter.ofPattern("yyyy-MM");
    do {
        result.add(localDateTime.format(monthFormat));
        localDateTime = localDateTime.plusMonths(1);
    } while (!localDateTime.isAfter(now));
    return result;

六、BUG分析

1、数据库存的时间是时间戳,所以开发从数据库取出来以后,使用LocalDateTime类处理成当月的1号,把当前系统时间也取出来处理成1号,如下图:
在这里插入图片描述如果不考虑时间(上图红框部分),在下面的while循环中,是能正常比较大小的,

while (!localDateTime.isAfter(now))

但是因为加了时间,导致每天的10:40:02 之前之后执行结果不一样。

七、完整代码

import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
public class Bug_LocalDateTime {
    // 页面需求,一个时间下拉框,显示年月。
    // 要求第一条数据是后台第一条数据的年月,第二条是第一条月份+1,直到当前时间年月
    public static void main(String[] args) {
        // 数据库的 firstLogTime  是 2020-11-12 10:40:02.347 , 这里直接写死
        long firstLogTime = 1605148802347l; // 时间戳
        List<String> result1 = errorCode(firstLogTime);
        // 修改前(测试时间,2021年的3月份)
        // 10:40:02 之前执行 result1 = [2020-11, 2020-12, 2021-01, 2021-02]  少一个月!!!!
        // 10:40:02 之前执行 result1 = [2020-11, 2020-12, 2021-01, 2021-02, 2021-03]
        System.out.println("result1 = " + result1);
        // 修改后
        List<String> result2 = rightCode(firstLogTime);
        System.out.println("result2 = " + result2);
    private static List<String> errorCode(long firstLogTime) {
        List<String> result = new ArrayList<>();
        LocalDateTime localDateTime =
                LocalDateTime.ofInstant(Instant.ofEpochMilli(firstLogTime), ZoneId.systemDefault())
                        .withDayOfMonth(1);
        LocalDateTime now = LocalDateTime.now().withDayOfMonth(1);  // 2020-11-15 09:01:02.347 如果是在10点40分前
        // 年月
        final DateTimeFormatter monthFormat = DateTimeFormatter.ofPattern("yyyy-MM");
        do {
            result.add(localDateTime.format(monthFormat));
            localDateTime = localDateTime.plusMonths(1);
        } while (!localDateTime.isAfter(now));
        return result;
    private static List<String> rightCode(long firstLogTime) {
        List<String> result = new ArrayList<>();
        LocalDate localDate = LocalDateTime.ofInstant(Instant.ofEpochMilli(firstLogTime), ZoneId.systemDefault())
                .toLocalDate().withDayOfMonth(1);
        LocalDate now = LocalDate.now().withDayOfMonth(1);  // 2020-11-15 09:01:02.347 如果是在10点40分前
        // 年月
        final DateTimeFormatter monthFormat = DateTimeFormatter.ofPattern("yyyy-MM");
        do {
            result.add(localDate.format(monthFormat));
            localDate = localDate.plusMonths(1);
        } while (!localDate.isAfter(now));
        return result;
                    那些神奇的BUG-0001-LocalDateTime 错误使用,导致的偶现问题一、BUG评级二、需求概述三、开发实现四、测试人员发现并跟踪BUG五、Code review六、BUG分析七、完整代码一、BUG评级BUG发现难度:★★★☆☆ (难度主要在偶然性上)BUG无法复现概率:★★★★☆ (如果开发喜欢下午改BUG的话,100%无法复现)BUG无法复现时,被开发鄙视程度:★★★★★BUG修复,烧脑程度:★☆☆☆☆二、需求概述前端页面有一个选择年+月的下拉框,要求系统上线前的月份不展示。
				
public static int differentDays(Date date1,Date date2) Calendar cal1 = Calendar.getInstance(); cal1.setTime(date1); Calendar cal2 = Calendar.getInstance(); cal2.setTime(date2);
今天碰到了个LocalDateTime.now()值存到mysql怎么都差八个小时问题,我知道是时差问题,但一开始并没有搞明白是哪里时差问题,还一直把问题定位到序列化的位置,但经过尝试发现并不是序列化问题,最后想到是不是数据源链接问题,一看,真是数据源链接处时区问题,这里不贴出代码了,百度一下有很多。
LocalDateTime时间序列化问题与返序列问题,mybatisLocalDateTime时间序列化问题 Execution of Rabbit message listener failed. Cannot construct instance of `java.time.LocalDateTime` ( org.springframework.amqp.rabbit.support.ListenerExecutionFailedException: Listener threw exception
最近在做一个小框架,因为本身比较精简,就没有引入太多依赖,直接用了JDBC来操作数据库,因为我的表有一个datetime类型的字段,对应的Java代码使用的是java.time.LocalDateTime,在处理这个日期字段的时候,就遇到了一个有趣的问题; 在我的数据库表建好后,在Java使用JDBC原生API实现了一个repository,包含一些数据库的操作,因为代码java.time.LocalDateTime字段,在使用java.sql.PreparedStatement的时候不确认ja
public static void main(String[] args) { SpringApplication.run(SwappingApplication.class, args); @PostConstruct void started() { // Tim
新项目里使用LocalDateTime遇到了一些坑,总结一下,本文章以全局配置方式解决了以下问题ヽ( ̄▽ ̄)ノ: 0、**概念介绍**:前端参数**反序列化**到后端,后端参数**序列化**到前端,具体概念请咨询战略合作伙伴(ノ゚∀゚)ノ [百度一下](https://www.baidu.com/) 1、数据库和后端的日期差:请在数据库链接上加上&serverTimezone=Asia/Shanghai。 2、后端无法接收数据库参数:大概率是数据库连接池包版本太低了,不支持LocalDatetime,我的是
将Date转换为LocalDatetime,我们可以使用以下方法: 1.从日期获取ZonedDateTime使用其方法toLocalDateTime()获取LocalDateTime 2.使用LocalDateTime的Instant()工厂方法 package insping; ...
```java String dateStr = "2022-03"; DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM"); LocalDateTime localDateTime = LocalDateTime.parse(dateStr, formatter); System.out.println(localDateTime); 在这个示例,我们使用"yyyy-MM"作为日期时间格式的模式,并将字符串"2022-03"解析成LocalDateTime对象。然后,我们将其打印出来。