Convert unix timestamp to date without system libs
c, date, embedded, timestamp
Solution
First divide by 86400; the remainder can be used trivially to get the HH:MM:SS part of your result. Now, you're left with a number of days since Jan 1 1970. I would then adjust that by a constant to be the number of days (possibly negative) since Mar 1 2000; this is because 2000 is a multiple of 400, the leap year cycle, making it easy (or at least easier) to count how many leap years have passed using division.
Rather than trying to explain this in more detail, I'll refer you to my implementation:
http://git.musl-libc.org/cgit/musl/tree/src/time/__secs_to_tm.c?h=v0.9.15
Problem
I am building a embedded project which displays the time retrieved from a GPS module on a display, but I would also like to display the current date. I currently have the time as a unix time stamp and the progject is written in C. I am looking for a way to calculate the current UTC date from the timestamp, taking leap years into account? Remember, this is for an embedded project where there is no FPU, so floating point math is emulated, avoiding it as much as possible for performance is required. EDIT After looking at @R...'s code, I decided to have a go a writing this myself and came up with the following. ``` void calcDate(struct tm *tm) { uint32_t seconds, minutes, hours, days, year, month; uint32_t dayOfWeek; seconds = gpsGetEpoch(); /* calculate minutes */ minutes = seconds / 60; seconds -= minutes * 60; /* calculate hours */ hours = minutes / 60; minutes -= hours * 60; /* calculate days */ days = hours / 24; hours -= days * 24; /* Unix time starts in 1970 on a Thursday */ year = 1970; dayOfWeek = 4; while(1) { bool leapYear = (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)); uint16_t daysInYear = leapYear ? 366 : 365; if (days >= daysInYear) { dayOfWeek += leapYear ? 2 : 1; days -= daysInYear; if (dayOfWeek >= 7) dayOfWeek -= 7; ++year; } else { tm->tm_yday = days; dayOfWeek += days; dayOfWeek %= 7; /* calculate the month and day */ static const uint8_t daysInMonth[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; for(month = 0; month < 12; ++month) { uint8_t dim = daysInMonth[month]; /* add a day to feburary if this is a leap year */ if (month == 1 && leapYear) ++dim; if (days >= dim) days -= dim; else break; } break; } } tm->tm_sec = seconds; tm->tm_min = minutes; tm->tm_hour = hours; tm->tm_mday = days + 1; tm->tm_mon = month; tm->tm_year = year; tm->tm_wday = dayOfWeek; } ```