C语言中的时间

C语言中的时间



高斯日记:

    大数学家高斯有个好习惯:无论如何都要记日记。

    他的日记有个与众不同的地方,他从不注明年月日,而是用一个整数代替,比如:4210

    后来人们知道,那个整数就是日期,它表示那一天是高斯出生后的第几天。这或许也是个好习惯,它时时刻刻提醒着主人:日子又过去一天,还有多少时光可以用于浪费呢?

    高斯出生于:1777年4月30日。
    
    在高斯发现的一个重要定理的日记上标注着:5343,因此可算出那天是:1791年12月15日。

    高斯获得博士学位的那天日记上标着:8113   

    请你算出高斯获得博士学位的年月日。

提交答案的格式是:yyyy-mm-dd, 例如:1980-03-21


看到这个题目,我只想吐槽.....这真是好习(hen)惯(tai)啊.....= W =


关于tm结构体:

在标准C/C++中,我们可通过tm结构来获得日期和时间,tm结构在time.h中的定义如下:
#ifndef _TM_DEFINED
struct tm {
int tm_sec; /* 秒–取值区间为[0,59] */
int tm_min; /* 分 - 取值区间为[0,59] */
int tm_hour; /* 时 - 取值区间为[0,23] */
int tm_mday; /* 一个月中的日期 - 取值区间为[1,31] */
int tm_mon; /* 月份(从一月开始,0代表一月) - 取值区间为[0,11] */
int tm_year; /* 年份,其值从1900开始 */
int tm_wday; /* 星期–取值区间为[0,6],其中0代表星期天,1代表星期一,以此类推 */
int tm_yday; /* 从每年的1月1日开始的天数–取值区间为[0,365],其中0代表1月1日,1代表1月2日,以此类推 */
int tm_isdst; /* 夏令时标识符,实行夏令时的时候,tm_isdst为正。不实行夏令时的进候,tm_isdst为0;不了解情况时,tm_isdst()为负。*/
long int tm_gmtoff; /*指定了日期变更线东面时区中UTC东部时区正秒数或UTC西部时区的负秒数*/
const char *tm_zone; /*当前时区的名字(与环境变量TZ有关)*/
};


关于time_t:

包含文件:
#ifndef __TIME_T
#define __TIME_T      /*  避免重复定义  time_t */
typedef long      time_t;    /*  时间值 time_t 为长整型的别名*/
#endif
 
既然time_t实际上是长整型,到未来的某一天, 从一个时间点(一般是1970年1月1日0时0分0秒)到那时的秒数(即日历时间) ,超出了长整形所能表示的数的范围怎么办?对time_t数据类型的值来说,它所表示的时间不能晚于2038年1月18日19时14分07秒。为了能够表示更久远的时间,一些编译器厂商引入了64位甚至更长的整形数来保存日历时间。比如 微软在Visual C++中采用了__time64_t数据类型来保存日历时间,并通过_time64()函数来获得日历时间 (而不是通过使用32位字的time()函数),这样就可以通过该数据类型保存3001年1月1日0时0分0秒(不包括该时间点)之前的时间。
 
在time.h头文件中,我们还可以看到一些函数,它们都是以time_t为参数类型或返回值类型的函数:
 
double difftime(time_t time1, time_t time0);
time_t mktime(struct tm * timeptr);
time_t time(time_t * timer);
char * asctime(const struct tm * timeptr);
char * ctime(const time_t *timer);
 
此外,time.h还提供了两种不同的函数将日历时间(一个用time_t表示的整数)转换为我们平时看到的把年月日时分秒分开显示的时间格式tm:
 
struct tm * gmtime(const time_t *timer);                                          
struct tm * localtime(const time_t * timer);
 
