原文:http://blog.csdn.net/luoweifu/article/details/20288549

Unix时间戳(Unix timestamp),或称Unix时间(Unix time)、POSIX时间(POSIX time),是一种时间表示方式,定义为从格林威治时间1970年01月01日00时00分00秒起至现在的总秒数。Unix时间戳不仅被使用在Unix 系统、类Unix系统中,也在许多其他操作系统中被广告采用。
目前相当一部分操作系统使用32位二进制数字表示时间。此类系统的Unix时间戳最多可以使用到格林威治时间2038年01月19日03时14分07秒(二进制:01111111 11111111 11111111 11111111)。其后一秒,二进制数字会变为10000000 00000000 00000000 00000000,发生溢出错误,造成系统将时间误解为1901年12月13日20时45分52秒。这很可能会引起软件故障,甚至是系统瘫痪。使用64位二进制数字表示时间的系统(最多可以使用到格林威治时间292,277,026,596年12月04日15时30分08秒)则基本不会遇到这类溢出问题。
首先我们了解一下时间的相关概念,以及之间的区别,需要了解的时间概念有:
本地时间(locale time)
格林威治时间(Greenwich Mean Time GMT)
时间协调时间 (Universal Time Coordinated UTC)

本地时间,显而易见不用解释了
先看看时间的标准:
(1)世界时
世界时是最早的时间标准。在1884年,国际上将1s确定为全年内每日平均长度的1/8.64×104。以此标准形成的时间系统,称为世界是,即UT1。1972年国际上开始使用国际原子时标,从那以后,经过格林威治老天文台本初子午线的时间便被称为世界时,即UT2,或称格林威治时间(GMT),是对地球转速周期性差异进行校正后的世界时。
(2)原子时
1967年,人们利用铯原子振荡周期极为规律的特性,研制出了高精度的原子时钟,将铯原子能级跃迁辐射9192631770周所经历的时间定为1s。现在用的时间就是1971年10月定义的国际原子时,是通过世界上大约200多台原子钟进行对比后,再由国际度量衡局时间所进行数据处理,得出的统一的原子时,简称TAI。
(3)世界协调时
世界协调时是以地球自转为基础的时间标准。由于地球自转速度并不均匀,并非每天都是精确的86400原子s,因而导致了自转时间与世界时之间存在18个月有1s的误差。为纠正这种误差,国际地球自转研究所根据地球自转的实际情况对格林威治时间进行增减闰s的调整,与国际度量衡局时间所联合向全世界发布标准时间,这就是所谓的世界协调时(UTC:CoordinatdeUniversalTime)。UTC的表示方式为:年(y)、月(m)、日(d)、时(h)、分(min)、秒(s),均用数字表示。

GPS 系统中有两种时间区分,一为UTC,另一为LT(地方时)两者的区别为时区不同,UTC就是0时区的时间,地方时为本地时间,如北京为早上八点(东八区),UTC时间就为零点,时间比北京时晚八小时,以此计算即可
通过上面的了解,我们可以认为格林威治时间就是世界协调时间(GMT=UTC),格林威治时间和UTC时间均用秒数来计算的。

而在我们平时工作当中看到的计算机日志里面写的时间大多数是用UTC时间来计算的,那么我们该怎么将UTC时间转化为本地时间便于查看日志,那么在作程序开发时又该怎么将本地时间转化为UTC时间呢?
下面就介绍一个简单而使用的工具,就是使用Linux/unix命令date来进行本地时间和local时间的转化。
大家都知道,在计算机中看到的utc时间都是从(1970年01月01日 0:00:00)开始计算秒数的。所看到的UTC时间那就是从1970年这个时间点起到具体时间共有多少秒。
我们在编程中可能会经常用到时间,比如取得系统的时间(获取系统的年、月、日、时、分、秒,星期等),或者是隔一段时间去做某事,那么我们就用到一些时间函数。

linux下存储时间常见的有两种存储方式,一个是从1970年到现在经过了多少秒,一个是用一个结构来分别存储年月日时分秒的。
time_t 这种类型就是用来存储从1970年到现在经过了多少秒,要想更精确一点,可以用结构struct timeval,它精确到微妙。
struct timeval
{
long tv_sec; //
long tv_usec; /微秒/
};

