Time system

来源:互联网 发布:查日本经济数据的网站 编辑:程序博客网 时间:2024/05/17 07:49

1 Time System

1.1 URL

http://leapsecond.com/java/gpsclock.htm

1.2 MCU Firmware Demo

/*

 * utils.c
 *
 * Copyright (C) 2017
 *
 * Author: George Tso <zoosenpin@163.com>
 *
 * For detail time, please reference to http://www.acme.com/software/date_parse/
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#define API
#define oem_printf(fmt, args...) printf(fmt, ##args)
typedef int int32;
typedef unsigned int u32;
//typedef unsigned long time_t;

#if !defined(SIMPLE_FORMAT)
struct strlong {
    char* s;
    long l;
};

static void pound_case( char* str )
{
    for ( ; *str != '\0'; ++str )
    {
        if ( isupper( (int) *str ) )
            *str = tolower( (int) *str );
    }
}

static int strlong_compare( v1, v2 )
    char* v1;
    char* v2;
{
    return strcmp( ((struct strlong*) v1)->s, ((struct strlong*) v2)->s );
}

static int strlong_search( char* str, struct strlong* tab, int n, long* lP )
{
    int i, h, l, r;

    l = 0;
    h = n - 1;
    for (;;)
    {
        i = ( h + l ) / 2;
        r = strcmp( str, tab[i].s );
        if ( r < 0 )
            h = i - 1;
        else if ( r > 0 )
            l = i + 1;
        else
        {
            *lP = tab[i].l;
            return 1;
        }
        if ( h < l )
            return 0;
    }
}

static int scan_wday( char* str_wday, long* tm_wdayP )
{
    static struct strlong wday_tab[] = {
        { "sun", 0 }, { "sunday", 0 },
        { "mon", 1 }, { "monday", 1 },
        { "tue", 2 }, { "tuesday", 2 },
        { "wed", 3 }, { "wednesday", 3 },
        { "thu", 4 }, { "thursday", 4 },
        { "fri", 5 }, { "friday", 5 },
        { "sat", 6 }, { "saturday", 6 },
    };
    static int sorted = 0;

    if ( ! sorted )
    {
        (void) qsort(
                wday_tab, sizeof(wday_tab)/sizeof(struct strlong),
                sizeof(struct strlong), strlong_compare );
        sorted = 1;
    }
    pound_case( str_wday );
    return strlong_search(
            str_wday, wday_tab, sizeof(wday_tab)/sizeof(struct strlong), tm_wdayP );
}

static int scan_mon( char* str_mon, long* tm_monP )
{
    static struct strlong mon_tab[] = {
        { "jan", 0 }, { "january", 0 },
        { "feb", 1 }, { "february", 1 },
        { "mar", 2 }, { "march", 2 },
        { "apr", 3 }, { "april", 3 },
        { "may", 4 },
        { "jun", 5 }, { "june", 5 },
        { "jul", 6 }, { "july", 6 },
        { "aug", 7 }, { "august", 7 },
        { "sep", 8 }, { "september", 8 },
        { "oct", 9 }, { "october", 9 },
        { "nov", 10 }, { "november", 10 },
        { "dec", 11 }, { "december", 11 },
    };
    static int sorted = 0;

    if ( ! sorted )
    {
        (void) qsort(
                mon_tab, sizeof(mon_tab)/sizeof(struct strlong),
                sizeof(struct strlong), strlong_compare );
        sorted = 1;
    }
    pound_case( str_mon );
    return strlong_search(
            str_mon, mon_tab, sizeof(mon_tab)/sizeof(struct strlong), tm_monP );
}
#endif

static int32 is_leap(int year)
{
    return year % 400? ( year % 100 ? ( year % 4 ? 0 : 1 ) : 0 ) : 1;
}

static u32 tm_to_time(struct tm* tm)
{
    time_t t;
    static int monthtab[12] = {
        0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };

    /* Years since epoch, converted to days. */
    t = ( tm->tm_year - 70 ) * 365;
    /* Leap days for previous years. */
    t += ( tm->tm_year - 69 ) / 4;
    /* Days for the beginning of this month. */
    t += monthtab[tm->tm_mon];
    /* Leap day for this year. */
    if ( tm->tm_mon >= 2 && is_leap( tm->tm_year + 1900 ) )
        ++t;
    /* Days since the beginning of this month. */
    t += tm->tm_mday - 1;  /* 1-based field */
    /* Hours, minutes, and seconds. */
    t = t * 24 + tm->tm_hour;
    t = t * 60 + tm->tm_min;
    t = t * 60 + tm->tm_sec;

    return t;
}

