第六个工具类,TimeTool

用于秒精度的时间获取:距离一个参考时间所经历的秒数,用于时间戳

以及计算两个时间戳,按照特定时间分割点分割后的差值

比如:一般游戏项目中通常都会有这样的需求:

某个任务,1周之内只能接取5次,周6早上6点算下一周开始,次数清零,

某个活动,每月5号开启下一轮

等等

所以通常就会存在需要计算玩家的本次操作(比如申请接任务),距离 上一次操作(上一次的接任务),以一个特定时间点为分界(周6早上6点),是否是同一小时/天/周/月,经过了几小时/天/周/月

首先,一般用time(NULL),取当前时间距离1970/1/1 00:00:00 所经历的总秒数, 作为时间戳

但是需要注意的是这个time(NULL)都是UTC时间

如果,需求是比如周6早上6点算下一周,这个显然说的是我们东八区的时间,相对于time(NULL)还存在一个时区转换的问题

怎么算:

假设玩家 2016/12/30(周5) 20:00:00接的任务,服务端这边记录了一个时间戳 t1

玩家 2016/12/31(周6)07:00:00再次接任务,服务端这边记录了一个时间戳 t2

t1和t2都是time(NULL)得到的UTC时间

而1970/1/1是周四,1970/1/5是周一

为了计算周数,将t1,和t2,减去4天,得到一个秒数,这个秒数即为距离UTC时间1970/1/5 00:00:00 所经历的总秒数

需求要求是周六,

再将t1,和t2,减去(6-1)天,得到一个秒数,这个秒数即为距离UTC时间1970/1/10 00:00:00 所经历的总秒数

而东八区的早上6点,即UTC时间的前一天晚上22点

再将t1,和t2,加上2小时,得到一个秒数这个秒数即为距离UTC时间的1970/1/9 22:00:00(东八区时间1970/1/10 06:00:00 周六)所经历的总秒数

以这个时间做为第一周的开始

将t1,和t2,分别除以7天,则得到距离UTC时间的1970/1/9 22:00:00所经历的总周数

如果这两个周数相等,则这两个时间,以东八区的周6早上6点为界,属于同一周

是否属于同一天类似,但是就不用偏移到周一了,就用1月1号作为参考时间,转换一下时区,然后除以24小时就好了

是否属于同一小时,也类似,而且这个不存在时区问题,更简单,直接算

是否属于同一个月,这个不能用上面的方法来算了,因为每个月的天数是不一样的

只能将时间戳,用localtime(),转换成本地时间的年月日时分秒

比如每个月的5号早上6点,

则将时间戳,减去5天6小时,以每个月的5号早上6点做为一个月的开始

减完之后,转成本地时间,得到年月,

然后年数×12+月数,算出来的就是距离东八区的1970/1/5 06:00:00 的总月数

月数相等则为同一周

但是这个依然存在一个问题,就是分割用的时间,不能大于28号,因为2月只有28天

如果用比如30号做为分割的话,3月的1号,2号就会被算到2月去

示例代码:

以2分2秒为界

以2时2分2秒为界

以周2,2时2分2秒为界

以2号,2时2分2秒为界

分别判断是否属于同一个小时/天/周/月

