4月21日正邦公布重整延期,短线最大的退市风险解除,那几天加班加昏了头,楼主看了公告,几分钟之内就决定买入,一早红盘买入,然后被杀的稀里哗啦。。。
原来,买入时完全忘了即将公布年报,然后披星戴月。。。
为啥会忘呢,因为最近工作太忙,尤其是一个浪Chao软件开发的一个项目尤其恼人!浪C软件的码农简直让我哭笑不得,很多很简单的东西居然都搞不定,有时候真把我气的笑了。。。
举个简单的例子,设备定期检测,检测合格要刷新有效期,公式是:
有效日期=检测日期+检测周期(月)-1天;
例如今天2023-4-29检测,检测周期是12个月,则有效日期=检测日期+12个月-1天=2024-04-28;
检测周期有6个月、12个月、24个月、60个月不等。
逻辑很清楚吧。
且看浪C软件的码农是怎么干的。。。
回合一:
浪C软件的码农写完代码,我一测试,发现有效日期跟理论值差了五六天的样子,就问他是怎么计算的,他说是将检测周期(月)乘以30,加上检测日期再减一天,就得到了有效日期,我说这样肯定不对啊,这样一年只有360天了,差了好几天!
我说在excel中很简单啊,直接加月份就可以了。
浪C软件的码农答曰,在浪C的软件中没有封装类似的功能,不能直接调用,只能自己写代码。
那就只好让他再改下。
回合二:
浪C软件的码农改完代码,这次我学乖了,我先问他,是怎么计算的,他说是用检测周期(月)除以12,再乘以365,加上检测日期,就得到了有效日期。我说这样遇到闰年肯定就有问题啊,一年366天,有效日期就差了一天,而且没有办法修改,肯定不行啊!
回合三:
回合二不是差了一天没有办法修改嘛,这次浪C软件的码农学乖了,直接用检测日期+检测周期(天)-1天,检测周期(天)-1天设置默认值,检测周期如果是一年,那默认值就设置为365-1=364天。如果闰年怎么办,那就需要手动修改为365;到了闰年的第二年,又需要将365改回364。如果检测周期如果是6个月,由于需要考虑闰年,备选值就有180/181/182/183/184。。。
我彻底崩溃了。。。浪C软件这么大的公司,做的软件怎么这么水!!!
由于没有想到好的解决思路,这个问题目前暂时放一边了,但是如果后续如果没有好的办法,很可能就这样了。
五一外面人太多,加上最近比较忙,我没有出去玩,先休息下。
抽空又想了一下这个问题,由于闰年的影响,还有周期6个月的起始时间要受到大月31天、小月30天的影响,貌似确实还挺复杂的。
不过这应该是个会经常遇到的问题,只好请教下各位高手,有没有好的算法或者代码,如果能够提供有效信息的金币答谢,如果能够完美解决的话,大量金币答谢。
先行谢过了~~
2
赞同来自: seancai110 、dingo49
C语言中对这种计算是比较麻烦,所以很多公司会对这些规则做自己的加工,做好通用函数。如果通用的函数没人写好,有个变通的方式,就是如果连数据库了,可以直接调用数据库的add_months函数,不需要自己去计算闰年这些,相对比较简单。
3
csfires - 毛顿的整活空间
赞同来自: tianshen1994 、时间的味道 、dingo49
想了下,最简便的方法貌似是把年月日拆出来去做加加减减最简单,譬如检测日期为2022-02-28,有效期1年1月0日,则为2023年3月28日,应当是较为简单的实现方式了。
浪C有好几个子公司,都不是一批人,A股的几家,有软件有硬件,还有港股的。
const int days_of_month[] = {31, 28, 31, 30, 31, 30,
31, 31, 30, 31, 30, 31};
int main(){
int year, month, day; // 检测日期的年月日
int test_period = 12; // 检测周期
int days_of_test_period; // 检测周期的天数
// 获取检测日期的年月日
printf("请输入检测日期(格式为YYYY-MM-DD):");
scanf("%d-%d-%d", &year, &month, &day);
// 获取检测周期的天数
switch(test_period){
case 6:
days_of_test_period = 180;
break;
case 12:
days_of_test_period = 365;
break;
case 24:
days_of_test_period = 730;
break;
case 60:
days_of_test_period = 1825;
break;
default:
printf("无效的检测周期!\n");
return -1;
}
// 计算有效日期
year += (month + test_period - 1) / 12;
month = (month + test_period - 1) % 12 + 1;
day += days_of_test_period;
while(day > days_of_month[month - 1]){
day -= days_of_month[month - 1];
month++;
if(month == 13){
year++;
month = 1;
}
}
// 输出结果
printf("检测日期:%d-%02d-%02d\n", year, month, day);
printf("检测周期:%d个月\n", test_period);
printf("有效日期:%d-%02d-%02d\n", year, month, day - 1);
return 0;
}
试了一下gpt给我的答案,用C写起来确实很麻烦。估计对方的实现方式比较老了,考虑调用其他可以直接实现的库吧。
浪C有好几个子公司,都不是一批人,A股的几家,有软件有硬件,还有港股的。
include <stdio.h>
include <stdlib.h>
include <time.h>
// 定义月份天数的数组,根据实际情况进行调整const int days_of_month[] = {31, 28, 31, 30, 31, 30,
31, 31, 30, 31, 30, 31};
int main(){
int year, month, day; // 检测日期的年月日
int test_period = 12; // 检测周期
int days_of_test_period; // 检测周期的天数
// 获取检测日期的年月日
printf("请输入检测日期(格式为YYYY-MM-DD):");
scanf("%d-%d-%d", &year, &month, &day);
// 获取检测周期的天数
switch(test_period){
case 6:
days_of_test_period = 180;
break;
case 12:
days_of_test_period = 365;
break;
case 24:
days_of_test_period = 730;
break;
case 60:
days_of_test_period = 1825;
break;
default:
printf("无效的检测周期!\n");
return -1;
}
// 计算有效日期
year += (month + test_period - 1) / 12;
month = (month + test_period - 1) % 12 + 1;
day += days_of_test_period;
while(day > days_of_month[month - 1]){
day -= days_of_month[month - 1];
month++;
if(month == 13){
year++;
month = 1;
}
}
// 输出结果
printf("检测日期:%d-%02d-%02d\n", year, month, day);
printf("检测周期:%d个月\n", test_period);
printf("有效日期:%d-%02d-%02d\n", year, month, day - 1);
return 0;
}
试了一下gpt给我的答案,用C写起来确实很麻烦。估计对方的实现方式比较老了,考虑调用其他可以直接实现的库吧。
这里采用了与前一个代码不同的方式,将输入的日期的年月日拆分出来存储,并根据检测周期的值计算出对应的天数。在计算有效日期时,先根据检测周期计算年份和月份,再根据每个月份的天数计算出对应的日期。需要注意的是,这里假设每个月份的天数是固定的,因此采用了一个数组来存储。如果实际情况中存在润年等特殊情况,需要进行相应的调整。另外,在计算结果时需要将最后一天减去,才能得到正确的有效日期。
0
如果需求文档上明确写了
有效日期=检测日期 +检测周期(月)-1天。
首先要承认,这不是一个可加的数学公式,包括接下来那个例子并不具代表性,也就意味着,深究起来根本就无法实施。
假如今天是1月31号,1个月有效期到期日是哪天?难道非要程序员写成2月30号才是符合需求的?(虽然眼下的周期没1个月的,那6个月周期的万一赶上2月30呢)。
如果程序员完成了实施,且没有明显bug,其实他已经想到第八层了,我相信,这个问题,需求方可能都没想清楚,也可能想清楚了没说清楚。
对方技术如何,还是要看具体事儿。精密车床造的公差大,那是技术问题;火棍撅的公差大能说明什么呢
有效日期=检测日期 +检测周期(月)-1天。
首先要承认,这不是一个可加的数学公式,包括接下来那个例子并不具代表性,也就意味着,深究起来根本就无法实施。
假如今天是1月31号,1个月有效期到期日是哪天?难道非要程序员写成2月30号才是符合需求的?(虽然眼下的周期没1个月的,那6个月周期的万一赶上2月30呢)。
如果程序员完成了实施,且没有明显bug,其实他已经想到第八层了,我相信,这个问题,需求方可能都没想清楚,也可能想清楚了没说清楚。
对方技术如何,还是要看具体事儿。精密车床造的公差大,那是技术问题;火棍撅的公差大能说明什么呢
1
赞同来自: dingo49
先按检测周期把月数和年数加上去,具体就是用检测周期月数整除12,把商加在年数上,余数加在月数上,如果月数超过12就往年数进1。得到日期D1。
然后检验D1,如果是4、6、9、11月的话,再检验是不是31号,是就退到30号;如果是2月份的话,再检验是不是大于等于29号,如果是再检验是不是闰年,如果是闰年就退到29号,不是闰年就退到28号。得到日期D2。判断闰年的规则,请自行百度。
然后在D2上减去一天。如果D2是1号的话,那就月数减1(如果减完后月数等于0,就要往年数退1),日数设为31,然后重复第二步的检验。
验收测试要遍历所有月份的首尾日,特别是起始日是2月29号、1月1号,起始日是8月29,30,31号且检验周期为六个月,到期日是闰年的2月27号。
然后检验D1,如果是4、6、9、11月的话,再检验是不是31号,是就退到30号;如果是2月份的话,再检验是不是大于等于29号,如果是再检验是不是闰年,如果是闰年就退到29号,不是闰年就退到28号。得到日期D2。判断闰年的规则,请自行百度。
然后在D2上减去一天。如果D2是1号的话,那就月数减1(如果减完后月数等于0,就要往年数退1),日数设为31,然后重复第二步的检验。
验收测试要遍历所有月份的首尾日,特别是起始日是2月29号、1月1号,起始日是8月29,30,31号且检验周期为六个月,到期日是闰年的2月27号。
0
理论上,肯定有办法实现楼主诉求的。
但话说回来,除非像可转债到期日期,必须精确到日。像巡检,不知道定在12个月和360天,或者365天的差别在哪里,是精确计算的,365天满足3sigma法则而366天就不满足?这就像拉个灯泡线,合同上要9999 2.5方的铜线,人家偷懒用999的代替,按说也不会有什么问题,但9999可是费工夫去了,虽然我不是乙方,但做自己的事有时候也偷懒不是吗,比如做饭放盐,差不多就行,也没精确到多少水多少盐
但话说回来,除非像可转债到期日期,必须精确到日。像巡检,不知道定在12个月和360天,或者365天的差别在哪里,是精确计算的,365天满足3sigma法则而366天就不满足?这就像拉个灯泡线,合同上要9999 2.5方的铜线,人家偷懒用999的代替,按说也不会有什么问题,但9999可是费工夫去了,虽然我不是乙方,但做自己的事有时候也偷懒不是吗,比如做饭放盐,差不多就行,也没精确到多少水多少盐
6
赞同来自: seancai110 、csfires 、hugo 、青火 、pppppp 、更多 »
1.如果时间精度不高,为啥不能用30* N来计算月份。
2.如果时间精度高,并且要跟系统时间匹配,那么调用系统时间mktime、gmtime、localtime就好了。
3.如果系统时间没联网,没法自动网络更新,只用linux内核的时间计算,精度也是够的。内置了近些年的闰年、润秒、处理,也是足够的。
4.如果是非linux内核,还不行,最后一招,clone linux内核的日期计算代码,然后烧进你的rom。
get不到难点在哪?一般1、2/3就能解决。极端没内核的用4。超出范围当我没说。
顺便说一句,大道至简,不要把问题想象那么复杂,也不要重复造轮子。
你能碰到的问题,别人早就解决了。
2.如果时间精度高,并且要跟系统时间匹配,那么调用系统时间mktime、gmtime、localtime就好了。
3.如果系统时间没联网,没法自动网络更新,只用linux内核的时间计算,精度也是够的。内置了近些年的闰年、润秒、处理,也是足够的。
4.如果是非linux内核,还不行,最后一招,clone linux内核的日期计算代码,然后烧进你的rom。
get不到难点在哪?一般1、2/3就能解决。极端没内核的用4。超出范围当我没说。
顺便说一句,大道至简,不要把问题想象那么复杂,也不要重复造轮子。
你能碰到的问题,别人早就解决了。
2
java 也可以
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
public class Main {
public static void main(String[] args) {
// 假设设备的检测周期是 12 个月
int checkPeriod = 12;
// 假设今天是 2023-04-29,进行设备检测
LocalDate checkDate = LocalDate.of(2023, 4, 29);
// 计算新的有效日期
LocalDate newValidDate = validDate.plus(checkPeriod, ChronoUnit.MONTHS);
// 减去一天以得到正确的有效日期
newValidDate = newValidDate.minusDays(1);
// 输出新的有效日期
System.out.println(newValidDate.toString());
}
}
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
public class Main {
public static void main(String[] args) {
// 假设设备的检测周期是 12 个月
int checkPeriod = 12;
// 假设今天是 2023-04-29,进行设备检测
LocalDate checkDate = LocalDate.of(2023, 4, 29);
// 计算新的有效日期
LocalDate newValidDate = validDate.plus(checkPeriod, ChronoUnit.MONTHS);
// 减去一天以得到正确的有效日期
newValidDate = newValidDate.minusDays(1);
// 输出新的有效日期
System.out.println(newValidDate.toString());
}
}