而直接存储年月日的是一个结构:
struct tm
{
int tm_sec; /秒,正常范围0-59, 但允许至61/
int tm_min; /分钟,0-59/
int tm_hour; /小时, 0-23/
int tm_mday; /日,即一个月中的第几天,1-31/
int tm_mon; /月, 从一月算起,0-11/ 1+p->tm_mon;
int tm_year; /年, 从1900至今已经多少年/ 1900+ p->tm_year;
int tm_wday; /星期,一周中的第几天, 从星期日算起,0-6/
int tm_yday; /从今年1月1日到目前的天数,范围0-365/
int tm_isdst; /日光节约时间的旗标/
};
需要特别注意的是,年份是从1900年起至今多少年,而不是直接存储如2011年,月份从0开始的,0表示一月,星期也是从0开始的, 0表示星期日,1表示星期一。

下面介绍一下我们常用的时间函数:

include

/*gettime1.c*/
#include <time.h>  int main()
{  time_t timep;  time(&timep); /*获取time_t类型的当前时间*/  /*用gmtime将time_t类型的时间转换为struct tm类型的时间,按没有经过时区转换的UTC时间 然后再用asctime转换为我们常见的格式 Fri Jan 11 17:25:24 2008 */  printf("%s", asctime(gmtime(&timep)));  return 0;
}  

编译并运行:
gcc−ogettime1gettime1.cgcc -o gettime1 gettime1.c ./gettime1
Fri Jan 11 17:04:08 2008

下面是直接把time_t类型的转换为我们常见的格式:

/* gettime2.c*/
#include <time.h>  int main()
{  time_t timep;  time(&timep); /*获取time_t类型当前时间*/     /*转换为常见的字符串:Fri Jan 11 17:04:08 2008*/  printf("%s", ctime(&timep));  return 0;
}  

编译并运行:
gcc−ogettime2gettime2.cgcc -o gettime2 gettime2.c ./gettime2
Sat Jan 12 01:25:29 2008

/*gettime3.c */
#include <time.h>  int main()
{  char *wday[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};  time_t timep;  struct tm *p;  time(&timep); /*获得time_t结构的时间,UTC时间*/  p = gmtime(&timep); /*转换为struct tm结构的UTC时间*/  printf("%d/%d/%d ", 1900 + p->tm_year, 1 + p->tm_mon, p->tm_mday);  printf("%s %d:%d:%d\n", wday[p->tm_wday], p->tm_hour,  p->tm_min, p->tm_sec);  return 0;
}  

编译并运行:
gcc−ogettime3gettime3.cgcc -o gettime3 gettime3.c ./gettime3
2008/1/11 Fri 17:42:54
从这个时间结果上来看,它和gettime1保持一致。

/*gettime4.c*/
#include <time.h>  int main()
{  char *wday[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};  time_t timep;  struct tm *p;  time(&timep); /*获得time_t结构的时间,UTC时间*/  p = localtime(&timep); /*转换为struct tm结构的当地时间*/  printf("%d/%d/%d ", 1900 + p->tm_year, 1 + p->tm_mon, p->tm_mday);  printf("%s %d:%d:%d\n", wday[p->tm_wday], p->tm_hour, p->tm_min, p->tm_sec);  return 0;
}  

编译并运行:
gcc−ogettime4gettime4.cgcc -o gettime4 gettime4.c ./gettime4
2008/1/12 Sat 1:49:29
从上面的结果我们可以这样说:
time, gmtime, asctime 所表示的时间都是UTC时间,只是数据类型不一样,
而localtime, ctime 所表示的时间都是经过时区转换后的时间,它和你用系统命令date所表示的CST时间应该保持一致。

/*gettime5.c*/
#include <time.h>  int main()
{  time_t timep;  struct tm *p;  time(&timep); /*当前time_t类型UTC时间*/  printf("time():%d\n",timep);  p = localtime(&timep); /*转换为本地的tm结构的时间按*/  timep = mktime(p); /*重新转换为time_t类型的UTC时间,这里有一个时区的转换*/   //by lizp 错误,没有时区转换, 将struct tm 结构的时间转换为从1970年至p的秒数  printf("time()->localtime()->mktime(): %d\n", timep);  return 0;
}  

