一组关于日期计算的代码

DateTime.h

#ifndef _DATE_TIME_H_
#define _DATE_TIME_H_

#ifdef __cplusplus
extern "C" {
#endif

#define YES 1
#define NO  0

	typedef struct _DateTime{
		unsigned short wSecond;     /* The current second - [0,59] */
		unsigned short wMinute;     /* The current minute - [0,59] */
		unsigned short wHour;		/* The current hour - [0,23] */
		unsigned short wDay;		/* The current day of the month - [1,31] */
		unsigned short wMonth;      /* The current month; January is 1 - [1,12] */
		unsigned short wYear;		/* The current year */
	}DateTime;

	int IsYearLeap(int year);						/* 判断year是不是闰年 */

	int IsDateValid(DateTime *date);				/* 判断日期是否正确, 不正确返回-1 */

	int LoadDateStruct(DateTime *date, int yy, int mm, int dd);		/* 填充DateTime结构体, 并判断日期参数是否正确, 不正确返回-1 */

	long DateToDayNumber(DateTime *date);			/* 把日期转换成天数 */

	int DayOfWeek(DateTime *date);					/* 给出当前日期是星期几 */

	int DayOfYear(DateTime *date);					/* 给出当前日期是这一年中的第几天 */

	long DateDiff(DateTime *d1, DateTime *d2);		/* 计算两个日期之间的天数差 */

	int DayNumberToDate(long int day_num, DateTime *date);	/* 把天数转换成日期 */

	double TimeDiff(DateTime *t1, DateTime *t2);			/* 计算两个时间之间差的秒数 */

#ifdef __cplusplus
};
#endif

#endif //~_DATE_TIME_H_

DateTime.c


#include "DateTime.h"

/* 定义PROLEPTIC代表忽略重大转变日期 */
#define PROLEPTIC

static const int Days_in_month[13] = {
	0,
	31, 28, 31,		/* Jan, Feb, Mar */
	30, 31, 30,		/* Apr, May, Jun */
	31, 31, 30,		/* Jul, Aug, Sep */
	31, 30, 31		/* Oct, Nov, Dec */
};

static const int Days_in_month_leap[13] = {
	0,
	31, 29, 31,		/* Jan, Feb, Mar */
	30, 31, 30,		/* Apr, May, Jun */
	31, 31, 30,		/* Jul, Aug, Sep */
	31, 30, 31		/* Oct, Nov, Dec */
};

static const char *Day_name[7] = {
	"Sunday", "Monday",
	"Tuesday", "Wednesday",
	"Thursday", "Friday",
	"Saturday"
};

static const char *Day_name_abbrev[7] = {
	"Sun", "Mon",
	"Tue", "Wed",
	"Thu", "Fri",
	"Sat"
};

static const char *Month_name[13] = {
	"",
	"January", "February", "March",
	"April", "May", "June",
	"July", "August", "September",
	"October", "November", "December"
};

static const char* Month_name_abbrev[13] = {
	"",
	"Jan", "Feb", "Mar",
	"Apr", "May", "Jun",
	"Jul", "Aug", "Sep",
	"Oct", "Nov", "Dec"
};

int IsYearLeap(int year)
{
	if(year % 4 != 0)
		return NO;

#ifndef PROLEPTIC
	if(year < 1582)		/* all years divisible by 4 were leap prior to 1582 */
		return YES;
#endif

	if(year % 100 != 0)
		return YES;

	if(year % 400 != 0)
		return NO;

	return YES;
}

int IsDateValid(DateTime *date)
{
	if(date->wMonth < 1 || date->wMonth > 12)
		return NO;

	if(date->wYear < 1)
		return NO;

	if(IsYearLeap(date->wYear) == NO)
	{
		if(date->wDay < 1 || date->wDay > Days_in_month[date->wMonth])
			return NO;
	}
	else 
	{
		if(date->wDay < 1 || date->wDay > Days_in_month_leap[date->wMonth])
			return NO;
	}

	return YES;
}

int LoadDateStruct(DateTime *date, int yy, int mm, int dd)
{
	date->wYear = yy;
	date->wMonth = mm;
	date->wDay = dd;

	if(IsDateValid(date) == NO)
		return -1;

	return 0;
}

