没有gmttime&localtime api调用,怎么办?

    在嵌入式开发上,又遇到过没有标准c api使用的情况没有?肯定有!

#include <stdio.h>
#include <string.h>
#include <time.h>
typedef struct 
{
        int tm_sec;    /* 秒 – 取值区间为[0,59] */
        int tm_min;    /* 分 - 取值区间为[0,59] */
        int tm_hour;    /* 时 - 取值区间为[0,23] */
        int tm_mday;   /* 一个月中的日期 - 取值区间为[1,31] */
        int tm_mon;    /* 月份(从一月开始,0代表一月) - 取值区间为[0,11] */
        int tm_year;    /* 年份,其值等于实际年份减去1900 */
        int tm_wday;    /* 星期 – 取值区间为[0,6],其中0代表星期天,1代表星期一,以此类推 */
        int tm_yday;   /* 从每年的1月1日开始的天数 – 取值区间为[0,365],其中0代表1月1日,1代表1月2日,以此类推 */
        int tm_isdst;   /* 夏令时标识符,实行夏令时的时候,tm_isdst为正。不实行夏令时的进候,tm_isdst为0;不了解情况时,tm_isdst()为负。*/ 
}my_tm_t;

/*
	seconds 是从1970年1月1日utc时间0时0分0秒到某一时刻的总秒数
	正常情况下函数返回指针就是参数指针local_time,非正常情况为null

*/
my_tm_t *my_gmtime(unsigned long seconds, my_tm_t *gmt_time) 
{
	const char mons[]={31,28,31,30,31,30,31,31,30,31,30};
    register unsigned long time = seconds;
    register int islpyr, lpcnt;
    register int y, ystart, i, t;

	if(gmt_time==NULL)
	{
		return NULL;
	}
	memset(gmt_time,0x00,sizeof(my_tm_t));
	gmt_time->tm_isdst= -1;

	i=time;	
	while (i<0)
	{
		i+= 7L*24*60*60*1000;    /* preserve the day of the week */
	}

	i = (i/(24*60*60))%7-3;		
	while (i<0)
	{
		i += 7;
	}

	gmt_time->tm_wday = i;
		
	i = time % (24l*60*60);
	if ( i<0 ) 
	{
		i = i+24l*60*60;
	}

	gmt_time->tm_hour = (i/(60*60))%24;
	gmt_time->tm_min = (i/60)%60;
	gmt_time->tm_sec = i%60;

	y = time/(365*24*60*60+6*60*60);        /* a year is about 365.25 days */
	y += 370;

	do 
	{
		islpyr = y%4==0 && (y%100!=0 || y%400==0);
		lpcnt = y/4;
		lpcnt -= y/100;
		lpcnt += y/400;

		lpcnt -= 89;            /* number of leap years in 370 years */
		ystart = (y-370)*(365*24*60*60) + lpcnt*(24*60*60);
		if ( ystart>time )
		{
	    		--y;
		}
    } while ( ystart>time );    /* should loop at most twice, at least once */

	time -= ystart;
	time /= 24*60*60;
/* [JY] Tue Jan  3 14:24:47 PST 1995.  was possible to get 12/32/94 from this.*/
/* If we get here with time of 365, this will happen.  Simply set the day to */
/* zero and increment the year.  This should work. */
	if ( time == 365 ) 
	{
		time=0;
		y++;
	}
/* end of new code */
	if ( islpyr )
	{
		++ time;
	}

	gmt_time->tm_yday= time;
	
	++ time;
	for ( i=0; i<11; ++i )
	{
		t = mons[i];
		if ( i==1 && islpyr )
		{
	    		++t;
		}
		if ( time<=t )
		{
	    		break;
		}
		time -= t;
    }

    gmt_time->tm_year = y-300;
    gmt_time->tm_mon  = i;
    gmt_time->tm_mday = time;        /* we incremented the mday above */
    return(gmt_time);
}

