不要网上乱拷贝代码了!一段网上找的代码把公司服务器崩了!

云栖号资讯:【点击查看更多行业资讯】
在这里您可以找到不同行业的第一手的上云资讯,还在等什么,快来!

碰到一个需求,给服某些要求的玩家的发送道具] w P n I w R奖励,奖励的数量根据离线的天数计算。
这个需求实现起来很简单,只需要在玩家上线的时候计算上s G ]次离线时间和当前时间间隔的天数,然后根据策划的算法,计算出道具种类与数量,发一封邮件给玩家就可以了。
计算两个时间间隔天数的函数没有现成的,自己又懒得写,就上谷歌搜了下,选了第一条结果,代码如下

public static int differentDays(Date date1,Date date2)
{
Calendar cal1 = Calendar.getInh 6 e % Rstance();
cal1.setTime(date1w M T)~ P D o Y;
Calendar cal% H ~ ! H L 62 = Calendar.getInstance();
cal2.setTime(date2);
int day1= cal1.get(Cale. = % ; +  g * _ndar.DAY_OF_YEAR);
int day2 = cal2.get(Calendar.DAY_OF_YEAR);
int year1 = cal1.get(Calendar.YEAR);
int year2 = calZ  D A _ k X2.get(Calendar.YEAR);
if(yec N 0 w Y H ` 0 ,ar1 != year2)   //同一年7 f | ] *
{
int timeDistanF H FcD ! 6 6 Ce = 0 ;
for(in]  n e [ zt i = year1 ; i &/  Flt; year2 ; i ++)
{
if(i%4==0 && i%1o x k ^ 5 2 Z00!=0 || i%400==0)    //闰年( . j n ` 6 = N e
{
timeDistance += 366;
}
else    //不是闰年
{
timeDistance += 365;
}
}
re^ 6 o d Iturn timeDistance + (day2-dq ( U 5ay1) ;
}
else    //不同年
{
System.out.println("判断dayv % S W P Q H s2 - day1 : " + (day2-d2 ` 7 T }ay1));
return day2-~ ~ Qday1;
}
}

代码来源:https://www.cnblogs.( / R A b N J fcom/0201zcr/p/5000977.html

把代码复制到项目里,调试下,发现没问题就直接用了,毕竟谷歌结果第一名,放心。

这段代码跑了几个月一直没7 Z J Q P问题,但是到了2020-1-1日那天,有玩家反馈收? # C Y / C U到了几百封奖励邮件,高兴坏了,但是出于对游戏的热爱,还是通知了运营人员。

运营把bug反馈到服务器这边后我开始排查,百思不得其解的是最近E X C ? x Q x r几天都没Z O U Z # y j u ~有更新服务器, 而前几天服务器都稳稳地,怎么突然就出BUG了呢E 5 5 - A j

接下来就是分析玩家数据,结合代码逻辑确定问题所在,最终根据BUG的表现排除了所有可能性后,发现唯一可能出问题的地方就是那个网上复制过来的计算天数差的函数

根据调试发现,这个函数在两个日期参数是不同的年份并且第一个日期大于第二个日期的时候,会返回一个错误的结果

比如

dH p _ K :ifferentDays("2020-1-1","2019-12-25")

理论上这么调用正确的z = P ? @ ? q结果是 -7,但是因为函数有bug,调用结果是 358

于是本来不用发奖励,因为这种特殊情况一下子发出去358份,严重影响了游戏某类道具的平衡性。

至于补救方式就是统计名单,把发出去但还没有用x m c q掉的道具回收,用掉的就当福利,然后再发公告道歉,再送些其他物品弥补。& 0 J y @ L &

也幸好补救的e o l * g及时,要是这些道具收不回来,游戏运营的策略都要大变了,我特么肯定没好果子吃了。

3 ` 3 a , j ] T以千万别在网上复制来路不明的代码乱用,如* u - a *果真的要用,必须t d |反复测试,否则哪一天突然暴雷有Y @ 7 0 Q + n {你受的。

改用Java8的日期库修复了BUG

  public static int differentDays(Date date1, Date dat` i : L u Ae2) {
if (date1 == null || date2 == null) {
throw new RuntimeExcepl  ] YtiV H O 1 [ r _ C non("日期不| t W $ ^能为空");
}
LocalDate local[ w e D  * O y 2Date1 = date2LocalDate(date1);
LocalDate localDate2 = date2LocalDate(date2);
return Generic.long2int(lo` # # }calDate1.until(localDate2, ChronoUnit.DAYS));
}
pubM Q # alic static LocalDate date2LocalDate(Date date) {
Instant instant = date.toInstant();
ZoneIdi & m k zoneId = ZoneId.systemDefault();
LocalDate localDateD t R A U } t = instant.atZone(zoneId).toLocalDate();
return localDate;
}

【云栖号在线课堂】每天都有产品技术专家分享!
课程地址:https://yqh.aliyun.com/zhibo

立即加入社群,与专家面对- c x u C面,2 X { ` % ?及时了解课程最新动态!
【云栖号在线) K O U 9 =课堂 社群】https://c.tb.cn/F3.Z8gvnK

原文发布时间:| } J S %2020-05-22
本文作者:陈宏鸿
本文来自:“互联网架构师 微信公众号”,了解相关信息可以关注“互联网架构师”