c time类型详解
linux下存储时间常见的有两种存储方式,一个是从1970年01月01日 0:00:00到现在经过了多少秒,一个是用一个结构来分别存储年月日时分秒的。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*/ +p->tm_mon;
int tm_year; /*年, 从1900至今已经多少年*/ + p->tm_year;
int tm_wday; /*星期,一周中的第几天, 从星期日算起,0-6*/
int tm_yday; /*从今年1月1日到目前的天数,范围0-365*/
int tm_isdst; /*日光节约时间的旗标*/
};
需要特别注意的是,年份是从1970年01月01日 0:00:00开始计算的。
下面介绍一下我们常用的时间函数:(参考链接:http://www.cplusplus.com/reference/ctime/)
#include <time.h>
char *asctime(const struct tm* timeptr);
将结构中的信息转换为真实世界的时间,以字符串的形式显示 char *ctime(const time_t *timep);
将timep转换为真是世界的时间,以字符串显示,它和asctime不同就在于传入的参数形式不一样 double difftime(time_t time1, time_t time2);
返回两个时间相差的秒数 int gettimeofday(struct timeval *tv, struct timezone *tz);
返回当前距离1970年的秒数和微妙数,后面的tz是时区 struct tm* gmtime(const time_t *timep);
将time_t表示的时间转换为没有经过时区转换的UTC时间,是一个struct tm结构指针 stuct tm* localtime(const time_t *timep);
和gmtime类似,但是它是经过时区转换的时间。
另外需要注意的是不能连续使用localtime,如有需求应该保存上一个timep的值。(多线程下也需要注意) time_t mktime(struct tm* timeptr);
将struct tm 结构的时间转换为从1970年至今的秒数 time_t time(time_t *t);
取得从1970年1月1日至今的秒数。
上面是简单的介绍,下面通过实战来看看这些函数的用法:
/*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 ;
}
编译并运行:
$gcc -o gettime1 gettime1.c
$./gettime1
Fri Jan ::
下面是直接把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 ;
}
编译并运行:
10:06:04
两个的结果除了秒上有差别之外(执行程序需要时间),应该是一样的,可是我这里执行却发现差了很长时间按,一个是周五,一个是周六,后来我用 date 命令执行了一遍(备注:date -u显示UTC时间)
$date
六 1月 :: CST
我发现date和gettime2比较一致, 我估计可能gettime1并没有经过时区的转换,它们是有差别的。
/*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 ", + p->tm_year, + 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 ;
}
编译并运行:
$gcc -o gettime3 gettime3.c
$./gettime3
// Fri ::
从这个时间结果上来看,它和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 ", + p->tm_year, + 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 ;
}
编译并运行:
$gcc -o gettime4 gettime4.c
$./gettime4
// Sat ::
从上面的结果我们可以这样说:
time, gmtime 所表示的时间都是UTC时间,只是数据类型不一样,
而localtime 所表示的时间都是经过时区转换后的时间,它和你用系统命令date所表示的CST时间应该保持一致。
(备注:CST 中央标准时间 GMT 格林威治时间 UTC 世界协调时间 EST 东部标准时间)
/*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时间,这里有一个时区的转换*/
printf("time()->localtime()->mktime(): %d\n", timep);
return ;
}
编译并运行:
$gcc -o gettime5 gettime5.c
$./gettime5
time():
time()->localtime()->mktime():
这里面把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); /*转换,这里会有时区的转换*/
printf("time()->gmtime()->mktime(): %d\n", timep);
return ;
}
编译并运行:
$gcc -o gettime6 gettime6.c
$./gettime6
time():
time()->gmtime()->mktime():
从这里面我们可以看出,转换后时间不一致了,计算一下,整整差了8个小时( (1200075192-1200046392)/3600 = 8),说明mktime会把本地时间转换为UTC时间,这里面本来就是UTC时间,于是再弄个时区转换,结果差了8个小时,用的时候应该注意。
c time类型详解的更多相关文章
- C#进阶系列——WebApi 接口返回值不困惑:返回值类型详解
前言:已经有一个月没写点什么了,感觉心里空落落的.今天再来篇干货,想要学习Webapi的园友们速速动起来,跟着博主一起来学习吧.之前分享过一篇 C#进阶系列——WebApi接口传参不再困惑:传参详解 ...
- C++11 并发指南六(atomic 类型详解四 C 风格原子操作介绍)
前面三篇文章<C++11 并发指南六(atomic 类型详解一 atomic_flag 介绍)>.<C++11 并发指南六( <atomic> 类型详解二 std::at ...
- C++11 并发指南六(atomic 类型详解三 std::atomic (续))
C++11 并发指南六( <atomic> 类型详解二 std::atomic ) 介绍了基本的原子类型 std::atomic 的用法,本节我会给大家介绍C++11 标准库中的 std: ...
- C++11 并发指南六( <atomic> 类型详解二 std::atomic )
C++11 并发指南六(atomic 类型详解一 atomic_flag 介绍) 一文介绍了 C++11 中最简单的原子类型 std::atomic_flag,但是 std::atomic_flag ...
- 服务启动项 Start类型详解
注册表的服务启动项 Start类型详解 HKLM\SYSTEM\CurrentControlSet\services\ 下的服务项.不论有没有在services.msc服务管理控制台中显示,在注册表中 ...
- c# WebApi之接口返回类型详解
c# WebApi之接口返回类型详解 https://blog.csdn.net/lwpoor123/article/details/78644998
- C++之string类型详解
C++之string类型详解 之所以抛弃char*的字符串而选用C++标准程序库中的string类,是因为他和前者比较起来,不必担心内存是否足够.字符串长度等等,而且作为一个泛型类出现,他集成的操作函 ...
- (转)C# WebApi 接口返回值不困惑:返回值类型详解
原文地址:http://www.cnblogs.com/landeanfen/p/5501487.html 正文 前言:已经有一个月没写点什么了,感觉心里空落落的.今天再来篇干货,想要学习Webapi ...
- Swift - 可选类型详解
可选类型详解 直接上代码解释 // 类中所有的属性在对象初始化时,必须有初始化值 class Person : NSObject { var name : String? var view : UIV ...
- (转)MySQL字段类型详解
MySQL字段类型详解 原文:http://www.cnblogs.com/100thMountain/p/4692842.html MySQL支持大量的列类型,它可以被分为3类:数字类型.日期和时间 ...
随机推荐
- webplus知识点小结
1.返回首页,要在首页栏目里面加链接,直接预览站点的时候地址栏那个地址就行 2.上传图片变色问题,要传jpg格式,不要png 3.留言板制作:后台组件管理->留言板->获取链接 然后在留言 ...
- Minimum Increment to Make Array Unique LT945
Given an array of integers A, a move consists of choosing any A[i], and incrementing it by 1. Return ...
- 深入理解JVM(一)编译openJDK
此文总结的很不错:https://www.cnblogs.com/ACFLOOD/p/5528035.html 准备openJDK源码和环境 1.在linux和macOS上编译openJDK更加友好, ...
- 解决win10系统无法安装.NET Framework 3.5
方法1:“我的电脑”,单击右键选择“管理” 在打开的“计算机管理”窗口中依路径“服务和应用程序—服务”打开,在列表中找到“Windows Update”并双击打开. 启动类型:自动. 服务状态下面点击 ...
- hadoop启动
安装完hadoop集群之后,第一次启动之前必须初始化,之后就可以不用再初始化(注意:初始化操作只可以一次) hdfs namenode -format (hadoop namenode -format ...
- IOS xib和代码自定义UIView
https://www.jianshu.com/p/1bcc29653085 总结的比较好 iOS开发中,我们常常将一块View封装起来,以便于统一管理内部的子控件. 下面就来说说自定义View的封装 ...
- 《mysql必知必会》学习_第20章_20180809_欢
第20章:更新和删除数据 P140 update customers set_emails='elmer@fudd.com' where cust_id=10005; 更新多个列,用逗号隔开.注意被指 ...
- nova scheduler filters 配置
scheduler_driver = nova.scheduler.filter_scheduler.FilterScheduler scheduler_default_filters = Avail ...
- 跨站请求伪造和csrf_token使用
day70 csrf简单用法 什么是CSRF ? 跨站请求伪造, 问题: 1. 钓鱼网站的页面和正经网站的页面对浏 ...
- Java学习笔记43(打印流、IO流工具类简单介绍)
打印流: 有两个类:PrintStream,PrintWriter类,两个类的方法一致,区别在于构造器 PrintStream:构造方法:接收File类型,接收字符串文件名,接收字节输出流(Outpu ...