C语言 日期转时间戳
- 废话先说
- 啥时候开始数?
- 站在2022的肩膀上!
- 一年能“嘀嗒”多少下?
- 言归正传
废话先说
关于用C实现日期转时间戳,面对这样一个很基础的功能,作为一个小白白当然是,先百度,再看CSDN,最后再去知乎逛,看看有没有现成的代码,就拿过来跑一跑,能省很多事,,,,,
本着省事的目的,就找呀,复制过来,测试,找了半天,没有一个能用的,得不偿失了,很烦。。。
那就自己动手吧!
啥时候开始数?
说到时间戳,好像一般默认讲的都是UNIX时间戳,
百度和维基讲的都是,从1970年1月1日(UTC/GMT的午夜) 零点零分零秒 开始数秒!
关于有哥们问,为啥1970-01-01 08:00:00 转出来的 时间戳 是 0 呀 ?
UTC时间和北京时间 都去了解一下吧!
站在2022的肩膀上!
从1970-01-01 起开始数秒 感觉太遥远了
不妨从 2022-01-01 00:00:00 进行新的开始吧。
//定义一个起始时间戳 2022-01-01 00:00:00
#define SPECIALTIMESTAMP 1640966400
过去的已经过去了,从今年开始数,数完了再加上 2022-01-01 00:00:00 这一刻的时间戳,不也就行了嘛
一年能“嘀嗒”多少下?
为此,定义了一些宏
平年一年365天,闰年一年366天!
#define SECONDS_IN_A_MINUTE 60
#define SECONDS_IN_AN_HOUR 60 * SECONDS_IN_A_MINUTE
#define SECONDS_IN_A_DAY 24 * SECONDS_IN_AN_HOUR#define SECONDS_IN_A_COMMON_YEAR 365 * SECONDS_IN_A_DAY
#define SECONDS_IN_A_LEAP_YEAR 366 * SECONDS_IN_A_DAY
百度平年的时候,搜到了一个很难受的结果。。
再看看维基,又来了个公历。。。。
作为一个只关注礼拜天和节假日的小菜鸟,我吐了,#ucking#
简单说一下,
公历是阳历的一种,阳历还包括公历外的其他历法;
农历则是以阳历为主,以阴历为辅的一种方法,严格来讲叫阴阳历;
阳历,太阳历,是以地球围绕太阳公转一周的时间为一年而定的历法,就是阳历;
阴历,太阴历,是根据月球绕地球运行的周期而定的历法;
好吧,再简单一下:看图
言归正传
时间也不早了,日期转时间戳,没啥可说的,就是数数,直接上代码,
#include <stdio.h>typedef struct times
{int Year;int Mon;int Day;int Hour;int Min;int Second;
}Times;#define SECONDS_IN_A_MINUTE 60
#define SECONDS_IN_AN_HOUR 60 * SECONDS_IN_A_MINUTE
#define SECONDS_IN_A_DAY 24 * SECONDS_IN_AN_HOUR#define SECONDS_IN_A_COMMON_YEAR 365 * SECONDS_IN_A_DAY
#define SECONDS_IN_A_LEAP_YEAR 366 * SECONDS_IN_A_DAY//从1970-01-01 08:00:00 起开始数秒
//定义一个起始时间戳 2022-01-01 00:00:00
#define SPECIALTIMESTAMP 1640966400
typedef struct
{int Year;int Mon;int Day;int Hour;int Min;int Second;
}Date;Date specialTime = {2022,01,01,00,00,00
};
//31 : 1 3 5 7 8 10 12 ; 30 : 4 6 9 11
const int daysofmon[] ={0,31 * SECONDS_IN_A_DAY,(28 + 31) * SECONDS_IN_A_DAY,(31 + 28 + 31) * SECONDS_IN_A_DAY,(30 + 31 + 28 + 31 ) * SECONDS_IN_A_DAY,(31 + 30 + 31 + 28 + 31) * SECONDS_IN_A_DAY,(30 + 31 + 30 + 31 + 28 + 31) * SECONDS_IN_A_DAY,(31 + 30 + 31 + 30 + 31 + 28 + 31) * SECONDS_IN_A_DAY,(31 + 31 + 30 + 31 + 30 + 31 + 28 + 31) * SECONDS_IN_A_DAY,(30 + 31 + 31 + 30 + 31 + 30 + 31 + 28 + 31) * SECONDS_IN_A_DAY,(31 + 30 + 31 + 31 + 30 + 31 + 30 + 31 + 28 + 31) * SECONDS_IN_A_DAY,(30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31 + 28 + 31) * SECONDS_IN_A_DAY};
const int _daysofmon[] ={0,31 * SECONDS_IN_A_DAY,(29 + 31) * SECONDS_IN_A_DAY,(31 + 29 + 31) * SECONDS_IN_A_DAY,(30 + 31 + 29 + 31 ) * SECONDS_IN_A_DAY,(31 + 30 + 31 + 29 + 31) * SECONDS_IN_A_DAY,(30 + 31 + 30 + 31 + 29 + 31) * SECONDS_IN_A_DAY,(31 + 30 + 31 + 30 + 31 + 29 + 31) * SECONDS_IN_A_DAY,(31 + 31 + 30 + 31 + 30 + 31 + 29 + 31) * SECONDS_IN_A_DAY,(30 + 31 + 31 + 30 + 31 + 30 + 31 + 29 + 31) * SECONDS_IN_A_DAY,(31 + 30 + 31 + 31 + 30 + 31 + 30 + 31 + 29 + 31) * SECONDS_IN_A_DAY,(30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31 + 29 + 31) * SECONDS_IN_A_DAY
};
//日期转时间戳
size_t Date2timeStamp(Date standardTime){//需要计算 传进来的 standardTime 比 specialTime 大多少秒size_t differenceValue = 0; //定义这个差值,单位为秒int leapYears = 0;if((standardTime.Year < specialTime.Year) || (standardTime.Year > 2099))//不允许 specialTime.Year 之前的时间传进来{printf("The year %d is not supported\r\n",standardTime.Year);return -1;}if((standardTime.Mon < 1) || (standardTime.Mon > 12))//不允许 无效的mon 传入{printf("The month %.2d is out of line\r\n",standardTime.Mon);return -1;}if((standardTime.Day < 1) || (standardTime.Day > 31))//不允许 无效的day 传入{printf("The day %.2d is out of line\r\n",standardTime.Day);return -1;}if((standardTime.Hour < 0) || (standardTime.Hour > 24))//不允许 无效的hour 传入{printf("The hour %.2d is out of line\r\n",standardTime.Hour);return -1;}if((standardTime.Min < 0) || (standardTime.Min > 59))//不允许 无效的min 传入{printf("The min %.2d is out of line\r\n",standardTime.Min);return -1;}if((standardTime.Second < 0) || (standardTime.Second > 59))//不允许 无效的sec 传入{printf("The sec %.2d is out of line\r\n",standardTime.Second);return -1;}//从 specialTime 开始,到 standardTime 的前一年之间有过少个闰年for(int i = specialTime.Year; i < standardTime.Year; i++){if((i % 4 == 0 && i % 100 != 0) || (i % 400 == 0)){leapYears++;}}differenceValue += (SECONDS_IN_A_LEAP_YEAR * leapYears +SECONDS_IN_A_COMMON_YEAR * (standardTime.Year - specialTime.Year - leapYears));//判断 是不是闰年if((standardTime.Year % 4 == 0 && standardTime.Year % 100 != 0) || (standardTime.Year % 400 == 0)) {differenceValue += (_daysofmon[standardTime.Mon - 1] +(standardTime.Day - 1) * SECONDS_IN_A_DAY +(standardTime.Hour ) * SECONDS_IN_AN_HOUR +(standardTime.Min ) * SECONDS_IN_A_MINUTE +standardTime.Second);}else{differenceValue += (daysofmon[standardTime.Mon - 1] +(standardTime.Day - 1) * SECONDS_IN_A_DAY +(standardTime.Hour) * SECONDS_IN_AN_HOUR +(standardTime.Min) * SECONDS_IN_A_MINUTE +standardTime.Second);}return differenceValue += SPECIALTIMESTAMP;
}int main(){//2022-09-16 22:47:24 1663339644Date Time = {2022,9, //不要填09和08,会判定成8进制17,0,8,8};printf("%lld\r\n",Date2timeStamp(Time));return 0;
}
简单测试过了,应该能用个几十年的。