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

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

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

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

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

gcc 环境进行测试:

测试程序:

  1 #include <stdio.h>
  2 #include <stdint.h>
  3 #include <time.h>
  4 #include <string.h>
  5
  6 #if 0
  7 struct tm {
  8     int tm_sec;   /* seconds after the minute, 0 to 60
  9                      (0 - 60 allows for the occasional leap second) */
 10     int tm_min;   /* minutes after the hour, 0 to 59 */
 11     int tm_hour;  /* hours since midnight, 0 to 23 */
 12     int tm_mday;  /* day of the month, 1 to 31 */
 13     int tm_mon;   /* months since January, 0 to 11 */
 14     int tm_year;  /* years since 1900 */
 15 //    int tm_wday;  /* days since Sunday, 0 to 6 */
 16 //    int tm_yday;  /* days since January 1, 0 to 365 */
 17 //    int tm_isdst; /* Daylight Savings Time flag */
 18 };
 19 #endif
 20 static const char mon_list[12]             = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
 21 static const char leap_mon_list[12]        = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
 22
 23 /*******************************************************************************
 24 * Function Name : fun_mktime
 25 * Description   : 时间转为时间戳
 26 * Input         :
 27 * Output        :
 28 * Other         :
 29 * Date          : 2016.11.14
 30 *******************************************************************************/
 31 int32_t fun_mktime(struct tm *pT)
 32 {
 33     const char *pDays = NULL;
 34     int32_t tmp = 0;
 35     int16_t i = 0;
 36
 37     //计算总共有多少个闰年
 38     tmp = (pT->tm_year  / 4 - pT->tm_year / 100 + pT->tm_year / 400) - (1970 / 4 - 1970 / 100 + 1970 / 400);
 39
 40     //如果当年是闰年,需要减去当年的闰年
 41     if ((pT->tm_year % 4 == 0) && ((pT->tm_year  % 100 != 0) || (pT->tm_year  % 400 == 0)))
 42     {
 43         tmp = tmp - 1 + (pT->tm_year - 1970) * 365;
 44         pDays = leap_mon_list;
 45     }
 46     else
 47     {
 48         tmp = tmp + (pT->tm_year - 1970) * 365;
 49         pDays = mon_list;
 50     }
 51
 52     for (i = 0; i < pT->tm_mon - 1; i++)
 53         tmp += pDays[i];
 54
 55     tmp = tmp + pT->tm_mday - 1;
 56
 57     tmp = tmp * 24 + pT->tm_hour;
 58
 59     tmp = tmp * 60 + pT->tm_min;
 60
 61     tmp = tmp * 60 + pT->tm_sec;
 62
 63     return tmp;
 64 }
 65
 66 /*******************************************************************************
 67 * Function Name : fun_localtime
 68 * Description   : 时间戳转为时间
 69 * Input         :   struct tm *pT: 输出的时间缓冲区   uint32_t tim:当前时间戳
 70 * Output        :
 71 * Other         :
 72 * Date          : 2016.11.14
 73 *******************************************************************************/
 74 void fun_localtime(struct tm *pT, int32_t tim)
 75 {
 76   const char *pDays = NULL;
 77
 78   uint16_t index = 0;
 79
 80   memset(pT, 0, sizeof(*pT));
 81
 82   //year initialization
 83   if (tim > 0x5685C180L)            // 2016-1-1 0:0:0
 84   {
 85     pT->tm_year = 2016;
 86     tim -= 0x5685C180L;
 87   }
 88   else if (tim > 0x4B3D3B00L)       // 2010-1-1 0:0:0
 89   {
 90     pT->tm_year = 2010;
 91     tim -= 0x4B3D3B00L;
 92   }
 93   else if (tim > 0x386D4380L)       // 2000-1-1 0:0:0
 94   {
 95     pT->tm_year = 2000;
 96     tim -= 0x386D4380L;
 97   }
 98   else
 99   {
100     pT->tm_year = 1970;
101   }
102
103   //now have year
104   while (tim >= 366L * 24 * 60 * 60)
105   {
106     if ((pT->tm_year % 4 == 0) && ((pT->tm_year  % 100 != 0) || (pT->tm_year  % 400 == 0)))
107       tim -= 366L * 24 * 60 * 60;
108     else
109       tim -= 365L * 24 * 60 * 60;
110
111     pT->tm_year++;
112   }
113
114   // then 365 * 24 * 60 * 60 < tim < 366 * 24 * 60 * 60
115   if (!(((pT->tm_year % 4 == 0) && ((pT->tm_year  % 100 != 0) || (pT->tm_year  % 400 == 0))))
116     && (tim > 365L * 24 * 60 * 60))
117   {
118     tim -= 365L * 24 * 60 * 60;
119     pT->tm_year++;
120   }
121
122   // this year is a leap year?
123   if (((pT->tm_year % 4 == 0) && ((pT->tm_year  % 100 != 0) || (pT->tm_year  % 400 == 0))))
124     pDays = leap_mon_list;
125   else
126     pDays = mon_list;
127
128   pT->tm_mon = 1;
129   // now have mon
130   while (tim > pDays[index] * 24L * 60 * 60)
131   {
132     tim -= pDays[index] * 24L * 60 * 60;
133     index++;
134     pT->tm_mon++;
135   }
136
137   // now have days
138   pT->tm_mday = tim / (24L * 60 * 60) + 1;
139   tim = tim % (24L * 60 * 60);
140
141   // now have hour
142   pT->tm_hour = tim / (60 * 60);
143   tim = tim % (60 * 60);
144
145   // now have min
146   pT->tm_min = tim / 60;
147   tim = tim % 60;
148
149   pT->tm_sec = tim;
150 }
151
152
153 int main (void *parg)
154 {
155   struct tm *pT = {0};
156   time_t timep = 0;
157   uint32_t cur_tim = 0;
158
159   time(&timep);
160
161   pT = localtime(&timep);
162
163   printf("linux time \t= %d\n", (int32_t)timep);
164   pT->tm_year += 1900;
165   pT->tm_mon += 1;
166   printf("fun_mktime \t= %d\n", cur_tim = (uint32_t)fun_mktime(pT));
167
168   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);
169   memset(pT, 0, sizeof(*pT));
170   fun_localtime(pT, cur_tim);
171   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);
172   return 0;
173 }