long DateToDayNumber(DateTime *date)
{
	long day_num;
	int mm, yy;

	if(IsDateValid(date) == NO)
		return -1;

	yy = date->wYear;
	mm = date->wMonth;

	/* get all the regular days in preceding years */
	day_num = (yy - 1) * 365L;

	/* now get the leap years */
	day_num += (yy - 1) / 4L;

	/* now back out the century years that are not leap:
	this would be all century years that are not 
	evenly divisible by 400: 1700, 1800, 1900, 2100 ... */

	day_num -= (yy - 1) / 100L;
	day_num += (yy - 1) / 400L;

#ifndef PROLEPTIC
	/* before 1582 all century years were leap, so adjust for this.
	If year is > 1582, then just all 12 days for years 100, 200, 300,
	500, 600, 700, 900, 1000, 1100, 1300, 1400 and 1500. Otherwise, 
	calculate it. */

	if((yy - 1) > 1582)
		day_num += 12L;
	else
	{
		day_num += (yy - 1) / 100L;
		day_num -= (yy - 1) / 400L;
	}
#endif

	/* now, add the days elapsed in the year so far */
	if(IsYearLeap(date->wYear) == NO)
	{
		while(--mm)
			day_num += Days_in_month[mm];
	}
	else
	{
		while(--mm)
			day_num += Days_in_month_leap[mm];
	}

	/* add days in current month for the year being evaluated */
	day_num += date->wDay;

#ifndef PROLEPTIC
	/* now adjust for the 10 days cut out of the calender when 
	the chang was made to the Gregorian calendar. this change
	reflects the jump from October 4 to October 15, 1582, a 
	deletion of 10 days. */

	if(day_num > 577737L)
		day_num -= 10L;
#endif

	return day_num;
}

int DayOfWeek(DateTime *date)
{
	long day_num = DateToDayNumber(date);

	if(day_num < 0)
		return -1;

	return (int)(day_num % 7);
}

int DayOfYear(DateTime *date)
{
	DateTime jan1;
	if(LoadDateStruct(&jan1, date->wYear, 1,1) == -1)
		return -1;

	return (int)(DateDiff(date, &jan1) + 1);
}

long DateDiff(DateTime *d1, DateTime *d2)
{
	return DateToDayNumber(d1) - DateToDayNumber(d2);
}

int DayNumberToDate(long int day_num, DateTime *date)
{
	int dd, mm, yy, i;
	long days_left;

#ifndef PROLEPTIC
	if(day_num > 577737L)
		day_num += 10L;
#endif

	yy = (int)(day_num / 365L);
	days_left = day_num % 365L;

#ifndef PROLEPTIC
	/* prior to 1700, all years evenly divisible by 4 are leap */
	if(yy < 1700)
		days_left -= (yy / 4);
	else
	{
		days_left -= (yy / 4);
		days_left += (yy / 100);
		days_left -= (yy / 400);
		days_left -= 12;
	}
#else
	days_left -= (yy / 4);
	days_left += (yy / 100);
	days_left -= (yy / 400);
#endif

	/* make sure days left is > 0 */
	while(days_left <= 0)
	{
		if(IsYearLeap(yy) == YES)
		{
			yy -= 1;
			days_left += 366;
		}
		else
		{
			yy -= 1;
			days_left += 365;
		}
	}

	/* yy holds the number of elapsed years.
	so, add 1 for the current year. */
	yy += 1;

	/* now deduct the days in each month, starting
	from January to find month and day of month.
	adjust for leap year, of course. */

	dd = (int) days_left;
	mm = 0;

	if(IsYearLeap(yy) == YES)
	{
		for(i = 1; i <= 12; i++)
		{
			mm = i;
			if(dd <= Days_in_month_leap[i])
				break;
			else
				dd -= Days_in_month_leap[i];
		}
	}
	else
	{
		for(i = 1; i <= 12; i++)
		{
			mm = i;
			if(dd <= Days_in_month[i])
				break;
			else
				dd -= Days_in_month[i];
		}
	}

	return LoadDateStruct(date, yy, mm, dd);
}

double TimeDiff(DateTime *t1, DateTime *t2)
{
	long day_num;
	double d1, d2;

	day_num = DateToDayNumber(t1);
	d1 = day_num * 86400.0 + t1->wHour * 3600.0 + t1->wMinute * 60.0 + t1->wSecond;

	day_num = DateToDayNumber(t2);
	d2 = day_num * 86400.0 + t2->wHour * 3600.0 + t2->wMinute * 60.0 + t2->wSecond;

	return d1 - d2;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值