由一个时间戳计算这个时间戳所属的一周

由一个时间戳得到这个时间戳所属的一周

1. 缘由

开发遇到一个需求,需要由一个linux时间戳,计算出这个时间戳所处于的一周的每一天,具体实现:先由linux系统调用将这个时间戳转换为具体的年月日,再根据这天是周几,不断往前递减一天直到周一,同理再往后不断+1天,直到周日,编码时主要的难点是考虑边界条件:润平年、2月份。

2.编码实现

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <assert.h>
#include <stdbool.h>

#define WEEK_MAX  7

 //润平年每个月份的天数
const int dayofmonth[2][12] = {{31,28,31,30,31,30,31,31,30,31,30,31},{31,29,31,30,31,30,31,31,30,31,30,31}};

//润平年判断
bool Leapyear(int year)
{
	if ( ((0 == year%4) && (0 != year%100)) ||(0 == year %400) )
	{
		return true;
	}
	
	return false;
}
 
//这个接口只是通过具体的年月日+设定的时分秒统一为5后,转化成时间戳,
int spectime2LinuxTime(int year, int month, int day)
{
	int time;
	struct tm tm_t;	//xxxx-xx-xx 05:05:05 
	memset(&tm_t,0,sizeof(struct tm));
	
	tm_t.tm_sec = 5;
	tm_t.tm_min = 5;
	tm_t.tm_hour = 5;
	
	tm_t.tm_mday = day;
	tm_t.tm_mon = month-1;
	tm_t.tm_year = year - 1900;
	time =(int)mktime(&tm_t);
	//printf("time:%d\n",time);
	return time;
}

bool getAWeekByOneDay(time_t time1,int *weekArray)
{
	int dayth1 = 0;
	int year = 0;
	int month = 0;
	int day = 0;
	int beyondCnt = 0;
	int backCnt = 0;
	time_t tmptime = 0;
	
#if 0		//结构体 struct tm的成员
	struct tm 
	{
		int tm_sec;    /* Seconds (0-60) */
		int tm_min;    /* Minutes (0-59) */
		int tm_hour;   /* Hours (0-23) */
		int tm_mday;   /* Day of the month (1-31) */
		int tm_mon;    /* Month (0-11) */
		int tm_year;   /* year - 1900 */
		int tm_wday;   /* Day of the week (0-6, Sunday = 0) */
		int tm_yday;   /* Day in the year (0-365, 1 Jan = 0) */
		int tm_isdst;  /* Daylight saving time */
	};
#endif

	int tmpday = 0,tmpmonth = 0,tmpyear = 0,tmpVardayth = 0;
	
	int tmpdayth1;
	int tmpseg1min;
	int tmpseg1max;	
	int leapIndex = 0;

	struct tm *tm1 = NULL;
	tm1 = localtime(&time1);
	
	year = tm1->tm_year + 1900;
 	month = tm1->tm_mon  + 1;	//1-12
 	day = 	tm1->tm_mday;		//1-31  day of the month
	
	dayth1 = ((tm1->tm_wday == 0)?7:tm1->tm_wday);			//day of week (0~6 : 周日~周六)

	tmpdayth1 = dayth1;				//((tm1->tm_wday == 0)?7:tm1->tm_wday);

	tmpseg1min = tmpdayth1 - 1;		//确定当前天处于星期几,往前推 tmpseg1min 天到星期一,往后推 tmpseg1max 天到星期日
	tmpseg1max = 7 - tmpdayth1;

	tmpmonth = 	month;
	tmpyear  = 	year;
	tmpday   = 	day;
	tmpVardayth = dayth1 -1;
	
	weekArray[tmpVardayth] = time1;//已知的当天日期先占位
	
	//(1).往前推,直至周一
	for (beyondCnt = 0 ; beyondCnt < tmpseg1min ; beyondCnt++)//将此天所处一周的位置逐一向前推一天直到周一
	{
		tmpday	-= 1;
		if (tmpday <= 0)
		{
			tmpmonth -= 1;
			if (tmpmonth <= 0)
			{
				tmpmonth = 12;
				tmpyear -= 1;
			}
    		
    		leapIndex = Leapyear(tmpyear)?1:0;
			tmpday = dayofmonth[leapIndex][tmpmonth-1];
		}
		
		if ((tmptime = spectime2LinuxTime(tmpyear,tmpmonth,tmpday)) < 0)
		{//不合法日期,直接返回
			return false;
		}
		else 
		{
			weekArray[--tmpVardayth] = tmptime;
		}
	}
	
	//归位
	tmpmonth = 	month;
	tmpyear  = 	year;
	tmpday   = 	day;
	tmpVardayth = dayth1 -1;
	
	//(2).往后推,直至周日
	for (backCnt = 0; backCnt < tmpseg1max; backCnt++)//将此天所处周的位置周几,逐一向后推一天直到周日
	{
		tmpday	+= 1;
		leapIndex = Leapyear(tmpyear)?1:0;
		if (tmpday > dayofmonth[leapIndex][tmpmonth-1])
		{
			tmpday = 1;
			tmpmonth += 1;
			if (tmpmonth > 12)
			{
				tmpmonth = 1;
				tmpyear += 1;
			}
		}
		
    	if ( ( weekArray[++tmpVardayth] = (spectime2LinuxTime(tmpyear,tmpmonth,tmpday))) < 0)
		{//不合法日期,直接返回
			return false;
		}
	}
	
	return true;
}	

void printDayOfWeek(int *weekArray)
{
    for (int i = 0 ; i < WEEK_MAX;++i)
    {
        printf("%d\n",weekArray[i]);
    }
    
    printf("\n\n");
}

int main()
{
	time_t time1,time2,time3,time4;
	
    //测试数据
	time1 = spectime2LinuxTime(2020,5,31); //2020-5-31 5:5:5
	time2 = spectime2LinuxTime(2000,4,30); //2000-4-30 5:5:5	
	time4 = spectime2LinuxTime(2020,1,12);	//2020-1-12 5:5:5	
	time3 = spectime2LinuxTime(2020,5,1);	//2020-5-1 5:5:5
	int weekArray[WEEK_MAX] = {0};
    
    //测试结果打印
	getAWeekByOneDay(time1,weekArray);
    printDayOfWeek(weekArray);
	
	getAWeekByOneDay(time2,weekArray);
    printDayOfWeek(weekArray);
	
	getAWeekByOneDay(time4,weekArray);
    printDayOfWeek(weekArray);
	
	getAWeekByOneDay(time3,weekArray);
    printDayOfWeek(weekArray);
	
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值