C++获取时间函数众多,何时该用什么函数,拿到的是什么时间?该怎么用?很多人都会混淆。

本文是本人经历了几款游戏客户端和服务器开发后,对游戏中时间获取的一点总结。

最早学习游戏客户端时,为了获取最精确的时间,使用两个函数

BOOL QueryPerformanceFrequency(LARGE_INTEGER *lpFrequency);

BOOL QueryPerformanceCounter(LARGE_INTEGER *lpCount);

这两个函数分别是获取CPU的时钟频率和CPU计数器,是能够获取到的最精确的时间差。对于需要获取每帧走过的精确时间,使用这两个函数是最最精确的。

#include<windows.h>

LARGE_INTEGER lFrequency;
QueryPerformanceFrequency(&lFrequency); LARGE_INTEGER lBeginCount;
QueryPerformanceCounter(&lBeginCount); Sleep(); LARGE_INTEGER lEndCount;
QueryPerformanceCounter(&lEndCount); double time = (double)(lEndCount.QuadPart - lBeginCount.QuadPart) / (double)lFrequency.QuadPart;

在客户端代码的时间处理模块中,每一帧调用QueryPerformanceCounter获取当前的counter,即可获取每一帧使用的时间。(当然现在有Unity,估计没人关注这俩函数了)

虽然利用这两个函数能够精确的统计经过的时间,但是却无法得到当前时间,并且以上两个函数是Windows系统所特有的,unix/linux系统中并不具备。

为了获取系统的当前精确时间,需要使用另一个系统函数

int gettimeofday(struct timeval *tv, struct timezone *tz);

获取从1970年1月1日到现在经过的时间和时区(UTC时间),(按照linux的官方文档,时区已经不再使用,正常应该传NULL)。

#include <sys/time.h>

struct timeval start_tv;

gettimeofday(&start_tv, NULL);

sleep();

struct timeval end_tv;

gettimeofday(&end_tv, NULL);

double time = (end_tv.tv_sec - start_tv.tv_sec) + (double)(end_tv.tv_usec - start_tv.tv_usec)/(double);

这样同样可以获得精确到微秒的每帧经过的时间。服务器上的帧运行机制,一般便是这个时间函数来计算和同步。

如果不需要非常精确的时间,而只要精确到秒,可以使用另一个时间函数

time_t time(time_t* timer);

该函数返回一个UTC时间戳,如果传入timer参数,则为timer设置时间戳的值。

然而以上两个函数获取的都是UTC时间戳,如果在游戏中需要显示当前时区的时间,该怎么办呢?

使用localtime或localtime_r,两者效果一致,只是获取结果参数位置不同。

struct tm *localtime(const time_t *timep); // 传入UTC时间戳,返回当前时区的tm结构指针

struct tm *localtime_r(const time_t *timep, struct tm *result);

第一个函数获取tm结构静态变量的指针,第二个函数则传入一个tm结构变量的地址,并为之赋值。最终得到的tm变量,存储了当前时区的时间。

tm的结构定义如下,可以直接用来显示。

struct tm {
int tm_sec; /* seconds */
int tm_min; /* minutes */
int tm_hour; /* hours */
int tm_mday; /* day of the month */
int tm_mon; /* month */
int tm_year; /* year */
int tm_wday; /* day of the week */
int tm_yday; /* day in the year */
int tm_isdst; /* daylight saving time */
};

通常来说服务器和客户端通信同步时间时,不会传这么多int,只会传一个int64的UTC时间戳,给客户端自己转成当前时区。另外服务器也不会每次都调一次localtime转一次。一般来说,服务器和客户端都是维护一个int64的当前时间的UTC时间戳,以及一个当前时区的偏移时间,(客户端还会定时更新和服务器的时间误差,对时)。

因此,需要用到另外两个函数:

struct tm *gmtime(const time_t *timep); // time_t 到 tm 的转换,前后都是UTC时间,没有时区转换

struct tm *gmtime_r(const time_t *timep, struct tm *result); // gmtime 传入result方式

time_t mktime(struct tm *timeptr); // localtime的逆向操作,从当前时区的 tm 转到UTC的 time_t

在进程启动时

time_t t0 = ; // 当前时间为0时

time_t t1 = mktime(gmtime(&t0)); // UTC的时间

int timezone_diff = (int)(t0 - t1); // 当前时区和UTC的时间差

每次需要拿到当前时区时间,只需要用 UTCStamp + timezone_diff 即可。

除了获取时间,为了格式化显示时间,我们也可以利用一些系统函数,格式化输出时间字符串

char *asctime(const struct tm *tm);

char *asctime_r(const struct tm *tm, char *buf);

char ctime(const time_t *timep);

char ctime_r(const time_t *timep, char *buf);

在游戏的实际应用中,一般都是根据具体需求来显示格式化的时间,甚至要做一些边界时间的特殊处理,因此这里都不详细讨论时间的格式化显示了。

