在标准C/C++中与日期和时间相关的数据结构

注意:年份是实际年份与  1900  的差值

我们可通过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()为负。*/
};
#define _TM_DEFINED
#endif

exmple:

string timeIn = "2016-09-17 09:48:13.560";
tm tm_timeIn = { };
int timeOutMsecTemp = ;
sscanf_s(timeIn.c_str(), "%4d-%2d-%2d %2d:%2d:%2d.%3d",
&tm_timeIn.tm_year,
&tm_timeIn.tm_mon,
&tm_timeIn.tm_mday,
&tm_timeIn.tm_hour,
&tm_timeIn.tm_min,
&tm_timeIn.tm_sec,
&timeInMsecTemp);
tm_timeIn.tm_year -= ; //年份,指的是与1900年的差值
tm_timeIn.tm_mon -= ;     //月份,0代表1月,故应减去1

char dt[];
ctime_s(dt, sizeof dt,&time_t_In);
cout << dt << endl; //Sat Sep 17 09:48:13 2016\n
char bat[];
asctime_s(bat, sizeof bat, &tm_timeIn);
cout << bat << endl; //Sat Sep 17 09:48:13 2016\n

ANSI C标准称使用tm结构的这种时间表示为分解时间(broken-down time)。

而日历时间(Calendar Time)是通过time_t数据类型来表示的,用time_t表示的时间(日历时间)是从一个时间点(例如:1970年1月1日0时0分0秒)到此时的秒数。在time.h中,我们也可以看到time_t是一个长整型数:

#ifndef _TIME_T_DEFINED
typedef long time_t; /* 时间值 */
#define _TIME_T_DEFINED /* 避免重复定义 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 end, time_t start);     //返回的是  end - start  的差值
time_t mktime(struct tm * timeptr); //结构体tm 转化为 从1970年到现在的 秒数(其中tm.tm_year是实际年份与1900的差值)
time_t time(time_t * timer); //time_t now = time(NULL);返回当前时间 与 1970年1月1日的差值 的秒数
char str[];
errno_t asctime_s(char * buf, rsize_t bufsz, const struct tm * time_ptr);
//tm结构转化为the following fixed 25-character form(\n也占一个字节): Tue May 26 21:51:50 2015\n
ctime_s(char * buf, rsize_t bufsz, const time_t *timer);
//time_t转化为 :Tue May 26 21:51:03 2015\n

example:

#define __STDC_WANT_LIB_EXT1__ 1
#include <time.h>
#include <stdio.h> int main(void)
{
time_t t = time(NULL);
printf("UTC: %s", asctime(gmtime(&t)));
printf("local: %s", asctime(localtime(&t))); #ifdef __STDC_LIB_EXT1__
struct tm buf;
char str[];
asctime_s(str,sizeof str,gmtime_s(&t, &buf));
printf("UTC: %s", str);
asctime_s(str,sizeof str,localtime_s(&t, &buf)));
printf("local: %s", str);
#endif
}
Output: UTC: Tue Feb ::
local: Tue Feb ::
UTC: Tue Feb ::
local: Tue Feb ::

此外,time.h还提供了两种不同的函数将日历时间(一个用time_t表示的整数)转换为我们平时看到的把年月日时分秒分开显示的时间格式tm:

struct tm * gmtime(const time_t *timer);
struct tm * localtime(const time_t * timer);
struct tm *gmtime_s(const time_t *restrict time, struct tm *restrict result);
//从1970年1月1日到现在的秒数 转化为 标准时间UTC: Tue Feb 17 18:12:09 2015
struct tm *localtime_s(const time_t *restrict time, struct tm *restrict result);
//从1970年1月1日到现在的秒数 转化为 系统本地时间local: Tue Feb 17 13:12:09 2015

通过查阅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秒到该时间点所经过的秒数。

