上篇文章中提到了将日期转化成天数的方法:c语言计算两个日期相差天数,不用循环语句。这篇文章介绍反过来将天数转化成日期的方法,于是可以直接用天数代替日期,只在显示时转化成日期形式。

记天数为days,日期为year年month月day日

求年份

400年一个周期,共146097天;除以146097的余数是100年一个周期,共36524天;余数再除以36524的余数是4年一个周期,共1461天;再除以1461的余数则是每365天一年。于是:

year=1;
year+=days/146097*400;
days%=146097;
year+=days/36524*100;
days%=36524;
year+=days/1461*4;
days%=1461;
year+=days/365;
days%=365;

这个是有误差的,由于闰年是加到2月后面,而不是一年的最后,所以在闰年交替时会出错,比如当days=1460时,求出的year=5。解决方法是将3月1日作为一年的起点。3月1日与次年1月1日相差天数为306天,将计日起点移到0年3月1日,则天数加306天,算完年份后,若天数的余数小于306,则年份因为加了306天而多算了1年,于是再减1。代码如下:

days += 306;
year = 1;
year += days / 146097 * 400;
days %= 146097;
year += days / 36524 * 100;
days %= 36524;
year += days / 1461 * 4;
days %= 1461;
year += days / 365;
days %= 365;
if(days<306){year--;
}

求月和日

用天数的余数计算月份,相当于3月1日的days天后是几月。先算(days+1)天相当于几个月,算出来的结果加2,对12取余,再加1,就是月份。每月天数可以用一个数组表示:

天数

31

30

31

30

31

31

30

31

30

31

31

月份

3月

4月

5月

6月

7月

8月

9月

10月

11月

12月

1月

mon[]={31,30,31,30,31,31,30,31,30,31,31}

根据天数求月份的公式其实是根据月份和日求天数的公式猜出来的。虽然试过用数学方法证明,但是没有成功。

mon数组的前n项和,凑出来的公式为(和上一篇文章里的公式一致):

sum=(n*367+7)/12;

凑出来的天数求月份的公式为:

month=((days+1)*12-8)/367+1;

剩余天数加1就是day日:

day=days-((month-1)*367+7)/12;

刚才的月份是3月起的月份,需要加1模12再加1才是月份。

全部代码:

days += 306;
year = 1;
year += days / 146097 * 400;
days %= 146097;
year += days / 36524 * 100;
days %= 36524;
year += days / 1461 * 4;
days %= 1461;
year += days / 365;
days %= 365;
days -= 306;
if (days < 0) {year--;
}
days++;
month = (days * 12 - 8) / 367;
daysay = days - (month * 367 + 7) / 12;
month = (month + 2) % 12 + 1;

尝试用c++写一个日期类,并调用:

#include<stdio.h>//将计日起点定为1970年1月1日
#define ORIGIN_YEAR 1600
#define OFFSET_DAYS 135141class Date {public:int days;void setdate(int year, int month, int day);void getdate(int&year, int&month, int&day);Date operator + (int days);int operator - (Date date);
};unsigned int getdate(Date date);//date早于ORIGIN_YEAR+1年会出错 int main() {//输入年份,打印当年日历,会溢出1~2天 Date t;unsigned int date;scanf("%u", &date);t.setdate(date, 1, 1);for (int i = 0; i < 367; i++) {date = getdate(t+i);printf("%d年%d月%d日\n", (date >> 16)&0xffff, (date >> 8) & 0xff, date & 0xff);}return 0;
}void Date::setdate(int year, int month, int day) {year-=ORIGIN_YEAR;days =month <= 2 ? ((year - 1) * 365 + (year - 1) / 4 - (year - 1) / 100 + (year - 1) / 400+ (month - 1) * 30 + month * 7 / 12+ day - 1) : ((year) * 365 + (year) / 4 - (year) / 100 + (year) / 400- (13 - month) * 30 - (14 - month) * 7 / 12+ day - 1);days-=OFFSET_DAYS;
}unsigned int getdate(Date date) {int year, month, day;date.getdate(year,month,day);return (year << 16) | (month << 8) | day;
}void Date::getdate(int&year, int&month, int&day) {int d = days + 306+OFFSET_DAYS;year = 1;year += d / 146097 * 400;d %= 146097;year += d / 36524 * 100;d %= 36524;year += d / 1461 * 4;d %= 1461;year += d / 365;d %= 365;if (d < 306) {year--;}year+=ORIGIN_YEAR;d++;month = (d * 12 - 8) / 367 + 1;day = d - ((month - 1) * 367 + 7) / 12;month=(month+1)%12+1;
}Date Date::operator + (int d) {Date r;r.days = days + d;return r;
}int Date::operator - (Date date) {return days - date.days;
}