通过查阅MSDN,我们可以知道Microsoft C/C++ 7.0中时间点的值(time_t对象的值)是从1899年12月31日0时0分0秒到该时间点所经过的秒数,而其它各种版本的Microsoft C/C++和所有不同版本的Visual C++都是计算的从1970年1月1日0时0分0秒到该时间点所经过的秒数。
     (转载于http://www.eefocus.com/xuefu2009/blog/10-03/187348_f456a.html)


实例:

0、关于 time_t 类型:

time_t t = time(NULL);
printf("time: %d\n", t);

可取当前时间。


1、关于 gmtime

包含头文件:time.h
原型:struct tm *gmtime(const time_t *time);
功能:把日期和时间转换为格林威治(GMT)时间的函数。将参数time 所指的time_t 结构中的信息转换成真实世界所使用的时间日期表示方法,然后将结果由结构tm返回。
struct tm*  t1 = gmtime(&t);
    printf("%d %d %d %d:%d:%d\n", t1->tm_year+1900, t1->tm_mon+1, t1->tm_mday, t1->tm_hour, t1->tm_min, t1->tm_sec);

2、 关于 localtime
功 能: 把从1970-1-1零点零分到当前时间系统所偏移的秒数时间转换为本地时间,而gmtime函数转换后的时间没有经过时区变换,是UTC时间 。
说明:此函数获得的tm结构体的时间是日历时间。
用 法: struct tm *localtime(const time_t *clock);
返回值:返回指向tm 结构体的指针.tm结构体是time.h中定义的用于分别存储时间的各个量(年月日等)的结构体.
struct tm*  t2 = localtime(&t);
    printf("%d %d %d %d:%d:%d\n", t2->tm_year+1900, t2->tm_mon+1, t2->tm_mday,t2->tm_hour, t2->tm_min, t2->tm_sec);

3、关于mktime
功能:将时间转换为自1970年1月1日以来失去时间的秒数,发生错误时返回-1.
表头文件:#include <time.h>
函数定义:time_t mktime(struct tm * timeptr);
函数说明:mktime()用来将参数timeptr所指的tm结构数据转换成从公元1970年1月1日0时0分0 秒算起至今的UTC时间所经过的秒数。
返回值:    返回经过的秒数。

// 计算时间差 1997年7月1日 到 今天过去了多少天? 
    struct tm tm1;
	tm1.tm_year = 1997 - 1900;
	tm1.tm_mon = 7 - 1;
	tm1.tm_mday = 1;
	tm1.tm_hour = 12;
	tm1.tm_min = 0;
	tm1.tm_sec = 0;
	int delta = (time(NULL) - mktime(&tm1))/(24*60*60);

4、关于difftime
功 能:返回两个time_t型变量之间的时间间隔,即 计算两个时刻之间的时间差。
用 法: double difftime(time_t time2, time_t time1);
头文件:time.h

5、关于 time
头文件:time.h
函数原型:time_t time(time_t * timer)
功能: 获取当前的系统时间,返回的结果是一个time_t类型,其实就是一个大整数,其值表示从CUT(Coordinated Universal Time)时间1970年1月1日00:00:00(称为UNIX系统的Epoch时间)到当前时刻的秒数。然后调用localtime 将time_t所表示的CUT时间转换为本地时间(我们是+8区,比CUT多8个小时)并转成struct tm类型,该类型的各数据成员分别表示年月日时分秒。
补充说明:time函数的原型也可以理解为 long time(long *tloc),即返回一个long型整数。因为在time.h这个头文件中time_t实际上就是:
#ifndef _TIME_T_DEFINED
typedef long time_t; /* time value */
#define _TIME_T_DEFINED /* avoid multiple defines of time_t */
#endif
即long。

5、关于 asctime
把timeptr指向的tm结构体中储存的时间转换为字符串字符串格式返回,格式为:Www Mmm dd hh:mm:ss yyyy。其中Www为星期;Mmm为月份;dd为日;hh为时;mm为分;ss为秒;yyyy为年份。

6、关于 ctime

功 能: 把日期和时间转换为字符串

那么本题是:

#include <iostream>
#include <time.h>
using namespace std; 


int main() {
	struct tm  tm1 ;
	tm1.tm_year = 1991 - 1900;
	tm1.tm_mon = 12 - 1;
	tm1.tm_mday = 15 + 8113 - 5343;
	tm1.tm_hour = 1;
	tm1.tm_min = 0;
	tm1.tm_sec = 0;
	time_t t3 = mktime(&tm1);
	struct tm * t2 = localtime( &t3 );
	cout<<t2->tm_year+1900<<" "<<t2->tm_mon+1<<" "<<t2->tm_mday<<endl;
	return 0;
}


得到的答案是1999  7  16 
标准日期1991的下一年是闰年,1791的下一年也是闰年,不用准换了。
由于将标准日期加来了200年,所以是1799  7  16




世纪末的星期

    曾有邪教称1999年12月31日是世界末日。当然该谣言已经不攻自破。

    还有人称今后的某个世纪末的12月31日,如果是星期一则会....

    有趣的是,任何一个世纪末的年份的12月31日都不可能是星期一!! 

    于是,“谣言制造商”又修改为星期日......

    1999年的12月31日是星期五,请问:未来哪一个离我们最近的一个世纪末年(即xx99年)的12月31日正好是星期天(即星期日)?

    请回答该年份(只写这个4位整数,不要写12月31等多余信息)


#include <iostream>
#include <time.h>
#include <windows.h>
using namespace std;

int main() {
	struct tm * tm1 = new tm();
	tm1->tm_mon = 12 - 1;
	tm1->tm_mday = 31;
	tm1->tm_year = 1999 - 1900;
	tm1->tm_hour = 1;
	tm1->tm_min = 0;
	tm1->tm_sec = 0;
	 
	time_t t = mktime( tm1 );
	tm1 = localtime( &t );
	
	while( tm1->tm_wday != 0 )
	{
		cout<<tm1->tm_year + 1900<<"  "<<tm1->tm_wday<<endl;
		tm1->tm_year += 100;
	
		time_t t1 = mktime( tm1 );
		tm1 = localtime( &t1 );
	
		cout<<tm1->tm_year+1900<<"  "<<tm1->tm_wday<<endl;
	}
	cout<<tm1->tm_year + 1900<<endl;
	return 0;
}

最后答案是2299年.....

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值