Thomas Morris
Thomas Morris

Reputation: 822

Unix Time stamp creation in C from custom data fields

I wish to create a Unix time stamp. I have a micro-controller with a ble connection that I send the present time to via a GATT connection. I receive the data several integers.

These are Year, Month, Day, Hour, Minute and Second. e.g:

I want to convert this to Unix time so I can then increment the value every second via a interrupt based timer. Therefore, what is the correct way to conjoin this data together to form the Unix time. My presumption is as follows:

Create a integer value large enough to store the value called unix time and add the equivalent seconds from the respective time components(year,month etc).

These are the value in seconds

Therefore, Unix time =

Is there anything wrong about my presumptions here?

I don't know how unix time deals with the different number of days in a month as different months have different lengths. Also leap years. So do I need another lookup table or something to make this accurate?

Or what is the correct method for getting the unix time from my set of data?

Upvotes: 1

Views: 324

Answers (2)

Saitejareddy
Saitejareddy

Reputation: 361

The timestamp is nothing but an elapsed time from 1st January 1970 to any specific instance.

With this logic lets see the steps to implementation a method to get timestamp from the date-time.

These are the value in seconds as mentioned in the question itself
Day_in_seconds = 86400
Hour_in_seconds = 3600
Minute_in_seconds = 60

1. First calculate the second for the year you want seconds for:

int yearInSeconds = (year - 1970)*365*86400 + // assume all year has only 365 day and multiple 365 * 86400(seconds in a day)
                    (year - 1968)/4 * 86400 // now here we are adding 1 day seconds for all the leaps which comes once in every 4 years from the first leap 1972 to till date

To check the leap years you can refer this tool.

2. Calculation of seconds for the a given month:

As a month can have following possible days [28, 30, 31] // excluding leap year february. lets create a cumulative month array which have the completed month days count at any particular month

const int daysInMonth[] = { 0, 31, 59, 90, 120, 151, 181, 211, 242, 272, 303, 333 };

seconds for a month = daysInMonth[month-1] * 86400 // daysInMonth[month-1] gives the days count of the full completed months and multiply with 86400(seconds in a day)

3. Calulation of seconds of a given day, hour, minutes and second:

// seconds of given day, hour, minutes and second as totalSeconds
int totalSeconds = day*86400 + hour*3600 + minute*60 + second; // multipling the given data with the above mentioned constants for day, hour and minute.

4. Now lets handle the special case where if you are querying for leaps date.

In the first step we added 1 day seconds for all the leap year, if your query is for leap year with a month on or before february that means we didn't crossed 29th of february.

For this we need subtract on day seconds from the final result.

if(!(year%4) && month <= 2) {
  result = result - 1*86400;
}

final code given below:

int getUnixTimestamp(int year, int month, int day, int hour, int minute, int second) {
    const int daysInMonth[] = {
        0,
        31,
        59,
        90,
        120,
        151,
        181,
        211,
        242,
        272,
        303,
        333
    };
    int unixtime = (year - 1970) * 86400 * 365 +
        ((year - 1968) / 4) * 86400 +
        daysInMonth[month - 1] * 86400 +
        (day - 1) * 86400 +
        hour * 3600 +
        minute * 60 +
        second;
    if (!(year % 4) && month <= 2) {
        unixtime -= 86400;
    }
    return unixtime;
}

This code will work until the year 2100, for more info or to check the time conversions you can use this tool.

Upvotes: 0

Ctx
Ctx

Reputation: 18420

This should be accurate up to 2100:

unsigned int tounix (int year, int month, int day, int hour, int min, int sec) {
    unsigned int epoch = 0;
    // These are the number of days in the year up to the corresponding month
    static const unsigned int monthdays[] = { 0, 31, 59, 90, 120, 151, 181, 211, 242, 272, 303, 333 };
    epoch = (year-1970)*86400*365u +    // Account the years
            ((year-1968)/4)*86400 +    // leap years
            monthdays[month-1]*86400 + // days in past full month
            (day-1)*86400u + hour*3600 + min*60 + sec; // days, hours, mins, secs

    if (!(year%4)&&month < 3) // Correct 1 day if in leap year before Feb-29
        epoch -= 86400;

    return epoch;
}

Input is expected as:

  • Year: 1970 - 2099
  • Month: 1 - 12
  • Day: 1 - 31
  • Hour, Minute, Second: as usual ;)

Upvotes: 4

Related Questions