// similar with time_t mktime(struct tm* tm)
#if !defined(SIMPLE_FORMAT)
API int32 u_gmt_to_elapsed_secs(const char *gmt)
{
    struct tm tm;
    char* cp;
    char str_mon[500], str_wday[500];
    int tm_sec, tm_min, tm_hour, tm_mday, tm_year;
    long tm_mon, tm_wday;
    time_t t;

    /* Initialize. */
    memset( (char*) &tm, 0, sizeof(struct tm) );

    /* Skip initial whitespace ourselves - sscanf is clumsy at this. */
    for ( cp = (char *)gmt; *cp == ' ' || *cp == '\t'; ++cp )
        continue;

    /* And do the sscanfs.  WARNING: you can add more formats here,
     ** but be careful!  You can easily screw up the parsing of existing
     ** formats when you add new ones.  The order is important.
     */

    /* DD-mth-YY HH:MM:SS GMT */
    if ( sscanf( cp, "%d-%400[a-zA-Z]-%d %d:%d:%d GMT",
                &tm_mday, str_mon, &tm_year, &tm_hour, &tm_min,
                &tm_sec ) == 6 &&
            scan_mon( str_mon, &tm_mon ) )
    {
        tm.tm_mday = tm_mday;
        tm.tm_mon = tm_mon;
        tm.tm_year = tm_year;
        tm.tm_hour = tm_hour;
        tm.tm_min = tm_min;
        tm.tm_sec = tm_sec;
    }

    /* DD mth YY HH:MM:SS GMT */
    else if ( sscanf( cp, "%d %400[a-zA-Z] %d %d:%d:%d GMT",
                &tm_mday, str_mon, &tm_year, &tm_hour, &tm_min,
                &tm_sec) == 6 &&
            scan_mon( str_mon, &tm_mon ) )
    {
        tm.tm_mday = tm_mday;
        tm.tm_mon = tm_mon;
        tm.tm_year = tm_year;
        tm.tm_hour = tm_hour;
        tm.tm_min = tm_min;
        tm.tm_sec = tm_sec;
    }
    /* HH:MM:SS GMT DD-mth-YY */
    else if ( sscanf( cp, "%d:%d:%d GMT %d-%400[a-zA-Z]-%d",
                &tm_hour, &tm_min, &tm_sec, &tm_mday, str_mon,
                &tm_year ) == 6 &&
            scan_mon( str_mon, &tm_mon ) )
    {
        tm.tm_hour = tm_hour;
        tm.tm_min = tm_min;
        tm.tm_sec = tm_sec;
        tm.tm_mday = tm_mday;
        tm.tm_mon = tm_mon;
        tm.tm_year = tm_year;
    }
    /* HH:MM:SS GMT DD mth YY */
    else if ( sscanf( cp, "%d:%d:%d GMT %d %400[a-zA-Z] %d",
                &tm_hour, &tm_min, &tm_sec, &tm_mday, str_mon,
                &tm_year ) == 6 &&
            scan_mon( str_mon, &tm_mon ) )
    {
        tm.tm_hour = tm_hour;
        tm.tm_min = tm_min;
        tm.tm_sec = tm_sec;
        tm.tm_mday = tm_mday;
        tm.tm_mon = tm_mon;
        tm.tm_year = tm_year;
    }

    /* wdy, DD-mth-YY HH:MM:SS GMT */
    else if ( sscanf( cp, "%400[a-zA-Z], %d-%400[a-zA-Z]-%d %d:%d:%d GMT",
                str_wday, &tm_mday, str_mon, &tm_year, &tm_hour, &tm_min,
                &tm_sec ) == 7 &&
            scan_wday( str_wday, &tm_wday ) &&
            scan_mon( str_mon, &tm_mon ) )
    {
        tm.tm_wday = tm_wday;
        tm.tm_mday = tm_mday;
        tm.tm_mon = tm_mon;
        tm.tm_year = tm_year;
        tm.tm_hour = tm_hour;
        tm.tm_min = tm_min;
        tm.tm_sec = tm_sec;
    }
    /* wdy, DD mth YY HH:MM:SS GMT */
    else if ( sscanf( cp, "%400[a-zA-Z], %d %400[a-zA-Z] %d %d:%d:%d GMT",
                str_wday, &tm_mday, str_mon, &tm_year, &tm_hour, &tm_min,
                &tm_sec ) == 7 &&
            scan_wday( str_wday, &tm_wday ) &&
            scan_mon( str_mon, &tm_mon ) )
    {
        tm.tm_wday = tm_wday;
        tm.tm_mday = tm_mday;
        tm.tm_mon = tm_mon;
        tm.tm_year = tm_year;
        tm.tm_hour = tm_hour;
        tm.tm_min = tm_min;
        tm.tm_sec = tm_sec;
    }
    /* wdy mth DD HH:MM:SS GMT YY */
    else if ( sscanf( cp, "%400[a-zA-Z] %400[a-zA-Z] %d %d:%d:%d GMT %d",
                str_wday, str_mon, &tm_mday, &tm_hour, &tm_min, &tm_sec,
                &tm_year ) == 7 &&
            scan_wday( str_wday, &tm_wday ) &&
            scan_mon( str_mon, &tm_mon ) )
    {
        tm.tm_wday = tm_wday;
        tm.tm_mon = tm_mon;
        tm.tm_mday = tm_mday;
        tm.tm_hour = tm_hour;
        tm.tm_min = tm_min;
        tm.tm_sec = tm_sec;
        tm.tm_year = tm_year;
    }
    // OEM
    // YY-mth-DD HH:MM:SS
    else if (6 == sscanf(gmt, "%d-%d-%d %d:%d:%d",
                &tm_year, (int32 *)&tm_mon, &tm_mday,
                &tm_hour, &tm_min, &tm_sec)) {
        //    oem_printf("[OEM] %d-%d-%d %d:%d:%d\n",
        //            tm_year, tm_mon, tm_mday, tm_hour, tm_min, tm_sec);
        //tm.tm_wday = tm_wday;
        tm.tm_year = tm_year;
        tm.tm_mon = tm_mon;
        tm.tm_mday = tm_mday;
        tm.tm_hour = tm_hour;
        tm.tm_min = tm_min;
        tm.tm_sec = tm_sec;
    }
    else
        return (time_t) -1;

    if ( tm.tm_year > 1900 )
        tm.tm_year -= 1900;
    else if ( tm.tm_year < 70 )
        tm.tm_year += 100;

    //////////////////////
    tm.tm_mon -= 1;
    //////////////////////
    t = tm_to_time(&tm);

    //////////////////////
    // TODO: decrease extra 8 hours
    t = t - 8 * 60 * 60;
    //////////////////////

    return t;
}

