首页 > 其他分享 >线上问题记录:因闰年导致的数据查询错误

线上问题记录:因闰年导致的数据查询错误

时间:2024-03-04 14:14:44浏览次数:14  
标签:年份 闰年 29 接口 查询 线上 now

在今天的生产环境测试中,测试发现几个数据页面显示为空白。反馈给开发后,通过查看相关接口和后台日志,发现某个查询 SQL 出现了问题,错误信息如下:

image.png

此查询功能的前后端近期没有改动,排除是改动造成的。从日志上看,导致错误的原因是无效的时间查询参数 20230229。结合业务分析,我们需要查询最近1年的数据,因为今年是闰年,2月有29天,而去年2023年的2月份只有28天,没有29号,导致 20230229 为无效参数,从而查询失败。这个问题只在2月29日出现,过了这天就暂时不会出现。

闰年的2月有29天,而非闰年的2月只有28天。这是因为闰年的定义是1年有366天,相较于平年的365天,多出来的1天被添加到2月的29号。这额外的一天是为了与地球绕太阳运动周期相匹配,确保日历和季节的协调。闰年是按照一定的规则确定的,通常是能够被4整除的年份,但如果该年份能够被100整除却不能被400整除,那么该年份就不是闰年。

在代码中查找了下,发现在查最近1年、最近3年等查询场景,都是这样的处理方法,具体简化如下:

CTime now = CTime::CurrentTime();
start.Format("%04d%02d%02d", now.GetYear()-1, now.GetMonth(), now.GetDay());

这种做法,在当天为闰2月最后一天,且同时使用年、月和日时,会触发问题,其他时间则不会触发。找到了问题的根源,解决方法也就随之而出。为了提高解决方法的适用范围,在时间类中新增接口 ChangeYear(int yearOffset),表示将年份偏移yearOffset年,支持向前/向后移动,考虑闰年影响。使用新接口来修改的实例代码如下:

CTime now = CTime::CurrentTime();
now.ChangeYear(-1);		// 传-1表示往前推1年
start.Format("%04d%02d%02d", now.GetYear(), now.GetMonth(), now.GetDay());

同时,为了防止类似错误再次发生,在 GetYear()、GetMonth() 接口上,增加注释,表示对年份、月份进行加减时,要注意有效性,推荐使用 ChangeYear、ChangeMoth等接口。此外,如果仅仅使用年份,没用到月份和日期,减1的做法是可以的,一旦使用到月和日,就不能简单减1了。考虑到查询场景可能由不同人来维护,保证时间处理的一致性,统一使用 ChangeYear 等接口更好。

小结

查询不同时间范围的数据是常见功能,这个闰2月的问题给我们提了个醒,获取数据查询起止时间要用正确的方法,不能简单地靠加减固定数值得到新的查询时间。软件的严谨性就是在这一个个边边角角中完善建立起来的,希望各位读者有则改之无则加勉。

标签:年份,闰年,29,接口,查询,线上,now
From: https://www.cnblogs.com/cherishui/p/18051689

相关文章

  • dremio 查询执行阶段简单说明
    内容实际来自官方架构介绍,图以前也在博客中放过,现在进行说明下参考执行图阶段说明参考上图,dremio将执行分为可4个阶段客户端通过jdbc,odbc,rest提交查询到协调节点计划阶段 此阶段可以细分3步 a.协调节点解析查询为dremio的通用关系模型 b.协调节点基于数据源的统计信......
  • MySQL查看执行慢的SQL语句(慢查询)
    更新日志点击查看2024年3月4日发布。慢查询日志查看执行慢的SQL语句,需要先开启慢查询日志。MySQL的慢查询日志,记录在MySQL中响应时间超过阀值的语句(具体指运行时间超过long_query_time值的SQL。long_query_time的默认值为10,意思是运行10秒以上(不含10秒)的语句)。......
  • sql常见四种连接查询
    原文链接:https://learn.microsoft.com/zh-CN/sql/relational-databases/performance/joins?view=aps-pdw-2016-au7         https://www.cnblogs.com/alone-striver/p/9055078.html1、内部联接  INNERJOIN2、左外部联接  LEFT[OUTER]JOIN3、右......
  • 【PG】查询 正在vacuum对象的(持续)时间
    --https://dataegret.com/2017/10/deep-dive-into-postgres-stats-pg_stat_progress_vacuum/SELECTp.pid,now()-a.xact_startASduration,coalesce(wait_event_type||'.'||wait_event,'f')ASwaiting,CASEWHENa.query~*'^autovacuum......
  • 对于需要实时处理的代码语句 就用定时器中断模式,实现多线程模式,建议不要用查询模式。
    对于需要实时处理的代码语句就用定时器中断模式,实现多线程模式,建议不要用查询模式。 示例代码1:查看代码#include"delay.h"#include"sysInt.h"#include"intrins.h"charSMGDuan[]={0x5B,0x3F,0x5B,0x66, 0x40,0x40, 0x3F,0x3F}; //2024--MMcharsegDuan[]={0x3F,0......
  • 一次线上redis慢的排查过程,发现redis根本不慢
    缓存应用场景:对话系统中,用redis来存储用户对话的上下文,用户每次说话将用户对话的上下文带给大模型进行推理,然后返回给用户回答该对话系统用在电话场景,对响应速度要求较高。代码中自己对redis的耗时进行了记录超过50毫秒报警start_time=time.time()dialogueSession=dial......
  • PostgreSQL、KingBase 数据库 ORDER BY LIMIT 查询缓慢案例
    好久没写博客了,最近从人大金仓离职了,新公司入职了蚂蚁集团,正在全力学习 OcenaBase 数据库的体系结构中。以后分享的案例知识基本上都是以OcenaBase分布式数据库为主了,呦西。......
  • dremio jobprofile查询简单说明
    dremio提供了方便的jobprofile能力,可以进行共享以及分析dremio查询的性能问题,以下是关于jobprofile下载功能的简单说明下载处理SupportResource.java@POST@Path("download")@Consumes(MediaType.APPLICATION_JSON)publicResponsedownloadData(......
  • mybatisPlus分页查询
    配置类:packagecom.oep.backend.config;importcom.baomidou.mybatisplus.annotation.DbType;importcom.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;importcom.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;importo......
  • delphi 新版内存表 FDMemTable使用SQL查询(02)
    fdLocalSql可以对fdMemTable内存表进行SQL查询(可以对多个fdMemTable内存表进行联表查询哦),fdLocalSql使用SQLITE引擎,而FIREDAC驱动SQLITE,连SQLITE驱动DLL都不需要附带的。1)设置fdConnection为SQLITE,LoginPrompt设为False; 2)设置TfdLocalSQL 的Connection 3)拖一个FDMemTa......