Advertisement

C语言北京时间与格林威治时间戳的转换

阅读量:

文本详细描述了一个基于C语言的时间处理库,涉及Unix时间戳的概念(从1970-01-01起算的总秒数),并提供了处理日期和时间的功能模块。该库定义了一个rtcdatetimet结构体来存储年月日时分秒及星期信息,并使用基姆拉尔森计算公式精确计算给定日期对应的星期几。此外,包含getmaxday函数以确定各月份的最大天数,并提供checkdatetime函数用于验证输入的时间是否有效。库中还包括两个主要转换函数:standardrtctostamp将RTC格式的时间转换为总秒数值,并调整时差;stamptostandardrtc则反向将给定的总秒数值重新解析为RTC格式的时间。

该值是从格林威治标准时间的起始点(即1970年1月1日零时)计算所得的总秒数;该值也可称为Unix timestamp

北京时间与格林威治时间有8小时偏差,28800秒;

该代码涵盖了时序和星期运算,并且时间段限定在2000年至2099年之间;使用基姆拉尔森计算公式来进行星期推算。

复制代码
 #include <stdlib.h>

    
 #include <stdio.h>
    
 #include <time.h>
    
  
    
 typedef struct rtc_date_time
    
 {
    
     uint8_t              u8Year;        ///< Year (range 0-99)
    
     uint8_t              u8Month;       ///< Month (range 1-12)
    
     uint8_t              u8Day;         ///< Day (range 1-31)
    
     uint8_t              u8Hour;        ///< Hours (range 1-12 when 12 hour format; range 0-23 when 24 hour format)
    
     uint8_t              u8Minute;      ///< Minutes (range 0-59)
    
     uint8_t              u8Second;      ///< Seconds (range 0-59)
    
     uint8_t              u8Weekday;     ///< Weekday (range 0-6)
    
 } rtc_date_time_t;
    
  
    
 //基姆拉尔森计算公式, Kim larsen calculation formula
    
 static uint8_t get_Weekday(uint16_t year, uint8_t month, uint8_t day)
    
 { 
    
     int week = -1; 
    
  
    
     year += 2000;
    
     if(1 == month || 2 == month) { 
    
     month += 12; 
    
     year--; 
    
     } 
    
     week  = (day + 2*month + 3*(month+1)/5 + year + year/4 - year/100 + year/400);
    
     week %= 7; 
    
     
    
     return week;
    
 }
    
  
    
 static uint8_t get_max_day(int year, int month)
    
 {
    
     uint8_t day = 0;
    
     
    
     switch(month)
    
     {
    
     case 1:
    
     case 3: 
    
     case 5:
    
     case 7:
    
     case 8: 
    
     case 10:
    
     case 12:
    
     day = 31;
    
     break;
    
     case 4:
    
     case 6: 
    
     case 9:
    
     case 11:
    
     day = 30;
    
     break;
    
     case 2:
    
     //day < 2099, ignore year % 400
    
     day = (year % 4 == 0) ? 29 : 28;
    
     break;
    
     }
    
     
    
     return day;
    
 }
    
  
    
 static uint8_t check_datetime(rtc_date_time_t *tc)
    
 {
    
     if(!tc) return 0;
    
     
    
     if(tc->u8Year > 99) return 0;
    
     if(tc->u8Month < 1 || tc->u8Month > 12) return 0;
    
     if(tc->u8Day < 1 || tc->u8Day > get_max_day(tc->u8Year, tc->u8Month)) return 0;
    
     
    
     if(tc->u8Hour > 23)   return 0;
    
     if(tc->u8Minute > 59) return 0;
    
     if(tc->u8Second > 59) return 0;
    
     
    
     return 1;
    
 }
    
  
    
 uint8_t rtc_datetime_set(rtc_date_time_t *tc)
    
 {
    
     tc->u8Weekday = get_Weekday(tc->u8Year, tc->u8Month, tc->u8Day);
    
     //return RTC_SetDateTime(RtcDataFormatDec, tc, Enable, Enable);
    
  
    
     return 0;
    
 }
    
  
    
 int standard_rtc_to_stamp(rtc_date_time_t* tc)
    
 {
    
     struct tm stm;
    
  
    
     stm.tm_year = tc->u8Year + 2000 - 1900;
    
     stm.tm_mon  = tc->u8Month - 1;
    
     stm.tm_mday = tc->u8Day;
    
     stm.tm_hour = tc->u8Hour;
    
     stm.tm_min  = tc->u8Minute;
    
     stm.tm_sec  = tc->u8Second;
    
  
    
     return (int)(mktime(&stm) - 28800); //北京时间-8
    
 }
    
  
    
 uint8_t stamp_to_standard_rtc(int stampTime)
    
 {
    
     char s[24] = {0};
    
     rtc_date_time_t tc;
    
     time_t tick = (time_t)stampTime + 28800; //北京时间+8
    
     struct tm tm;
    
  
    
     tm = *localtime(&tick);
    
     strftime(s, sizeof(s), "%Y-%m-%d %H:%M:%S", &tm);
    
  
    
     int year = atoi(s);
    
  
    
     if(year < 2022 || year > 2099) return 0;
    
     tc.u8Year   = year - 2000;
    
     tc.u8Month  = atoi(s+5);
    
     tc.u8Day    = atoi(s+8);
    
     tc.u8Hour   = atoi(s+11);
    
     tc.u8Minute = atoi(s+14);
    
     tc.u8Second = atoi(s+17);
    
  
    
     if(check_datetime(&tc)) 
    
     return rtc_datetime_set(&tc);
    
  
    
     return 0;
    
 }

全部评论 (0)

还没有任何评论哟~