C++中的时间函数的更多相关文章

  1. 借助JavaScript中的时间函数改变Html中Table边框的颜色

    借助JavaScript中的时间函数改变Html中Table边框的颜色 <html> <head> <meta http-equiv="Content-Type ...

  2. ylb:SQL Server中的时间函数

    ylbtech-SQL Server:SQL Server-SQL Server中的时间函数 SQL Server中的时间函数. 1,SQL Server中的时间函数 返回顶部 1.   当前系统日期 ...

  3. C中的时间函数的用法

    C中的时间函数的用法    这个类展示了C语言中的时间函数的常用的用法. 源代码: #include <ctime>#include <iostream> using name ...

  4. SQLSERVER数据库中的 时间函数

    一.sql server日期时间函数 Sql Server中的日期与时间函数 1.  当前系统日期.时间 select getdate() 2. dateadd  在向指定日期加上一段时间的基础上,返 ...

  5. PHP中日期时间函数date()用法总结

    date()是我们常用的一个日期时间函数,下面我来总结一下关于date()函数的各种形式的用法,有需要学习的朋友可参考. 格式化日期date() 函数的第一个参数规定了如何格式化日期/时间.它使用字母 ...

  6. 【推荐】PHP中格式化时间函数date与gmdate的区别 | 修改PHP的默认时区

    PHP中的时间有2个格式化函数:date()和gmdate(),在官方的文档中的描述为: date -- 格式化一个本地时间/日期 gmdate -- 格式化一个 GMT/UTC 日期/时间,返回的是 ...

  7. Linux C++中的时间函数(转)

    http://net.pku.edu.cn/~yhf/linux_c/function/03.html   asctime(将时间和日期以字符串格式表示) 相关函数 time,ctime,gmtime ...

  8. FineReport中日期时间函数使用总结

    说明:凡函数中以日期作为参数因子的,其中日期的形式都必须是yy/mm/dd.而且必须用英文环境下双引号(" ")引用. DATE DATE(year,month,day):返回一个 ...

  9. Oracle中的时间函数用法(to_date、to_char) (总结)

    一.24小时的形式显示出来要用HH24 select to_char(sysdate,'yyyy-MM-dd HH24:mi:ss') from dual; select to_date('2005- ...

随机推荐

  1. 微信公众号开发之VS远程调试

    目录 (一)微信公众号开发之VS远程调试 (二)微信公众号开发之基础梳理 (三)微信公众号开发之自动消息回复和自定义菜单 前言 微信公众平台消息接口的工作原理大概可以这样理解:从用户端到公众号端一个流 ...

  2. ASP.NET Aries 入门开发教程2:配置出一个简单的列表页面

    前言: 朋友们都期待我稳定地工作,但创业公司若要躺下,也非意念可控. 若人生注定了风雨飘摇,那就雨中前行了. 最机开始看聊新的工作机会,欢迎推荐,创业公司也可! 同时,趁着自由时间,抓紧把这系列教程给 ...

  3. 富文本编辑器Simditor的简易使用

    最近打算自己做一个博客系统,并不打算使用帝国cms或者wordpress之类的做后台管理!自己处于学习阶段也就想把从前台到后台一起谢了.好了,废话不多说了,先来看看富文本编辑器SimDitor,这里是 ...

  4. nodejs利用http模块实现银行卡所属银行查询和骚扰电话验证

    http模块内部封装了http服务器和客户端,因此Node.js不需要借助Apache.IIS.Nginx.Tomcat等传统HTTP服务器,就可以构建http服务器,亦可以用来做一些爬虫.下面简单介 ...

  5. Golang 编写的图片压缩程序,质量、尺寸压缩,批量、单张压缩

    目录: 前序 效果图 简介 全部代码 前序: 接触 golang 不久,一直是边学边做,边总结,深深感到这门语言的魅力,等下要跟大家分享是最近项目 服务端 用到的图片压缩程序,我单独分离了出来,做成了 ...

  6. Flexible 弹性盒子模型之CSS flex-shrink 属性

    实例 让第二个元素收缩到其他元素的三分之一: 效果预览 div:nth-of-type(2){flex-shrink:3;} 浏览器支持 表格中的数字表示支持该属性的第一个浏览器的版本号. 紧跟在 - ...

  7. SQL 提示介绍 hash/merge/concat union

    查询提示一直是个很有争议的东西,因为他影响了sql server 自己选择执行计划.很多人在问是否应该使用查询提示的时候一般会被告知慎用或不要使用...但是个人认为善用提示在不修改语句的条件下,是常用 ...

  8. 【腾讯Bugly干货分享】Android进程保活招式大全

    本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57ac4a0ea374c75371c08ce8 作者:腾讯——张兴华 目前市面上 ...

  9. Linux环境下shell和vim中乱码原因及消除办法

    shell和vim中乱码原因及消除办法 作者:Jack47 在Linux下开发,经常遇到乱码问题:shell或者vim中显示不了中文,或者能够显示,但不能输入中文.每次都是上网去搜,或者同事告诉我一些 ...

  10. 「微信小程序」来了

    ps:微信APP Store.微信小程序.微信应用号都是指同一个事情. 苦逼程序猿刚下班到家,还没来得及洗漱,收到条小道消息的推送.于是我有气无力的拿着手机点开了这条推送消息,映入眼帘的就是这张封面图 ...