#else

API int32 u_gmt_to_elapsed_secs(const char *gmt)
{
    int ret;
    int tm_hour, tm_min, tm_sec, tm_year, tm_mon, tm_mday;
    int tm_wday;
    struct tm tm;
    time_t t;

    // YY-mth-DD HH:MM:SS GMT
    if (6 == sscanf(gmt, "%d-%d-%d %d:%d:%d",
                &tm_year, &tm_mon, &tm_mday,
                &tm_hour, &tm_min, &tm_sec)) {
    //    oem_printf("[OEM] %d-%d-%d %d:%d:%d\n",
    //            tm_year, tm_mon, tm_mday, tm_hour, tm_min, tm_sec);
        //tm.tm_wday = tm_wday;
        tm.tm_year = tm_year;
        tm.tm_mon = tm_mon;
        tm.tm_mday = tm_mday;
        tm.tm_hour = tm_hour;
        tm.tm_min = tm_min;
        tm.tm_sec = tm_sec;
    } else {
        return (time_t) -1;
    }

    if (tm.tm_year > 1900) {
        tm.tm_year -= 1900;
    } else if (tm.tm_year < 70) {
        tm.tm_year += 100;
    }

    //////////////////////
    tm.tm_mon -= 1;
    //////////////////////
    t = tm_to_time(&tm);

    //////////////////////
    // TODO: decrease extra 8 hours
    t = t - 8 * 60 * 60;
    //////////////////////

    return t;
}
#endif