int main(int argc, char* argv[])
{
#define SetTm(number, year, mon, day, hour, min, sec) \tm##number.tm_year = year - 1900; \tm##number.tm_mon = mon - 1; \tm##number.tm_mday = day; \tm##number.tm_hour = hour; \tm##number.tm_min = min; \tm##number.tm_sec = sec; \t##number = mktime(&tm##number);#define PrintTM \std::cout << \(tm1.tm_year + 1900) << "/" << (tm1.tm_mon + 1) << "/" << tm1.tm_mday << " " << tm1.tm_hour << ":" << tm1.tm_min << ":" << tm1.tm_sec << \" -> " << \(tm2.tm_year + 1900) << "/" << (tm2.tm_mon + 1) << "/" << tm2.tm_mday << " " << tm2.tm_hour << ":" << tm2.tm_min << ":" << tm2.tm_sec << \std::endl;#define PrintHour \PrintTM \std::cout << \"IsDifferentHour " << TimeTool::IsDifferentHour(t1, t2, 2, 2) << \", " << \"GetDeltaHour " << TimeTool::GetDeltaHour(t1, t2, 2, 2) << \std::endl;#define PrintDay \PrintTM \std::cout << \"IsDifferentDay " << TimeTool::IsDifferentDay(t1, t2, 2, 2, 2) << \", " << \"GetDeltaDay " << TimeTool::GetDeltaDay(t1, t2, 2, 2, 2) << \std::endl;#define PrintWeek \PrintTM \std::cout << \"IsDifferentWeek " << TimeTool::IsDifferentWeek(t1, t2, 2, 2, 2, 2) << \", "<< \"GetDeltaWeek " << TimeTool::GetDeltaWeek(t1, t2, 2, 2, 2, 2) << \std::endl;#define PrintMonth \PrintTM \std::cout << \"IsDifferentMonth " << TimeTool::IsDifferentMonth(t1, t2, 2, 2, 2, 2) << \", " << \"GetDeltaMonth " << TimeTool::GetDeltaMonth(t1, t2, 2, 2, 2, 2) << \std::endl;tm tm1;tm tm2;time_t t1;time_t t2;SetTm(1, 2017, 1, 1, 23, 59, 59);SetTm(2, 2017, 1, 2, 0, 0, 0);PrintHour;SetTm(1, 2017, 1, 1, 23, 59, 59);SetTm(2, 2017, 1, 2, 0, 2, 1);PrintHour;SetTm(1, 2017, 1, 1, 23, 59, 59);SetTm(2, 2017, 1, 2, 0, 2, 2);PrintHour;SetTm(1, 2017, 1, 1, 23, 59, 59);SetTm(2, 2017, 1, 2, 1, 2, 2);PrintHour;std::cout << std::endl;SetTm(1, 2017, 1, 1, 23, 59, 59);SetTm(2, 2017, 1, 2, 0, 0, 0);PrintDay;SetTm(1, 2017, 1, 1, 23, 59, 59);SetTm(2, 2017, 1, 2, 2, 2, 1);PrintDay;SetTm(1, 2017, 1, 1, 23, 59, 59);SetTm(2, 2017, 1, 2, 2, 2, 2);PrintDay;SetTm(1, 2017, 1, 1, 23, 59, 59);SetTm(2, 2017, 1, 3, 2, 2, 2);PrintDay;std::cout << std::endl;SetTm(1, 2017, 1, 1, 23, 59, 59);SetTm(2, 2017, 1, 3, 0, 0, 0);PrintWeek;SetTm(1, 2017, 1, 1, 23, 59, 59);SetTm(2, 2017, 1, 3, 2, 2, 1);PrintWeek;SetTm(1, 2017, 1, 1, 23, 59, 59);SetTm(2, 2017, 1, 3, 2, 2, 2);PrintWeek;SetTm(1, 2017, 1, 1, 23, 59, 59);SetTm(2, 2017, 1, 10, 2, 2, 2);PrintWeek;std::cout << std::endl;SetTm(1, 2017, 1, 1, 23, 59, 59);SetTm(2, 2017, 1, 2, 0, 0, 0);PrintMonth;SetTm(1, 2017, 1, 1, 23, 59, 59);SetTm(2, 2017, 1, 2, 2, 2, 1);PrintMonth;SetTm(1, 2017, 1, 1, 23, 59, 59);SetTm(2, 2017, 1, 2, 2, 2, 2);PrintMonth;SetTm(1, 2017, 1, 1, 23, 59, 59);SetTm(2, 2017, 2, 1, 2, 2, 2);PrintMonth;SetTm(1, 2017, 1, 1, 23, 59, 59);SetTm(2, 2017, 2, 2, 2, 2, 2);PrintMonth;return 0;
}

结果截图

最后完整代码:

