NTP 将自 1900 年 1 月 1 日以来的秒数转换为当前日期
NTP convert seconds since 1st january 1900 to current date
我是嵌入式编程,所以我无法使用许多 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 日以来的秒数,但其中 none 按预期工作。
我 运行 的代码是:
#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; day:32277; hour:32275;分钟:32221; seconds:537001984.
你让 t
指向某处有效吗?因为它是一个未初始化的全局变量,它将被零初始化,这意味着指针将被初始化为 NULL
。取消引用空指针会导致 未定义的行为。
与其将其声明为指针,不如将其声明为普通的非指针变量:
tim t;
然后在调用转换函数时使用address-of运算符&
secs_to_date( (secondsSince1900 - 2208988800ul) , &t)
// ^
// |
// Notice the use of the address-of operator here
我是嵌入式编程,所以我无法使用许多 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 日以来的秒数,但其中 none 按预期工作。
我 运行 的代码是:
#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; day:32277; hour:32275;分钟:32221; seconds:537001984.
你让 t
指向某处有效吗?因为它是一个未初始化的全局变量,它将被零初始化,这意味着指针将被初始化为 NULL
。取消引用空指针会导致 未定义的行为。
与其将其声明为指针,不如将其声明为普通的非指针变量:
tim t;
然后在调用转换函数时使用address-of运算符&
secs_to_date( (secondsSince1900 - 2208988800ul) , &t)
// ^
// |
// Notice the use of the address-of operator here