基于C++实现以周为时间段的简易日期获取机制

1.背景

在很多业务场景中,都有一个类似于每周计划/每周任务的功能,比如游戏中玩家每周都有一定的任务需要完成来获取奖励。这里就需要即使用户客户端时间不同,在服务端也要根据统一时间来进行判断。

2.需求

这套机制需要尽可能的高效快速,并且易于维护,不需要经常修改配置使其满足各种时间过程,例如每周过渡、每月过渡、每年过渡等等。

3.实现

该机制的实现主要有几个方面:

  • 使得本周的判断有独立性、唯一性,防止与其他周的混淆。

  • 能够计算本周开始到现在的每日日期信息,从而进行其他日期有关操作。

本机制使用的周数是基于unix时间戳(Unit timestamp)来制定的。具体步骤如下:

  1. 获取当前时间戳,使用C++中的time方法
time_t cur_time = time(NULL);

2.计算本周的index

int week_index = (cur_time + (8 * 3600) + (3 * 24 * 3600) ) / (60 * 60 * 24 * 7);

公式解析:
+( 8 * 3600) 表示时区偏差。若当前位于东八区北京时间,而unix时间戳是基于标准格林尼治时间,所以如果本机服务位于北京时间需要这一偏移来调整至标准时间,否则在程序运行时直到早上八点才会切换至下一周期,这与预期是不符的。这一时间也需要根据服务所在地区来调整
+(3 * 24 * 3600) 表示周偏差。查看日历可以得知unix时间戳起始之日即1970-01-01是一个星期四,在本机制中每周定义为周一开始至周日,所以需要加上三天的偏差使得判断处于正常周期内。
(60 * 60 * 24 * 7)是一周的秒数,根据分子中的秒数除该秒数即可得到准确周数。

计算出本周的周数可以以周的范围来制定一些数据,例如周任务的奖励领取情况便可以以周数将数据唯一地保存下来。而如果想要获取本周任务的完成情况,而任务数据又分布在每日数据中的话,就需要将范围缩小在一周内。

1.获取C++中tm结构体的当前时间

struct tm* tm = localtime(&cur_time);

C++中tm是一种保存时间的各种信息的结构体,非常实用,结构体具体内容如下:

struct tm {
        int tm_sec;     /* seconds after the minute - [0,59] */
        int tm_min;     /* minutes after the hour - [0,59] */
        int tm_hour;    /* hours since midnight - [0,23] */
        int tm_mday;    /* day of the month - [1,31] */
        int tm_mon;     /* months since January - [0,11] */
        int tm_year;    /* years since 1900 */
        int tm_wday;    /* days since Sunday - [0,6] */
        int tm_yday;    /* days since January 1 - [0,365] */
        int tm_isdst;   /* daylight savings time flag */
        };

在这个结构体中的tm_wday属性是我们需要的,但是这一属性根据西方的习惯起始于周天,所以我们在使用时需要一定的修改。

2.根据当前日期处于本周的第几天来向前循环


int real_week_day = tm->tm_wday;
int real_month_day = tm->tm_mday;
int real_year_day = tm->tm_yday;

//取出tm->tm_wday时,周天是0,但是我们需要遍历整个周,
//所以我们用求余来使得周一到周日的日期正常
int total_week_day =( real_week_day + 6 ) % 7;	

for (int i = 0; i <= total_week_day; i++)
	{
		//从当前日期向前循环
		//当i为0时计算的是今天
		tm->tm_wday = tm->tm_wday - (i > 0 ? 1 : 0 );
		tm->tm_mday = tm->tm_mday - (i > 0 ? 1 : 0 );
		tm->tm_yday = tm->tm_yday - (i > 0 ? 1 : 0 );

		//利用mktime方法可以在修改结构体中的个别数据后重新生成一个时间戳
		int a = mktime(tm);
		CTime t = CTime(a);
		//根据时间戳来获取对应日期
		int cycle_date = atoi(t.Format("%Y%m%d"));

		//具体业务blablabla,比如根据日期取出当天数据
	}

如有改进,请留言与我互动^^_

发布了3 篇原创文章 · 获赞 4 · 访问量 1522

猜你喜欢

转载自blog.csdn.net/weixin_41880150/article/details/104773321