欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C语言mktime()

程序员文章站 2022-04-14 13:21:35
最近在调试stm32L151单片机,因为业务需要将从RTC获取的时间转换成时间戳。转换的时候发现获取的时间戳一直不对。一直被两个问题困扰。 1.从RTC获取出来的月份为什么比实际月份小1? 2.转换得来的时间戳一直不对。 检查半天发现原来是我没有正确的理解C中的struct tm tm.tm_yea ......

最近在调试stm32L151单片机,因为业务需要将从RTC获取的时间转换成时间戳。转换的时候发现获取的时间戳一直不对。一直被两个问题困扰。

1.从RTC获取出来的月份为什么比实际月份小1?

2.转换得来的时间戳一直不对。

检查半天发现原来是我没有正确的理解C中的struct tm

 1 struct tm {
 2    int tm_sec;         /* 秒,范围从 0 到 59                */
 3    int tm_min;         /* 分,范围从 0 到 59                */
 4    int tm_hour;        /* 小时,范围从 0 到 23                */
 5    int tm_mday;        /* 一月中的第几天,范围从 1 到 31                    */
 6    int tm_mon;         /* 月份,范围从 0 到 11                */
 7    int tm_year;        /* 自 1900 起的年数                */
 8    int tm_wday;        /* 一周中的第几天,范围从 0 到 6                */
 9    int tm_yday;        /* 一年中的第几天,范围从 0 到 365                    */
10    int tm_isdst;       /* 夏令时                        */    
11 };

tm.tm_year表示的是自1900起的年数。我一直以为这个是当前的年份。所以导致了时间戳一直不对。

tm.tm_mon表示月份,范围从0到11 也就是说0代表的是1月份。

 另外附上RTC其他代码:

static void RTC_Config(void)
{
#if 1
    NVIC_InitTypeDef NVIC_InitStructure; 
    EXTI_InitTypeDef EXTI_InitStructure;
    /* Enable the PWR clock */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR , ENABLE);
//    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
    /* Allow access to RTC */
    PWR_RTCAccessCmd(ENABLE);    
    
    /* LSE used as RTC source clock */
    /* The RTC Clock may varies due to LSE frequency dispersion. */   
    /* Enable the LSE OSC */ 
    RCC_LSEConfig(RCC_LSE_ON);    
    //RCC_LSEConfig(RCC_LSE_Bypass);
    /* Wait till LSE is ready */  
    while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
    {
    }    
    
    /* Select the RTC Clock Source */
    RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);    
    
    /* Enable the RTC Clock */
    RCC_RTCCLKCmd(ENABLE);    
    
    /* Wait for RTC APB registers synchronisation */
    if (ERROR == RTC_WaitForSynchro())
    {
        printf("Wait for RTC APB registers synchronisation Failed\r\n");
    }        
#endif     
    /* Calendar Configuration */
    RTC_InitStructure.RTC_AsynchPrediv = 127;//0x7F;
    RTC_InitStructure.RTC_SynchPrediv    = 0x120; /* (37KHz / 128) - 1 = 0x120*/
    RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24;
    if(RTC_Init(&RTC_InitStructure) == ERROR)
    {
        printf("Rtc_Init failed\r\n");
    }        
    RTC_TimeStampCmd(RTC_TimeStampEdge_Rising,ENABLE);

}

time_t GetTimeStamp(void)    //获取时间戳
{
    RTC_DateTypeDef sdatestructure;  
    RTC_TimeTypeDef stimestructure;     
    struct tm tmstr; 
    RTC_GetDate(RTC_Format_BIN, &sdatestructure);
    RTC_GetTime(RTC_Format_BIN, &stimestructure);
    tmstr.tm_year = sdatestructure.RTC_Year;
    tmstr.tm_mon = sdatestructure.RTC_Month;
    tmstr.tm_mday = sdatestructure.RTC_Date;
    tmstr.tm_hour = stimestructure.RTC_Hours;
    tmstr.tm_min = stimestructure.RTC_Minutes;
    tmstr.tm_sec = stimestructure.RTC_Seconds;
    printf("%u-%u-%u-%u-%u-%u.\r\n", tmstr.tm_year+1900,tmstr.tm_mon+1, tmstr.tm_mday, tmstr.tm_hour,tmstr.tm_min, tmstr.tm_sec);
    return mktime(&tmstr);
}
void SetRtcTime(time_t timestamp) //设置RTC时间
{
    RTC_DateTypeDef sdatestructure;  
    RTC_TimeTypeDef stimestructure;     
    struct tm *tmstr; 
    tmstr = localtime(&timestamp);
    printf("set>>%u-%u-%u-%u-%u-%u.\r\n", tmstr->tm_year+1900,tmstr->tm_mon+1, tmstr->tm_mday, tmstr->tm_hour,tmstr->tm_min, tmstr->tm_sec);
    sdatestructure.RTC_Year = (tmstr->tm_year);
    sdatestructure.RTC_Month = tmstr->tm_mon;
    sdatestructure.RTC_Date = tmstr->tm_mday;
    sdatestructure.RTC_WeekDay = tmstr->tm_wday;
    stimestructure.RTC_Hours = tmstr->tm_hour;
    stimestructure.RTC_Minutes = tmstr->tm_min;
    stimestructure.RTC_Seconds = tmstr->tm_sec;
    RTC_SetTime(RTC_Format_BIN,&stimestructure);    
    RTC_SetDate(RTC_Format_BIN, &sdatestructure);

}