NTP将自1900年1月1日起的秒数转换为当前日期

时间:2016-09-01 09:33:18

标签: c timestamp embedded ntp

我正在编程嵌入式,因此我无法使用许多c库。

我已经使用了NTP协议,所以我现在拥有自1900年1月1日以来的秒数。现在我需要在一个有意义的时间戳中转换它。我一直在寻找它,我发现了这个@R ..实现。

http://git.musl-libc.org/cgit/musl/tree/src/time/__secs_to_tm.c?h=v0.9.15

我试图使用它,但我没有得到正确的结果。

有人知道函数的第一个参数是什么吗?自1900年1月1日以来,我试图通过几秒钟的数字和自1970年1月1日以来的秒数,但没有一个像预期的那样工作。

我正在运行的代码是:

#define NTP_PACKET_SIZE         48
uint8_t packetBuffer[ NTP_PACKET_SIZE];
typedef struct tempo{
    int tm_sec;         /* seconds,  range 0 to 59          */
    int tm_min;         /* minutes, range 0 to 59           */
    int tm_hour;        /* hours, range 0 to 23             */
    int tm_mday;        /* day of the month, range 1 to 31  */
    int tm_mon;         /* month, range 0 to 11             */
    int tm_year;        /* The number of years since 1900   */
    int tm_wday;        /* day of the week, range 0 to 6    */
    int tm_yday;        /* day in the year, range 0 to 365  */
    int tm_isdst;       /* daylight saving time             */
 } tim;

 tim * t;

 static returnTypes_t bsdUdpClient(uint16_t AddrSize){

     int16_t Status = (int16_t) ZERO;

      memset(packetBuffer, 0, NTP_PACKET_SIZE);

      // Initialize values needed to form NTP request
          packetBuffer[0] = 0xE3; //0b11100011;   // LI, Version, Mode
          packetBuffer[1] = 0x00;     // Stratum, or type of clock
          packetBuffer[2] = 0x06;     // Polling Interval
          packetBuffer[3] = 0xEC;  // Peer Clock Precision
       // 8 bytes of zero for Root Delay & Root Dispersion
          packetBuffer[12]  = 49;
          packetBuffer[13]  = 0x4E;
          packetBuffer[14]  = 49;
          packetBuffer[15]  = 52;

    SockID = sl_Socket(SL_AF_INET, SL_SOCK_DGRAM, (uint32_t) ZERO);
    if (SockID < (int16_t) ZERO)
         return (SOCKET_ERROR);

    Status = sl_SendTo(SockID, packetBuffer, NTP_PACKET_SIZE * sizeof(uint8_t), (uint32_t) ZERO, (SlSockAddr_t *) &Addr, AddrSize);

    /*Check if 0 transmitted bytes sent or error condition*/
    if (Status <= (int16_t) ZERO) {
        sl_Close(SockID);
        return (SEND_ERROR);
    }
    else
        printf("request sent successfully\n\r");

    /* receive the reply from the server*/
    Status = sl_RecvFrom(SockID, packetBuffer, NTP_PACKET_SIZE * sizeof(uint8_t), (uint32_t) ZERO, (SlSockAddr_t *) &Addr, &AddrSize);
    if (Status < (int16_t) ZERO){
        printf("error - no bytes received: %d\n\r", (int16_t)Status);
        return SOCKET_ERROR;
    }
    else
        printf("reply received\n\r");

    Status = sl_Close(SockID);
    if (Status < 0)
        printf("problem on sl_Close\n\r");

    uint8_t index3 = packetBuffer[40];
    uint8_t index2 = packetBuffer[41];
    uint8_t index1 = packetBuffer[42];
    uint8_t index0 = packetBuffer[43];

    uint16_t highWord = index3 << 8 | index2;
    uint16_t lowWord = index1 << 8 | index0;

    uint32_t secondsSince1900 = highWord << 16 | lowWord;

    printf("Seconds since 1 Janeiro de 1900: %lu\n\r", secondsSince1900);
    printf("Seconds since 1 Janeira de 1970: %lu\n\r", secondsSince1900 - 2208988800ul );


    if(secs_to_date( (secondsSince1900 - 2208988800ul) , t)!=0)
        printf("impossible to convert\n\r");

    printf("year: %d; month: %d; day:%d; hour:%d; minuts: %d; seconds:%d\n\r",  t->tm_year, t->tm_mon, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec );

     return (STATUS_OK);

  }

因此,例如,我在几分钟之前运行了代码,我期待结果

年:2016;月:9;日:1;小时:9;小时:20;秒:56(例如)

但我得到了这个

年:32281;月:32279;天:32277;小时:32275; minuts:32221;秒:537001984

1 个答案:

答案 0 :(得分:2)

你是否将t指向任何有效的地方?因为它是一个未初始化的全局变量,所以它将被零初始化,这意味着指针将被初始化为NULL。取消引用空指针会导致未定义的行为

不是将其声明为指针,而是将其声明为普通的非指针变量:

tim t;

然后在调用转换函数

时使用address-of operator &
secs_to_date( (secondsSince1900 - 2208988800ul) , &t)
//                                                ^
//                                                |
//   Notice the use of the address-of operator here