编译并运行:
gcc−ogettime5gettime5.cgcc -o gettime5 gettime5.c ./gettime5
time():1200074913
time()->localtime()->mktime(): 1200074913
这里面把UTC时间按转换为本地时间,然后再把本地时间转换为UTC时间,它们转换的结果保持一致。

/*gettime6.c */
#include <time.h>  int main()
{  time_t timep;  struct tm *p;  time(&timep);  /*得到time_t类型的UTC时间*/  printf("time():%d\n",timep);  p = gmtime(&timep); /*得到tm结构的UTC时间*/  timep = mktime(p); /*转换,这里会有时区的转换*/ //by lizp 错误,没有时区转换, 将struct tm 结构的时间转换为从1970年至p的秒数  printf("time()->gmtime()->mktime(): %d\n", timep);  return 0;
}  

编译并运行:
gcc−ogettime6gettime6.cgcc -o gettime6 gettime6.c ./gettime6
time():1200075192
time()->gmtime()->mktime(): 1200046392
从这里面我们可以看出,转换后时间不一致了,计算一下,整整差了8个小时( (1200075192-1200046392)/3600 = 8),说明mktime会把本地时间转换为UTC时间,这里面本来就是UTC时间,于是再弄个时区转换,结果差了8个小时,用的时候应该注意。

strftime() 函数将时间格式化
我们可以使用strftime()函数将时间格式化为我们想要的格式。它的原型如下:
size_t strftime(
char *strDest,
size_t maxsize,
const char *format,
const struct tm *timeptr
);
我们可以根据format指向字符串中格式命令把timeptr中保存的时间信息放在strDest指向的字符串中,最多向strDest中存放maxsize个字符。该函数返回向strDest指向的字符串中放置的字符数。
函数strftime()的操作有些类似于sprintf():识别以百分号(%)开始的格式命令集合,格式化输出结果放在一个字符串中。格式化命令说明串 strDest中各种日期和时间信息的确切表示方法。格式串中的其他字符原样放进串中。格式命令列在下面,它们是区分大小写的。
%a 星期几的简写
%A 星期几的全称
%b 月分的简写
%B 月份的全称
%c 标准的日期的时间串
%C 年份的后两位数字
%d 十进制表示的每月的第几天
%D 月/天/年
%e 在两字符域中,十进制表示的每月的第几天
%F 年-月-日
%g 年份的后两位数字,使用基于周的年
%G 年分,使用基于周的年
%h 简写的月份名
%H 24小时制的小时
%I 12小时制的小时
%j 十进制表示的每年的第几天
%m 十进制表示的月份
%M 十时制表示的分钟数
%n 新行符
%p 本地的AM或PM的等价显示
%r 12小时的时间
%R 显示小时和分钟:hh:mm
%S 十进制的秒数
%t 水平制表符
%T 显示时分秒:hh:mm:ss
%u 每周的第几天,星期一为第一天 (值从0到6,星期一为0)
%U 第年的第几周,把星期日做为第一天(值从0到53)
%V 每年的第几周,使用基于周的年
%w 十进制表示的星期几(值从0到6,星期天为0)
%W 每年的第几周,把星期一做为第一天(值从0到53)
%x 标准的日期串
%X 标准的时间串
%y 不带世纪的十进制年份(值从0到99)
%Y 带世纪部分的十制年份
%z,%Z 时区名称,如果不能得到时区名称则返回空字符。
%% 百分号
如果想显示现在是几点了,并以12小时制显示,就象下面这段程序:

#include "time.h"
#include "stdio.h"
int main(void)
{  struct tm *ptr;  time_t lt;  char str[80];  lt=time(NULL);  ptr=localtime(&lt);  strftime(str,100,"It is now %I %p",ptr);  printf(str);  return 0;
}  

其运行结果为:
It is now 4PM

而下面的程序则显示当前的完整日期:

其运行结果为:
Today is Sunday, the 02 day of March in the year 2014.

