写代码被大语言模型坑之使用LocalDateTime比较两个时间差了几天
自从去年ChatGPT3.5发布后使用了几次,现在写代码基本上离不开它和它的衍生产品们了。一方面查资料很方便,快速提炼要点总结;另一方面想写什么样的代码一问就能生成出来,功能大差不差,稍微改改就能用,大大减少使用搜索引擎的时间,是新时代高阶版的Ctrl+C/V。
不过大语言模型归根揭底是靠训练集训练出来的,它给出的代码还是要自己测试一下用起来才放心,比如这次就被它坑了一把。
注:因种种原因,本文仅测试了一些国内的大语言模型,没有测试ChatGPT。
原始需求
某列表查询功能,入参包含一组起止日期,需要校验起止日期跨度小于等于200天。
前端传参现状
将用户选择的起止日期(yyyy-MM-dd)转换成"yyyy-MM-dd HH:mm:ss"格式的字符串,且起始时间是"yyyy-MM-dd 00:00:00",终止时间是"yyyy-MM-dd 23:59:59"。
比如,页面上选择从2024-09-01到2024-09-30,实际的入参是"2024-09-01 00:00:00"和"2024-09-30 23:59:59"。而且对于这组参数,时间跨度是30天,也就是说包括首尾的当天。
需求简化
为了便于测试,我先把时间跨度的要求改为2天,比如"2024-09-01 00:00:00"到"2024-09-02 23:59:59"的时间跨度正好是2天。需求可以简化为:
String sendDateBegin="2024-09-01 00:00:00"
String sendDateEnd="2024-09-02 23:59:59"
Java代码判断两个天数是否小于等于2天
kimi给的结果:

代码提取出来:
public static void main(String[] args) {
String sendDateBegin = "2024-09-01 00:00:00";
String sendDateEnd = "2024-09-04 23:59:59";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime beginDate = LocalDateTime.parse(sendDateBegin, formatter);
LocalDateTime endDate = LocalDateTime.parse(sendDateEnd, formatter);
// 计算时间差
Duration duration = Duration.between(beginDate, endDate);
// 获取天数差
long daysBetween = duration.toDays();
// 判断天数是否小于等于2
if (daysBetween <= 2) {
System.out.println("两个日期之间的天数小于或等于2天。");
} else {
System.out.println("两个日期之间的天数超过2天。");
}
}
}
发现问题
使用2024-09-01 00:00:00~2024-09-02 23:59:59这组数据,返回结果如下,看上去一切正常:

换一组输入2024-09-01 00:00:00~2024-09-03 23:59:59,居然也告诉我小于等于2天,是哪里出现了问题?

分析
debug一下代码,发现duration.toDays()的实际处理方式是:
将两个时间的秒数差,除以一天包含的秒数(86400),两个参数都是long型。

那么在这个例子里,超过2天但不足3天的数据,由于long的除法,会将小数部分抛弃,再与2比较:2.999≈2,2≤2为true。这就是为什么看似正确的代码实际引入了一个bug。
而且,即使提醒kimi这段代码有bug并告知对应的输入,给出的答案仍然是错的。
同样的问题通义千问给了另一种解法,但是答案仍然是错的:

再看看文心一言,半斤八两:

解决
既然按天比较因为精度丢失而有误差,那么把日期转成毫秒比较就不会丢失精度了,使用如下的判断即可。
Duration.between(beginDate, endDate).toMillis() <= Duration.ofDays(2).toMillis();
这个例子生动的展示,写代码不能完全依赖大语言模型,该做的测试还是要做的。当然,如果你把测试用例的编写工作也交给了大语言模型,或许是能够测出来bug的,挺讽刺的是不是?