c语言将元年1月1日起的天数转化成日期,不用循环和数组相关推荐

  1. java把距离1970年 1月1日 的秒数 转换成对应的日期

    java 中把 已知的距离1970年 1月1日 的秒数 转化 为相应的日期 的实现方式 第一种方式: 采用 Date 类的 setTime( Long time ) 方法 public class T ...

  2. c语言求某年某月1日是星期几,蔡勒(Zeller)公式:根据日期推算是星期几

    Zeller's Congruence: w=y + [y/4] + [c/4] - 2c + [26(m+1)/10] + d - 1 公式中的符号含义如下: w:星期: w对7取模得:0-星期日, ...

  3. 2013年10月20日江苏省高校计算机等级考试二级c语言,2012年10月14日江苏省高校计算机等级考试二级C语言上机题(C02)及其解答_张柏雄.doc...

    2012年10月14日江苏省高校计算机等级考试二级C语言上机题(C02)及其解答_张柏雄 [上机题命题评述]2012年10月14日C01套编程试题是求三位数的水仙花数及其反序数分别存入数组a和b.为本 ...

  4. 水仙花亲密数c语言,★2015年3月15日江苏省高校计算机等级考试二级C语言1套上机题(C01)及其解答_张柏雄.doc...

    ★2015年3月15日江苏省高校计算机等级考试二级C语言1套上机题(C01)及其解答_张柏雄 目录 C01(上午8:00-9:10)原题 解答 附录:通用的自编函数 2015春江苏省高校计算机二级C语 ...

  5. C语言——输入年、月、日,输出该日期是当年的第几天,其中区分了闰年和平年

    主要考察了循环和数组的利用,笔者的代码比较冗余,但是简单易懂,方便初学者阅读与理解. 代码如下:用switch嵌套,更易于理解,当然也有改进的缩减代码在后文 #include<stdio.h&g ...

  6. C语言 输入年、月、日判断天数

    题目:任意给出一个年月日,判断是这一年的第几天 如:2012 5 10 是这一年的第131天. 闰年算法:能被4整除且不能被100整除,或者能被400整除. #include<stdio.h&g ...

  7. c语言每轮for循环初始化i,十三.Linux博客-2016年8月18日while、for特殊用法、selet循环与菜单、函数...

    格式说明: 操作 概念 命令 说明及举例 十三.while.for特殊用法.selet循环与菜单.函数 while特殊用法 while循环的特殊用法(遍历文件的每一行): while read lin ...

  8. matlab儒略日转日期,将日期(年、月、日)转换为儒略日编号并返回日期

    我尝试实现两个功能:1)将日期转换为儒略日数;2)将儒略日数转换回日期(年.月和日).我的代码返回的结果是关闭了一天.我不熟悉算法的工作原理,但是如果我使用 Math.Ceiling 朱利安数的工作, ...

  9. java 距离1970年1月1日的秒数 转换成对应现在的日期

    Long ulTimeSecond = 1660789024L; SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm: ...

最新文章

  1. Linux学习第三章
  2. FPGA 控制 FLASH 之 Startup 原语使用相关链接
  3. Python主要智能优化算法库汇总
  4. emq插件开发mysql_EMQ的Mysql插件
  5. 数据揭秘中国女性的薪水普遍比男性低,说好的“同工同酬”呢?
  6. js设置控件的隐藏与显示的两种方法
  7. Simple2D-15(音乐播放器)使用 glfw 库
  8. c 语言程序上机考试系统,计算机二级C语言上机考试操作步骤及流程
  9. “串标围标”,是如何被识破的?
  10. 怎么批量修改文件夹名称?
  11. arccatalog点要素显示不完_利用ArcCatalog 管理地理空间数据库
  12. python人口普查数据显示_如何使用FCC的API在Python中查找人口普查数据块并遍历dict列表?...
  13. 信号与系统(关于流程框图的一个简单问题记录)
  14. MySQL学习笔记(七)视图,触发器,事务,存储过程,函数,流程控制,索引
  15. Caffe_stu03_小训练
  16. MATLAB-APP编程
  17. 递归删除符合条件的目录,文件, kotlin,java
  18. 如何将excel表格导入matlab,将Excel数据导入MATLAB中的方法
  19. Kubernetes开发(4)-webhook 实现拦截请求
  20. 【前端趋势】Vue、Vite作者尤雨溪前端趋势2022主题演讲

热门文章

  1. 5MW风电永磁直驱发电机-1200V直流并网MATLAB仿真模型
  2. 2016-12-15 Nginx 之初学者(一)
  3. 《消防设施操作员(中级检测维修保养)鉴定在线仿真考试系统》(应试版)上线合作!
  4. 基于逻辑回归算法癌症症状预测分析
  5. 优秀web前端工程师必备_优秀的Web工程师的技能和素质
  6. 433MHz(CC1101)与zigbee (CC2530)对比测试
  7. Unique函数的使用方法
  8. 从360看软件产品的大众心理学
  9. AppStore 隐私政策(Privacy policy)
  10. java tick_Java中这段代码的tick为什么不是唯一的?