TimeTool.h

#ifndef __TimeTool_h__
#define __TimeTool_h__#include <time.h>namespace common{namespace tool{class TimeTool{public:// 返回距离UTC时间1970/1/1 00:00:00的总秒数static time_t GetCurrSecond();// 返回本地日历日期,用于取年月日时分秒// t为GetCurrSecond获取到的UTC时间static tm GetDateTime(time_t t);// 返回当前本地日历日期,用于取年月日时分秒static tm GetCurrDateTime();// M分S秒为界(M分S秒之前算前一小时),返回两个秒数之间,相差几小时// t1,t2:   GetCurrSecond获取到的UTC时间// m:     0 ~ 59// s:     0 ~ 59static unsigned int GetDeltaHour(time_t t1, time_t t2, unsigned int m, unsigned int s);// 以东八区时间每天H时M分S秒为界(H时M分S秒之前算前一天),返回两个秒数之间,相差几天// t1,t2:   GetCurrSecond获取到的UTC时间// h:     0 ~ 23,东八区时间// m:        0 ~ 59// s:     0 ~ 59static unsigned int GetDeltaDay(time_t t1, time_t t2, unsigned int h, unsigned int m, unsigned int s);// 以东八区时间每周星期W,H时M分S秒为界(星期W,H时M分S秒之前算上一周),返回两个秒数之间,相差几周// t1,t2:  GetCurrSecond获取到的UTC时间// w:     1 ~ 7,东八区时间// h:     0 ~ 23,东八区时间// m:        0 ~ 59// s:     0 ~ 59static unsigned int GetDeltaWeek(time_t t1, time_t t2, unsigned int w, unsigned int h, unsigned int m, unsigned int s);// 以东八区时间每月D号,H时M分S秒为界(D号,H时M分S秒之前算上一个月),返回两个秒数之间,相差几个月// t1,t2: GetCurrSecond获取到的UTC时间// d:     1 ~ 28,东八区时间// h:        0 ~ 23,东八区时间// m:        0 ~ 59// s:     0 ~ 59static unsigned int GetDeltaMonth(time_t t1, time_t t2, unsigned int d, unsigned int h, unsigned int m, unsigned int s);// M分S秒为界(M分S秒之前算前一小时),判断两个秒数是否是同一小时// t1,t2:    GetCurrSecond获取到的UTC时间// m:     0 ~ 59// s:     0 ~ 59static bool IsDifferentHour(time_t t1, time_t t2, unsigned int m, unsigned int s);// 以东八区时间每天H时M分S秒为界(H时M分S秒之前算前一天),判断两个秒数是否是同一天// t1,t2:    GetCurrSecond获取到的UTC时间// h:     0 ~ 23,东八区时间// m:        0 ~ 59// s:     0 ~ 59static bool IsDifferentDay(time_t t1, time_t t2, unsigned int h, unsigned int m, unsigned int s);// 以东八区时间每周星期W,H时M分S秒为界(星期W,H时M分S秒之前算上一周),判断两个秒数是否是同一周// t1,t2:   GetCurrSecond获取到的UTC时间// w:     1 ~ 7,东八区时间// h:     0 ~ 23,东八区时间// m:        0 ~ 59// s:     0 ~ 59static bool IsDifferentWeek(time_t t1, time_t t2, unsigned int w, unsigned int h, unsigned int m, unsigned int s);// 以东八区时间每月D号,H时M分S秒为界(D号,H时M分S秒之前算上一个月),判断两个秒数是否是同一月// t1,t2:   GetCurrSecond获取到的UTC时间// d:     1 ~ 28,东八区时间// h:        0 ~ 23,东八区时间// m:        0 ~ 59// s:     0 ~ 59static bool IsDifferentMonth(time_t t1, time_t t2, unsigned int d, unsigned int h, unsigned int m, unsigned int s);// 将       距离UTC时间1970/1/1 00:00:00的总秒数// 换算成  距离UTC+8时间1970/1/1 h:m:s的总秒数// t:       GetCurrSecond获取到的UTC时间// h:     0 ~ 23,东八区时间// m:        0 ~ 59// s:     0 ~ 59static time_t GetHMS_Utc8(time_t t, unsigned int h, unsigned int m, unsigned int s);// 将      距离UTC时间1970/1/1 00:00:00的总秒数// 换算成  距离UTC+8时间1970/1/(5+w-1) h:m:s的总秒数,1970/1/5为周一// t:     GetCurrSecond获取到的UTC时间// w:     1 ~ 7,东八区时间// h:     0 ~ 23,东八区时间// m:        0 ~ 59// s:     0 ~ 59static time_t GetWHMS_Utc8(time_t t, unsigned int w, unsigned int h, unsigned int m, unsigned int s);};}
}#endif