测试结果:

linux time      = 1480133002
fun_mktime      = 1480161802
localtime       = 2016-11-26 12:3:22
fun_localtime   = 2016-11-26 12:3:22

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

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

时间: 2024-10-09 11:04:24

8位单片机可用的 mktime localtime函数的相关文章

合泰8位单片机使用小结

合泰单片机是台湾芯片,集成开发环境为HT-3000.大陆这边的芯片代理商是盛群半导体有限公司,官网上的程序用例都是由汇编编写的,当然也对C语言很好的支持,是标准C的子集.在工作中使用到的是8位的HT48R006,在开发过程中,需要注意一下几点: 1.在HT-3000中有相关的配置,包括时钟的选择,管脚的功能配置,看门狗的使能,看门狗的喂狗指令方式. 2.寄存器是支持位寻址的,包含了对应的头文件后,就能使用相关的位标示符. 3.在系统时钟配置为内部时钟时,PA5,PA6作为普通IO引脚来使用,若使

freescale 16位单片机的地址映射

以MC9S12XS128MAL为例,其实DG128之类的类似.如图一,128代表的是单片机中的FLASH大小为128K Byte,同理64代表的是单片机中的FLASH大小为64 K Byte,256代表的是单片机中的FLASH大小为256 K Byte.但是S12(X)所使用的内核CPU12(X)的地址总线为16位,寻址范围最大为2^16 =64K Byte,而这64K Byte的寻址空间还包括寄存器.EEPROM(利用Data Flash模拟).RAM等,因此不是所有的64K Byte都是用来

gmtime函数与localtime函数的区别:

gmtime函数与localtime函数的区别: gmtime函数返回的时间日期未经时区转换,是UTC时间(又称为世界时间,即格林尼治时间). localtime函数返回当前时区的时间, 转换日期时间表示形式time_t类型转换为struct tm类型示例: #include #include int main() { char *wday[]={"Sun","Mon","Tue","Wed","Thu",

8位16位32位单片机区别

8位16位32位区别 8位单片机的数据总线宽度为8位,通常直接只能处理8位数据: 16位单片机的数据总线宽度为16位,通常可直接处理8位或16位数据. 8位数据类型所占大小 16位数据类型所占大小 stm32,k60数据类型

Linux C 中获取local日期和时间 time()&amp;localtime()函数

1.  time() 函数 /* time - 获取计算机系统当前的日历时间(Calender Time) * 处理日期时间的函数都是以本函数的返回值为基础进行运算 * * 函数原型: * #include <time.h> * * time_t time(time_t *calptr); * * 返回值: * 成功:秒数,从1970-1-1,00:00:00 * * 使用: * time_t now; * * time(&now); // == now = time(NULL); *

关于8位单片机上资源有限一些要注意的点

8位mcu,51内核: 新塘的N76E003AT20,比stm8同款的多一点端口,具体多什么可以百度一下,这里不赘述了. 注意点1:局部变量的合理分配,一般在8位单片机上跑的程序逻辑都比较简单,单循环+中断. 根据N76的特性,把一些大的数组局部变量分配在xram里.参考EEPROM的demo. 注意点2:8位机运算能力有限,有限取余和整除运算可以直接用 1 TH0=(65536-50000)/256; 2 TL0=(65536-50000)%256; 3 //等效于 4 TH0=(65536-

javascript中可用的编码解码函数

在项目实践中可能会遇到一些特殊字符的转义问题,那么这个时候就需要js编码解码函数来解决这些情况了: 特殊字符的含义 URL编码  符号 解释 转义 # 用来标志特定的文档位置 %23 % 对特殊字符进行编码 %25 & 分隔不同的变量值对 %26 + 在变量值中表示空格 %2B / 表示目录路径 %2F \ 表示目录路径 %5C = 用来连接键和值 %3D ? 表示查询字符串的开始 %3F 空格 空格 %20 . 句号 %2E : 冒号 %3A javascript中可用的编码解码函数,有如下的

C语言的setlocale和localtime函数(C++也可用)

Example 1234567891011121314151617181920212223242526272829303132 /* setlocale example */ #include <stdio.h> /* printf */ #include <time.h> /* time_t, struct tm, time, localtime, strftime */ #include <locale.h> /* struct lconv, setlocale,

IAR瑞萨单片机开发加入printf调试函数

IAR开发环境,没有printf函数,自己百度加入了一个(http://www.cnblogs.com/codecamel/p/4686437.html),但是还是有一些问题,特别是打印多个变量时,只能够打印字符串时比较稳定,原因是因为va_arg()给了错误的返回值,故只能找寻其他的方法,今天测试了一下,新的办法步骤如下 1.关键之处,否则会出现PUTCHAR函数未定义现象. 右键点击工程选择option-> General Option->ibrary configuration中libr