C/C++_date&time的更多相关文章

  1. 06_java 时间获取练习_Date\SimpleDateFormat\Calendar类练习

     1.获取当前的日期,并把这个日期转换为指定格式的字符串,如2088-08-08 08:08:08 import java.text.SimpleDateFormat; import java.uti ...

  2. JAVA基础复习与总结<五> String类_File类_Date类

    String类 .Java字符串就是Unicode字符序列,例如串“Java”就是4个Unicoe字符组成. .Java没有内置的字符串类型,而是在标准java类库中提供了一个预定义的类String, ...

  3. [19/03/16-星期六] 常用类_Date时间类&DateFormat类

    一.Date时间类 计算机中 以1970 年 1 月 1 日 00:00:00定为基准时间,每个度量单位是毫秒(1秒的千分之一) 用ong类型的变量来表示时间,如当前时刻数值:long  now =n ...

  4. 时间获取_Date\SimpleDateFormat\Calendar类

     1.获取当前的日期,并把这个日期转换为指定格式的字符串,如2088-08-08 08:08:08 import java.text.SimpleDateFormat; import java.uti ...

  5. Oracle碎碎念~2

    1. 如何查看表的列名及类型 SQL> select column_name,data_type,data_length from all_tab_columns where owner='SC ...

  6. 5.在MVC中使用泛型仓储模式和工作单元来进行增删查改

    原文链接:http://www.c-sharpcorner.com/UploadFile/3d39b4/crud-operations-using-the-generic-repository-pat ...

  7. jquery 的一些基本操作

    日常使用中的操作记录,持续更新中: ECharts,一个纯 Javascript 的图表库,可以流畅的运行在 PC 和移动设备上,兼容当前绝大部分浏览器(IE8/9/10/11,Chrome,Fire ...

  8. JavaScript 操作 Cookie

    转自作者:聂微东出处:http://www.cnblogs.com/Darren_code/      什么是 Cookie “cookie 是存储于访问者的计算机中的变量.每当同一台计算机通过浏览器 ...

  9. .NET单元测试的艺术-3.测试代码

    开篇:上一篇我们学习单元测试和核心技术:存根.模拟对象和隔离框架,它们是我们进行高质量单元测试的技术基础.本篇会集中在管理和组织单元测试的技术,以及如何确保在真实项目中进行高质量的单元测试. 系列目录 ...

随机推荐

  1. 高德地图纯js和html

    <!doctype html> <html> <head> <meta content="" charset="utf-8&qu ...

  2. java 标签库(核心,xml,sql ,国际化,函数)

    java标签库分分为上述几种,一般经常使用的是核心和函数,接下来会分别讲解这几种,和常见的用法. 一般标签库会和el表达式一起使用,所以在学习标签库前最后也学习下el表达式的使用. 导入后展开 可以从 ...

  3. mysql深入浅出的笔记(存储过程一)

    1.存储过程和函数....    存储过程和函数是事先经过编译并存储在数据库中的一段SQL语句的集合,调用存储过程和函数可以简化应用开发人员的很多工作,    减少数据在数据库中和应用服务器之间的传说 ...

  4. C语言学习笔记二

    第二章 数组 一,定义: 数组是有序数据的结合,同一数据类型 整型数组     int arr[10]={0,1,2,4,5,6,7,8,9}; 字符数组     char str[6]={'h',' ...

  5. adb 的使用

    打出log:adb logcat -s fliterName     ps:(fliterName就是你的tag)

  6. css雪碧图生成工具4.2更新

    v4.0更新连接:http://www.cnblogs.com/wang4517/p/4493917.html v4.1更新连接:http://www.cnblogs.com/wang4517/p/4 ...

  7. SharedPreferences 详解

    获取SharedPreferences的两种方式: 1 调用Context对象的getSharedPreferences()方法 2 调用Activity对象的getPreferences()方法 两 ...

  8. 百度地图API试用--(初次尝试)

    2016-03-17: 百度地图API申请key的步骤相对简单,不做过多阐述. 初次使用百度地图API感觉有点神奇,有些功能加进来以后有点问题,注释掉等有空再解决. 代码如下: <%@ page ...

  9. 进击的Python【第三章】:Python基础(三)

    Python基础(三) 本章内容 集合的概念与操作 文件的操作 函数的特点与用法 参数与局部变量 return返回值的概念 递归的基本含义 函数式编程介绍 高阶函数的概念 一.集合的概念与操作 集合( ...

  10. jQuery 追加元素的方法如append、prepend、before,after(转)

    1.jQuery append() 方法 jQuery append() 方法在被选元素的结尾插入内容. 实例 复制代码代码如下: $("p").append("Some ...