TimeTool.cpp

#include "TimeTool.h"namespace common{namespace tool{time_t TimeTool::GetCurrSecond(){return time(NULL);}tm TimeTool::GetDateTime(time_t t){tm tm = *localtime(&t);tm.tm_year += 1900;  /* years since 1900 */tm.tm_mon += 1;     /* months since January - [0,11] */return tm;}tm TimeTool::GetCurrDateTime(){time_t t = GetCurrSecond();return GetDateTime(t);}unsigned int TimeTool::GetDeltaHour(time_t t1, time_t t2, unsigned int m, unsigned int s){if (t1 != t2){// 参数校验if (m > 59 || s > 59){m = 0;s = 0;}// 更换参考时间t1 = t1 - (m * 60 + s);t2 = t2 - (m * 60 + s);// 换算成小时t1 = t1 / (60 * 60);t2 = t2 / (60 * 60);// 计算小时数的差值if (t1 > t2){return static_cast<unsigned int>(t1 - t2);}else if (t1 < t2){return static_cast<unsigned int>(t2 - t1);}else{return 0;}}else{return 0;}}unsigned int TimeTool::GetDeltaDay(time_t t1, time_t t2, unsigned int h, unsigned int m, unsigned int s){if (t1 != t2){// 参数校验if (h > 23 || m > 59 || s > 59){h = 0;m = 0;s = 0;}// 更换参考时间t1 = GetHMS_Utc8(t1, h, m, s);t2 = GetHMS_Utc8(t2, h, m, s);// 换算成天数t1 = t1 / (24 * 60 * 60);t2 = t2 / (24 * 60 * 60);// 计算天数的差值if (t1 > t2){return static_cast<unsigned int>(t1 - t2);}else if (t1 < t2){return static_cast<unsigned int>(t2 - t1);}else{return 0;}}else{return 0;}}unsigned int TimeTool::GetDeltaWeek(time_t t1, time_t t2, unsigned int w, unsigned int h, unsigned int m, unsigned int s){if (t1 != t2){// 参数校验if (w < 1 || w > 7 || h > 23 || m > 59 || s > 59){w = 1;h = 0;m = 0;s = 0;}// 更换参考时间t1 = GetWHMS_Utc8(t1, w, h, m, s);t2 = GetWHMS_Utc8(t2, w, h, m, s);// 换算成周数t1 = t1 / (7 * 24 * 60 * 60);t2 = t2 / (7 * 24 * 60 * 60);// 计算周数的差值if (t1 > t2){return static_cast<unsigned int>(t1 - t2);}else if (t1 < t2){return static_cast<unsigned int>(t2 - t1);}else{return 0;}}else{return 0;}}unsigned int TimeTool::GetDeltaMonth(time_t t1, time_t t2, unsigned int d, unsigned int h, unsigned int m, unsigned int s){if (t1 != t2){// 参数校验if (d < 1 || d > 28 || h > 23 || m > 59 || s > 59){d = 1;h = 0;m = 0;s = 0;}// 更换参考时间,以d号h时m分s秒为参考时间// 不考虑时区,后面就是以本地时间计算t1 = t1 - ((d - 1) * 24 * 60 * 60 + h * 60 * 60 + m * 60 + s);t2 = t2 - ((d - 1) * 24 * 60 * 60 + h * 60 * 60 + m * 60 + s);// 转化为本地时间tm tm1 = *localtime(&t1);tm tm2 = *localtime(&t2);// 换算成月数t1 = tm1.tm_year * 12 + tm1.tm_mon;t2 = tm2.tm_year * 12 + tm2.tm_mon;if (t1 > t2){return static_cast<unsigned int>(t1 - t2);}else if (t1 < t2){return static_cast<unsigned int>(t2 - t1);}else{return 0;}}else{return 0;}}bool TimeTool::IsDifferentHour(time_t t1, time_t t2, unsigned int m, unsigned int s){return 0 != GetDeltaHour(t1, t2, m, s);}bool TimeTool::IsDifferentDay(time_t t1, time_t t2, unsigned int h, unsigned int m, unsigned int s){return 0 != GetDeltaDay(t1, t2, h, m, s);}bool TimeTool::IsDifferentWeek(time_t t1, time_t t2, unsigned int w, unsigned int h, unsigned int m, unsigned int s){return 0 != GetDeltaWeek(t1, t2, w, h, m, s);}bool TimeTool::IsDifferentMonth(time_t t1, time_t t2, unsigned int d, unsigned int h, unsigned int m, unsigned int s){return 0 != GetDeltaMonth(t1, t2, d, h, m, s);}time_t TimeTool::GetHMS_Utc8(time_t t, unsigned int h, unsigned int m, unsigned int s){// 如:东八区时间的:9时30分30秒,则为UTC时间的:1时30分30秒(参考时间往后偏移,总秒数减少)// 如:东八区时间的:7时30分30秒,则为UTC时间的前一天:23时30分30秒(参考时间往前偏移,总秒数增加)unsigned int deltaT = h * 60 * 60 + m * 60 + s;unsigned int delta8 = 8 * 60 * 60;if (delta8 <= deltaT){t = t - (deltaT - delta8);}else{t = t + (delta8 - deltaT);}return t;}time_t TimeTool::GetWHMS_Utc8(time_t t, unsigned int w, unsigned int h, unsigned int m, unsigned int s){t = GetHMS_Utc8(t, h, m, s);// 1970/1/1 为周4// 1970/1/5 为周1// 换算成距离1970/1/5 h:m:s的总秒数,即减4天t = t - 4 * 24 * 60 * 60;// 换算成距离星期W,即距离1970/1/(5+w-1) h:m:s的总秒数,即减(w-1)天t = t - (w - 1) * 24 * 60 * 60;return t;}}
}