c++ time_t和tm相关推荐

  1. linux '$^t' 时间,Linux C时间函数 time_t struct tm

    Linux C时间函数 time_t struct tm #include 关于时间的类型: time_t long型,表示从1970年1月1日到现在经过的秒数. struct tm { int tm ...

  2. C/C++时间相关类型timeval、time_t、tm、clock_t、size_t、时间戳及其对应操作函数总结

    C/C++时间相关结构体timeval.time_t.tm.clock_t.size_t及其对应操作函数总结 一.结构体timeval与类型time_t.clock_t.size_t timt_t.c ...

  3. CRT中的时间(time_t和tm)

    时间处理时实际项目中经常碰到的问题,这里介绍最常用的时间处理函数. 首先介绍基本的时间概念.时间一般分为两种,一种是本地时间(Local Time),一种是协调世界时间(Coordinated Uni ...

  4. 关于时间time_t和tm的介绍(很详细)

    Unix时间戳(Unix timestamp),或称Unix时间(Unix time).POSIX时间(POSIX time),是一种时间表示方式,定义为从格林威治时间1970年01月01日00时00 ...

  5. C/C++中time_t、tm、字符串之间的转换

    1.字符串到time_t的转换 BOOL GetStrFromTime(time_t iTimeStamp, char *pszTime) { tm *pTmp = localtime(&iT ...

  6. 各类时间转换(FILETIME,time_t,tm,QDateTime,SystemTime,LocalTime)

    FILETIME转SystemTime和本地系统时间 需要先将FILETIME转为LocalFileTime 再将LocalFileTime 转为SystemTime 即为本地的系统时间 FILETI ...

  7. C++时间戳time_t和时间结构体tm

    本地时间(LT)是东八区的时间,格林尼治时间(GMT)是0时区的时间,世界协调时(UTC)是修正后的格林尼治时间. 我们可以粗略地认为世界协调时(UTC)就是格林尼治时间(GMT). 本地时间在东八区 ...

  8. c语言中tm与time_t两种时间格式的转换

    1.它们两个都包含在头文件 #include<ctime> 2.time_t:time_t表示的时间(日历时间)是从一个时间点(例如:1970年1月1日0时0分0秒)到此时的秒数,可以采用 ...

  9. time_t tm systemtime 互相转换

    为什么80%的码农都做不了架构师?>>>    头文件:time.h 函数原型:time_t time(time_t * timer) 功 能: 获取当前的系统时间,返回的结果是一个 ...

  10. mysql变量string_mysql sql语句有变量 time_t变量转换为string

    1.char*变量 如果有两个指针变量不可以 需要一个转换为string string strCall ; strCall.assign(pCallInfo->m_szCallerNo,strl ...

最新文章

  1. SaaS九问,ToB必读
  2. PHP的词法解析器:re2c
  3. TensorRT C++ 批量推理笔记
  4. 小爱音箱怎么装app_79元的Redmi小爱音箱怎么样?这里有一份体验报告
  5. 八大排序算法交换排序算法
  6. GC 调优(实战篇) - GC参考手册
  7. sql语句优化之not in
  8. php excel parser pro v4.2,PHP Excel Parser Pro v4.2怎么用
  9. 华为交换机VTY用户界面属性配置教程
  10. 外国视频伪原创工具 视频MD5修改器破解版
  11. oracle按照拼音排序,ORACLE根据中文拼音首字母排序、取得中文拼音首字母函数
  12. 阿里服务器微信发不了图片,为什么微信发不了图片?这四招教你解决难题
  13. 破解Excel2013密码设置工作表保护
  14. vue中使用echarts结合百度地图制作地图(引入百度地图、获取百度地图实例、设置百度地图)
  15. PPI (手机屏幕的PPI 和计算方法)
  16. 软考初级程序员--学习
  17. 传智播客成都java培训老学员福利
  18. windows10开启wst子系统
  19. Git教程 - 密钥配置
  20. java gui 嵌入浏览器_DJNativeSwing-SWT组件-Java GUI中内嵌浏览器

热门文章

  1. python-数据结构-大学生-航空订票系统
  2. 教育大数据采集机制与关键技术研究
  3. 简单的C语言程序介绍(重点理解),超详细基础代码解析
  4. 常用服务和开放端口对照表
  5. 科学计数法 (C语言)
  6. “互联网+”大学生创新创业大赛项目策划书
  7. 【经典算法实现 16】阿克曼函数(非递归实现 代码优化)
  8. 查找所引用的文献在某种期刊下的引用格式(引用风格)
  9. MATLAB2017安装步骤
  10. r7c刷机android6.0,OPPOR7c官方固件刷机教程_线刷|救砖教程图解