8位单片机可用的 mktime  localtime函数及源码

最近在做一个8位单片机项目,其中用到了时间戳转换函数,这个在32位机上一个库函数就解决了问题,没想到在8位单片机中没有对应库(time.h),没有办法只有自己来写。

目标:1,满足和库函数mktime  localtime所计算出的数据一至;2,考虑8位单片机的处理能力慢软件效率问题。

分享给大家,方便有同样需求的朋友。

gcc 环境进行测试:

测试程序:

 #include <stdio.h>
#include <stdint.h>
#include <time.h>
#include <string.h> #if 0
struct tm {
int tm_sec; /* seconds after the minute, 0 to 60
(0 - 60 allows for the occasional leap second) */
int tm_min; /* minutes after the hour, 0 to 59 */
int tm_hour; /* hours since midnight, 0 to 23 */
int tm_mday; /* day of the month, 1 to 31 */
int tm_mon; /* months since January, 0 to 11 */
int tm_year; /* years since 1900 */
// int tm_wday; /* days since Sunday, 0 to 6 */
// int tm_yday; /* days since January 1, 0 to 365 */
// int tm_isdst; /* Daylight Savings Time flag */
};
#endif
static const char mon_list[] = {, , , , , , , , , , , };
static const char leap_mon_list[] = {, , , , , , , , , , , }; /*******************************************************************************
* Function Name : fun_mktime
* Description : 时间转为时间戳
* Input :
* Output :
* Other :
* Date : 2016.11.14
*******************************************************************************/
int32_t fun_mktime(struct tm *pT)
{
const char *pDays = NULL;
int32_t tmp = ;
int16_t i = ; //计算总共有多少个闰年
tmp = (pT->tm_year / - pT->tm_year / + pT->tm_year / ) - ( / - / + / ); //如果当年是闰年,需要减去当年的闰年
if ((pT->tm_year % == ) && ((pT->tm_year % != ) || (pT->tm_year % == )))
{
tmp = tmp - + (pT->tm_year - ) * ;
pDays = leap_mon_list;
}
else
{
tmp = tmp + (pT->tm_year - ) * ;
pDays = mon_list;
} for (i = ; i < pT->tm_mon - ; i++)
tmp += pDays[i]; tmp = tmp + pT->tm_mday - ; tmp = tmp * + pT->tm_hour; tmp = tmp * + pT->tm_min; tmp = tmp * + pT->tm_sec; return tmp;
} /*******************************************************************************
* Function Name : fun_localtime
* Description : 时间戳转为时间
* Input : struct tm *pT: 输出的时间缓冲区 uint32_t tim:当前时间戳
* Output :
* Other :
* Date : 2016.11.14
*******************************************************************************/
void fun_localtime(struct tm *pT, int32_t tim)
{
const char *pDays = NULL; uint16_t index = ; memset(pT, , sizeof(*pT)); //year initialization
if (tim > 0x5685C180L) // 2016-1-1 0:0:0
{
pT->tm_year = ;
tim -= 0x5685C180L;
}
else if (tim > 0x4B3D3B00L) // 2010-1-1 0:0:0
{
pT->tm_year = ;
tim -= 0x4B3D3B00L;
}
else if (tim > 0x386D4380L) // 2000-1-1 0:0:0
{
pT->tm_year = ;
tim -= 0x386D4380L;
}
else
{
pT->tm_year = ;
} //now have year
while (tim >= 366L * * * )
{
if ((pT->tm_year % == ) && ((pT->tm_year % != ) || (pT->tm_year % == )))
tim -= 366L * * * ;
else
tim -= 365L * * * ; pT->tm_year++;
} // then 365 * 24 * 60 * 60 < tim < 366 * 24 * 60 * 60
if (!(((pT->tm_year % == ) && ((pT->tm_year % != ) || (pT->tm_year % == ))))
&& (tim > 365L * * * ))
{
tim -= 365L * * * ;
pT->tm_year++;
} // this year is a leap year?
if (((pT->tm_year % == ) && ((pT->tm_year % != ) || (pT->tm_year % == ))))
pDays = leap_mon_list;
else
pDays = mon_list; pT->tm_mon = ;
// now have mon
while (tim > pDays[index] * 24L * * )
{
tim -= pDays[index] * 24L * * ;
index++;
pT->tm_mon++;
} // now have days
pT->tm_mday = tim / (24L * * ) + ;
tim = tim % (24L * * ); // now have hour
pT->tm_hour = tim / ( * );
tim = tim % ( * ); // now have min
pT->tm_min = tim / ;
tim = tim % ; pT->tm_sec = tim;
} int main (void *parg)
{
struct tm *pT = {};
time_t timep = ;
uint32_t cur_tim = ; time(&timep); pT = localtime(&timep); printf("linux time \t= %d\n", (int32_t)timep);
pT->tm_year += ;
pT->tm_mon += ;
printf("fun_mktime \t= %d\n", cur_tim = (uint32_t)fun_mktime(pT)); printf("localtime \t= %d-%d-%d %d:%d:%d\n", pT->tm_year, pT->tm_mon, pT->tm_mday, pT->tm_hour, pT->tm_min, pT->tm_sec);
memset(pT, , sizeof(*pT));
fun_localtime(pT, cur_tim);
printf("fun_localtime \t= %d-%d-%d %d:%d:%d\n", pT->tm_year, pT->tm_mon, pT->tm_mday, pT->tm_hour, pT->tm_min, pT->tm_sec);
return ;
}

测试结果:

linux time      =
fun_mktime =
localtime = -- ::
fun_localtime = -- ::

linux time 是库函数mktime计算结果,因为进行了时区处理,所以与fun_mktime计算出来刚好是8 * 3600 秒的差值

此函数在C51下进行过测试,符合要求。

最新文章

  1. eclipse导入第三方jar包进入web项目的方法
  2. lua练手基础
  3. Sqli-LABS通关笔录-7[文件写入函数Outfile]
  4. AIX 第3章 指令记录
  5. WinPcap编程(二)
  6. EMV/PBOC解析(三) TLV格式解析(C#)
  7. UEFI模式下安装Win 7系统
  8. token验证 sae
  9. MyBatis映射文件的resultMap如何做表关联
  10. 02&mdash;从Cocos2DX视角看游戏组成
  11. 开发反模式(GUID) - 伪键洁癖
  12. R与数据分析旧笔记(十六) 基于密度的方法:DBSCAN
  13. linux(ubuntu) 遇到的问题 --1
  14. 怎样使用jsp实现header和footer与网页内容的分离
  15. 使用JS意识到自己主动提交表单
  16. [Lua]Mac系统上安装Lua环境
  17. margin和padding的用法与区别--以及bug处理方式
  18. Android快速实现二维码扫描--Zxing
  19. java中三种for循环之间的对比
  20. Solr游标查询提高翻页效率

热门文章

  1. linux USR1亦通常被用来告知应用程序重载配置文件
  2. Hibernate标准查询语言
  3. Spring MVC可参数化的视图控制器
  4. 012android初级篇之Handler机制
  5. VS2005 Manifest 配置问题总结
  6. 新MBP使用git命令时启用xcode的终端log
  7. 微信 oauth 授权3
  8. python socket编程入门(编写server实例)+send 与sendall的区别与使用方法
  9. Kotlin——中级篇(五):枚举类(Enum)、接口类(Interface)详解
  10. 【BZOJ1266】[AHOI2006]上学路线route Floyd+最小割