static int32 get_now_tm(struct tm *tm)
{
    struct timespec time;

    if (!tm) {
        return -1;
    }

    clock_gettime(CLOCK_REALTIME, &time);  //获取相对于1970到现在的秒数
    oem_printf("[OEM] [%s] elapsed secs: %d\n", __func__, (int)time.tv_sec);
    if (localtime_r(&time.tv_sec, tm) != NULL) {
        return 0;
    }

    return -1;
}

API int32 u_elapsed_secs_to_tm(u32 secs, struct tm *tm)
{
    struct timespec time;

    if (!tm) {
        return -1;
    }

    time.tv_sec = secs;
    oem_printf("[OEM] [%s] elapsed secs: %d\n", __func__, (int)time.tv_sec);
    if (localtime_r(&time.tv_sec, tm) != NULL) {
        return 0;
    }

    return -1;
}

API int32 u_macstr_to_array(const char *mac_str, char mac_addr[], u32 mac_addr_len)
{
    if (mac_addr_len < 6) {
        return -1;
    }

    if (6 == sscanf(mac_str, "%02x:%02x:%02x:%02x:%02x:%02x",
                (u32 *)&mac_addr[0], (u32 *)&mac_addr[1], (u32 *)&mac_addr[2],
                (u32 *)&mac_addr[3], (u32 *)&mac_addr[4], (u32 *)&mac_addr[5])) {
        oem_printf("[OEM] %02x:%02x:%02x:%02x:%02x:%02x\n", mac_addr[0],
                mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4],mac_addr[5]);
        return 0;
    }

    return -1;
}

int main(int argc, char **argv)
{
    char gmt[32];
    const char *macstr = "00:0C:43:76:20:58";
    char mac_addr[6];
    struct tm tm;

    if (!get_now_tm(&tm)) {
        snprintf(gmt, 32, "%04d-%d-%d %02d:%02d:%02d", tm.tm_year + 1900,
                tm.tm_mon + 1, tm.tm_mday,
                tm.tm_hour, tm.tm_min, tm.tm_sec);
        oem_printf("[OEM] %s\n", gmt);
    }
 
    //oem_printf("[OEM] elapsed secs: %d\n", u_gmt_to_elapsed_secs(gmt));
    if (!u_elapsed_secs_to_tm(u_gmt_to_elapsed_secs(gmt), &tm)) {
        snprintf(gmt, 32, "%04d-%d-%d %02d:%02d:%02d", tm.tm_year + 1900,
                tm.tm_mon + 1, tm.tm_mday,
                tm.tm_hour, tm.tm_min, tm.tm_sec);
        oem_printf("[OEM] %s\n", gmt);
    }

    u_macstr_to_array(macstr, mac_addr, 6);

    return 0;

}

2 TODO

原创粉丝点击