工具类库系列(六)-TimeTool相关推荐

  1. 工具类库系列(一)-StringTool

    好久没写了,最近闲了下来,把这段时间的代码整理整理,将常用的代码按功能整理成一些静态库,便于以后复用 今天是第一个库:libtool,其实就是一些工具类的集合 第一个工具类:StringTool st ...

  2. 工具类库系列(四)-CsvReader

    第四个工具类:CsvReader CsvReader是用来支持读取Csv表格用的 Csv格式其实就是一个有固定格式的txt,一行每一列用英文','隔开 游戏项目中,很多游戏静态表.策划提供的是Csv表 ...

  3. 编写更少量的代码:使用apache commons工具类库

    Commons-configuration Commons-FileUploadCommons DbUtilsCommons BeanUtils Commons CLI Commons CodecCo ...

  4. Silverlight Blend动画设计系列六:动画技巧(Animation Techniques)之对象与路径转化、波感特效...

    原文:Silverlight & Blend动画设计系列六:动画技巧(Animation Techniques)之对象与路径转化.波感特效 当我们在进行Silverlight & Bl ...

  5. 实用工具类库java.util

    本章介绍Java的实用工具类库java.util包.在这个包中,Java提供了一些实用的方法和数据结构.例如,Java提供日期(Data)类.日历(Calendar)类来产生和获取日期及时间,提供随机 ...

  6. 数学之美系列六 -- 图论和网络爬虫 (Web Crawlers)

    数学之美系列六 -- 图论和网络爬虫 (Web Crawlers) [离散数学是当代数学的一个重要分支,也是计算机科学的数学基础.它包括数理逻辑.集合论.图论和近世代数四个分支.数理逻辑基于布尔运算, ...

  7. Web前端开发人员和设计师必读文章推荐【系列六】

    这篇文章收录了十一月份发布在梦想天空的优秀文章,特别推荐给Web开发人员和设计师阅读.梦天空博客关注前端开发技术,展示最新HTML5和CSS3技术应用,分享实用的jQuery插件,推荐优秀的网页设计案 ...

  8. ONNX系列六 --- 在Java中使用可移植的ONNX AI模型

    目录 安装和导入ONNX运行时 载入ONNX模型 使用ONNX运行时进行预测 摘要和后续步骤 参考文献 下载源547.1 KB 系列文章列表如下: ONNX系列一 --- 带有ONNX的便携式神经网络 ...

  9. 推荐一款优秀的国内开源工具类库Hutool,让你的代码量减少90%

    文章目录 一.常用的工具类库有哪些?为啥我要推荐Hutool? 二.Hutool简介 三. Hutool如何改变我们的coding方式 四.包含组件 五.使用示例 六.Hutool结构概述 一.常用的 ...

  10. Android基于Retrofit2.0 +RxJava 封装的超好用的RetrofitClient工具类(六)

    csdn :码小白 原文地址: http://blog.csdn.net/sk719887916/article/details/51958010 RetrofitClient 基于Retrofit2 ...

最新文章

  1. myeclipse 10创建maven项目
  2. CISCO ACL的匹配数问题
  3. 网站推广——seo优化对企业网站推广能力的提升有着不小的帮助
  4. Oracle对象之序列
  5. C#中更改DataTable某列的值,格式化显示指定列的数据
  6. python语言程序设计慕课_中国大学MOOC(慕课)_Python语言程序设计基础_试题及答案...
  7. 当代开发者的六大真实现状,你被哪一个场景“戳中”了?
  8. 京东抢购机器人_戴森、科沃斯、SKG...超多大牌低价秒杀!京东电器等你来
  9. 徽柏工业机器人_国产工业机器人龙头企业,是这家徽商!
  10. 太难了!线下教培受重创,这家企业无奈宣布全员工资3.5折5个月
  11. python能做哪些方面的准备_学习pyhton需要做哪些准备工作
  12. vs新建一个excelpackage时间太长_炖牛肉vs煎牛肉,前者几小时后者几分钟,大厨告诉了我原因...
  13. OSChina 周六乱弹 —— 表白有风险,装逼需谨慎
  14. TestRange.cs error CS0104: `Range' is an ambiguous reference between `System.Range' and Gtk.Range
  15. QFIL的烧录、读写
  16. 九个实用的Word转PDF的方法,为你解决格式转换的问题
  17. 前端学习从入门到高级全程记录之31(JavaScript高级3)
  18. 计算机主板启动显示器黑屏,电脑开机显示器黑屏怎么回事_开机显示器黑屏怎么解决...
  19. MAC 虚拟机配置静态IP
  20. Caffe新手教程傻瓜系列(9):训练和测试自己的图片

热门文章

  1. linux wireshark 中文,Wireshark (简体中文)
  2. [MATLAB]线性方程组应用--小行星运行轨道计算问题
  3. c# 时间戳的使用,日期判定(时间戳获取、 时间戳和DateTime的转换、时差计算)
  4. php http请求 返回数据包太大 499,http错误码原理及复现 - 499,500,502,504
  5. 2019圣诞节 — 徒步看风景
  6. 经营项目计算机、软件及辅助设备、
  7. windows7 安装pytorch简易教程
  8. 分享三大外汇日内交易策略
  9. html5+开启摄像头,双摄像头时如何通过html5选择打开哪个摄像头_沃航科技
  10. java+selenium键盘操作