写代码被大语言模型坑之使用LocalDateTime比较两个时间差了几天的更多相关文章
- [No000018B]写代码要用 Vim,因为越难入门的工具回报越大
编者按:现在的技术界有一种倾向,将软件/应用操作简单化,用户能轻松上手.但是工具是否强大,取决于它能否灵活地满足使用者的各种需要.有些工具虽然很难入门,学会了便能对自己的操作有更深的层次的了解,能赋予 ...
- 使用 .NET WinForm 开发所见即所得的 IDE 开发环境,实现不写代码直接生成应用程序
直接切入正题,这是我09年到11年左右业余时间编写的项目,最初的想法很简单,做一个能拖拖拽拽就直接生成应用程序的工具,不用写代码,把能想到的业务操作全部封装起来,通过配置的方式把这些业务操作组织起来运 ...
- 如何让Java编译器帮你写代码
作者:京东零售 刘世杰 导读 本文结合京东监控埋点场景,对解决样板代码的技术选型方案进行分析,给出最终解决方案后,结合理论和实践进一步展开.通过关注文中的技术分析过程和技术场景,读者可收获一种样板代码 ...
- 记2016腾讯 TST 校招面试经历,电面、笔试写代码、技术面、hr面,共5轮
(出处:http://www.cnblogs.com/linguanh/) 前序: 距离 2016 腾讯 TST 校招面试结束已经5天了,3月27日至今,目前还在等待消息.从投简历到两轮电面,再到被 ...
- 【腾讯Bugly干货分享】深入理解 ButterKnife,让你的程序学会写代码
本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/578753c0c9da73584b025875 0.引子 话说我们做程序员的,都 ...
- 如果选择构建ui界面方式,手写代码,xib和StoryBoard间的博弈
代码手写UI这种方法经常被学院派的极客或者依赖多人合作的大型项目大规模使用. 大型多人合作项目使用代码构建UI,主要是看中纯代码在版本管理时的优势,检查追踪改动以及进行代码合并相对容易一些. 另外,代 ...
- Delphi/C#之父首次访华:55岁了 每天都写代码
Delphi.C#之父Anders Hejlsberg 近日首次访华,并在10月24日和27日参加了两场见面会,分享了他目前领导开发的TypeScript项目,并与国内前端开发者近距离交流.本文就为读 ...
- .netER的未来路,关于基础是否重要和应该自己手写代码吗?
http://www.cnblogs.com/onepiece_wang/p/5558341.html#!comments 引用"基础知识的学习,一开始可能是背书,但是在后续若干年的工作过程 ...
- Java面试题:写代码使得分别出现StackOverflowError和OutOfMemoryError
转载自:http://www.cnblogs.com/xudong-bupt/p/3360206.html 今天做了个笔试,这是其中的一道题目:写代码使得分别出现StackOverflowError和 ...
- 用css以写代码形式画一个皮卡丘
我的个人网站是通过写代码的形式来形成一个网站的,前一阵子在某个大神的github上看到他用写代码的形式来完成一个皮卡丘,于是心血来潮花了半个小时,也完成了一个作品. 这其中涉及到的知识点也不是很复杂, ...
随机推荐
- PowerBI_一分钟学会计算门店开业前3天销售金额_计算列及度量值方法
在某些特殊场景,我们往往需要去计算一些特定的组别的聚合数据 今天,就以计算门店开业前3天的销售情况,来学习一下,利用计算列和DAX度量值,两种快捷计算此类问题的方案. 一:XMIND 二:示例数据 2 ...
- 关于没使用Mybatis 分页,分页sql默认执行count(0) 的问题
之前的Impl 的方法 :selectFromList(String uid, Integer pageNum, Integer pageSize) 之后的Impl 的方法 :selectFromLi ...
- Java中0.2减0.1 结果为什么不是0.1?
double 表示这种类型的数值精度是 float 类型的两倍(有人称之为双精度数值).绝大部 分应用程序都采用double 类型.在很多情况下,float 类型的精度很难满足需求.实际上,只 有很少 ...
- 电商API接口应该如何使用?
从定义上看,API接口是指预先定义的一组规则和协议,允许不同的软件应用之间相互通信和交换数据. 目前,市场中电商行业用到API接口的场景较多,电商API接口则是专门针对电子商务应用场景所提供的API, ...
- GPT 中的函数调用(function call)是什么?
在 OpenAI ChatGPT API 和 Google Gemini API 中我们可以看到函数调用的功能.这个功能是做什么用的?下面大概讲解. 以 Google Gemini API 函数调用 ...
- Java多线程并发编程中并发容器第二篇之List的并发类讲解
Java多线程并发编程中并发容器第二篇之List的并发类讲解 概述 本文我们将详细讲解list对应的并发容器以及用代码来测试ArrayList.vector以及CopyOnWriteArrayList ...
- 啥是Session?
什么是 Session 会话? 1.Session 就一个接口(HttpSession). 2.Session 就是会话.它是用来维护一个客户端和服务器之间关联的一种技术. 3.每个客户端都有自己的一 ...
- .NET 多版本兼容的精美 WinForm UI控件库
前言 有粉丝小伙伴在后台留言咨询有没有WinForm 控件库推荐,现在就给安排上. .NET 平台进行 Windows 应用程序开发的我们来说,找一个既美观又实用的 WinForm UI 控件库至关重 ...
- Mongodb入门1
学如逆水行舟不进则退 | 心似平原走马易放难追 MongoDB是一个NOSQL类型的数据库,关于SQL与NOSQL的区别不是本文的重点,不在此进行记录. MongoDB安装 然后再将MongoDB的安 ...
- Angular 18+ 高级教程 – Memory leak, unsubscribe, onDestroy
何谓 Memory Leak? Angular 是 SPA (Single-page application) 框架,用来开发 SPA. SPA 最大的特点就是它不刷新页面,不刷新就容易造成 memo ...