/*
    If no other implementation provided, assume Epoch is 00:00:00 January 1,1970
    as is true in UNIX.

    There should be code in here to calculate daylight savings time in different
    ways than the one given here.  Which is true for USA as of 1987.

    The rules I follow are:
	before 1987
	    at 2am of the last sunday of april dst starts
	    at 2am of the last sunday of october dst ends
	1987 and after
	    at 2am of the first sunday of april dst starts
	    at 2am of the last sunday of october dst ends
	I shall not concern myself with the vargaries of dst in the 70s
	
	time_zone 是时区数,比如中国北京是+8区,time_zone = 8
	seonds 是从1970年1月1日utc时间0时0分0秒到某一时刻的总秒数
	正常情况下函数返回指针就是参数指针local_time,非正常情况为null
*/
my_tm_t *my_localtime(unsigned long seonds, my_tm_t *local_time, int time_zone) 
{
	register unsigned long local_seconds = seonds + 60 * 60 * time_zone;
    register my_tm_t *temp;
	register my_tm_t gmttime;
    register int isdst=0, sn_mday;

	if ((temp = my_gmtime(local_seconds, &gmttime))==NULL)
	{
		return(NULL);
	}
	temp = &gmttime;
	if (temp->tm_mon<=2 || temp->tm_mon>=10)/*March or before or Nov or after */
	{
		isdst=0;
	}
	else if ( temp->tm_mon!=3 && temp->tm_mon!=9 )  /* between may and Sept */
	{
		isdst=1;
	}
	else if ( temp->tm_mon==9 ) 
	{                   /* october */
		sn_mday=temp->tm_mday-temp->tm_wday;

		while ( sn_mday+7 <=31 ) sn_mday +=7;

		if ( temp->tm_mday<sn_mday )
		{
			isdst=1;
		}
		else if ( temp->tm_mday==sn_mday && temp->tm_hour<2 )
		{
			isdst=1;
		}
	}
	else if ( temp->tm_year<87 ) 
	{                /* april, before 87 */
		sn_mday=temp->tm_mday-temp->tm_wday;

		while ( sn_mday+7 <=31 ) sn_mday +=7;

		if ( temp->tm_mday>sn_mday )
		{
			isdst=1;
		}
		else if ( temp->tm_mday==sn_mday && temp->tm_hour>=2 )
		{
			isdst=1;
		}
	} 
	else 
	{                                        /* april, after 87 */
		sn_mday=temp->tm_mday-temp->tm_wday+7;

		while ( sn_mday-7 > 1 ) sn_mday -=7;

		if ( temp->tm_mday>sn_mday )
		{
			isdst=1;
		}
		else if ( temp->tm_mday==sn_mday && temp->tm_hour>=2 )
		{
			isdst=1;
		}
	}

	if(local_time->tm_isdst==0)
	{
		*local_time = gmttime;
		temp = local_time;
	}
	else
	{
		*local_time = gmttime;
		temp = local_time;
		temp->tm_isdst = isdst;
		if ( isdst) 
		{
			if ( ++(temp->tm_hour)==24 ) 
			{
				const char mons[]={31,28,31,30,31,30,31,31,30,31,30,31};
				temp->tm_hour=0;
				++(temp->tm_yday);          /* can't overflow dst not on Dec. 31 */
				if ( ++(temp->tm_wday)==7 )
				{
					temp->tm_wday=0;
				}
				if ( ++(temp->tm_mday)>mons[temp->tm_mon] ) 
				{
					temp->tm_mday=1;
					++(temp->tm_mon);       /* can't overflow dst not on Dec. 31 */
				}
			}
		}		
	}

	return( temp );
}

int main(int argc, char* argv[])
{
	char StrTime[20];
	my_tm_t gmt;
	my_tm_t local;

	if(my_gmtime((unsigned long)time(NULL), &gmt) ==&gmt)
	{
		sprintf(StrTime,"%04d-%02d-%02d %02d:%02d:%02d", 
			gmt.tm_year+1900,  
			gmt.tm_mon+1,  
			gmt.tm_mday, 
			gmt.tm_hour,
			gmt.tm_min,  
			gmt.tm_sec);
		printf("%s\r\n",StrTime);
	}

	local.tm_isdst=0;
	if(my_localtime((unsigned long)time(NULL), &local,8) ==&local)
	{
		sprintf(StrTime,"%04d-%02d-%02d %02d:%02d:%02d", 
			local.tm_year+1900,  
			local.tm_mon+1,  
			local.tm_mday, 
			local.tm_hour,
			local.tm_min,  
			local.tm_sec);
		printf("%s\r\n",StrTime);
	}

	local.tm_isdst=1;
	if(my_localtime((unsigned long)time(NULL), &local,8) ==&local)
	{
		sprintf(StrTime,"%04d-%02d-%02d %02d:%02d:%02d", 
			local.tm_year+1900,  
			local.tm_mon+1,  
			local.tm_mday, 
			local.tm_hour,
			local.tm_min,  
			local.tm_sec);
		printf("%s\r\n",StrTime);
	}

	local.tm_isdst=-1;
	if(my_localtime((unsigned long)time(NULL), &local,8) ==&local)
	{
		sprintf(StrTime,"%04d-%02d-%02d %02d:%02d:%02d", 
			local.tm_year+1900,  
			local.tm_mon+1,  
			local.tm_mday, 
			local.tm_hour,
			local.tm_min,  
			local.tm_sec);
		printf("%s\r\n",StrTime);
	}

    return 0;
}


以上代码摘自编译器,可以解燃眉之急。

问题又来了,seconds 是从1970年1月1日utc时间0时0分0秒到某一时刻的总秒数,这个总秒数如何计算呢?

码海拾贝 date&time 后续mktime将要上场啦!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值