How to get Unix Timestamp?



  • Another problem. ;)

    I noticed that DateTime doesn't support Unix Timestamp (seconds since 1/1/1970 UTC).

    mbed has function time (example) but it's not working as time(NULL) only returns -1.

    Also trying to use related function set_time from mbed gives error 'set_time' was not declared in this scope.



  • I will look at what it takes to implement the mbed (Clib style) time functions.

    DateTime is a calendar based timestamp, that counts years, days etc. It implements the Gregorian calendar standard. Therefore I have postponed to implementing conversion to and from UNIX style time stamps.

    Read: Anyone willing to pitch in, and add UNIX timestamp support in either mbed time functions, or DateTime are very welcome ;-)



  • It seems that converting from Gregorian calendar to Unix Time is easiest to do by first converting to JDN (Julian day number).

    Wikipedia article https://en.wikipedia.org/wiki/Julian_day has needed formulas, from Gregorian year/month/date to JDN and then from JDN to Unix Time.

    I can try to write this in C++ shortly.

    ps. I wonder who came up with the JDN formula, it's fun trying to understand it - http://www.cs.utsa.edu/~cs1063/projects/Spring2011/Project1/jdn-explanation.html



  • I'm still testing this, but so far this seems to work:

        /**
         * @brief Return Julian day number of the DateTime
         */
        uint32_t toJulianDayNumber() const;
    
        /**
         * @brief Returns Unix time of the DateTime
         */
        uint32_t toUnixTime() const;
    
    ...
    
    uint32_t DateTime::toJulianDayNumber() const
    {
        if (type == LOCAL_TIME_ZONE) return toUtcTime().toJulianDayNumber();
        
        // this formula is from https://en.wikipedia.org/wiki/Julian_day
        
        uint32_t a = (14 - month) / 12;
        uint32_t y = year + 4800 - a;
        uint32_t m = month + 12 * a - 3;
        uint32_t jdn = day + (153 * m + 2) / 5
            + 365 * y + (y / 4) - (y / 100) + (y / 400) - 32045;
        
        return jdn;
    }
    
    uint32_t DateTime::toUnixTime() const
    {
        if (type == LOCAL_TIME_ZONE) return toUtcTime().toUnixTime();
    
        uint32_t jdn = toJulianDayNumber();
        uint32_t hms = hours * 3600 + mins * 60 + secs;
        uint32_t unix_time = (jdn - 2440588) * 86400 + hms;
    
        return unix_time;    
    }
    


  • @malaire Cool! When ever you are ready, you are welcome to submit a pull request on GitHub 😀

    I have realized that libc already contains time component conversion functions, that DateTime does not use. I was unaware of libc capabilities when I wrote the DateTime class 😖

    I think it would be a good thing to replace the date / time manipulation implementations with libc's functions.

    We can use localtime or gmtime for UTC time zones. These take a time_t and returns broken-down date and time components. The reverse can be done by timelocal or timegm.

    We could keep DateTime as a component based, absolute time specification. Then create a class called TimeInterval or TimeSpan that is a wrapper around time_t. This will allow the following semantics in operator overloads:

    //subtraction of 2 absolute times
    TimeInterval = DateTime - DateTime
     
    // subtraction and addition of absolute and relative times
    DateTime = DateTime - TimeInterval
    DateTime = DateTime + TimeInterval
    
    // subtraction and addition of relative times
    TimeInterval = TimeInterval - TimeInterval
    TimeInterval = TimeInterval + TimeInterval
    

    We could also call it TimeSpan or just Time



  • The reverse can be done by timelocal or timegm.

    I just realized the timelocal-like functions are missing from newlib-nano. And that is what we use on Mono.

    EDIT: In newlib-nano (and newlib) the timelocal is called: mktime.



  • ok, I added pull request.

    As for libc functions, timegm doesn't seem to be available and it seems to be a non-standard function. But as it seems to do basically same what I just added as DateTime::toUnixTime, I'm not sure if that is really needed.

    UTC is somewhat simple to handle even without library functions, but localtime and especially daylight saving time is definitely not.


Log in to reply