Take the 2-minute tour ×

I am trying to make an easily accessible TimeDate variable, but am having problems with conversion. In time.h, how would I convert time_t (seconds since 1/1/1970), into the current local timezone (compensating for daylight savings time if applicable), so that:

time_t Seconds;


struct TimeDate
    short YYYY;
    unsigned char MM;
    unsigned char DD;

    unsigned char HH; //Non-DST, non-timezone, IE UTC (user has to add DST and TZO to get what they need)
    unsigned char MM;
    unsigned char S;

    char TZ[4]; //This can be optionally a larger array, null terminated preferably
    char TZO; //Timezone Offset from UTC        

    char DST; //Positive is DST (and amount of DST to apply), 0 is none, negative is unknown/error

Without using any string literals (bar for the timezone name) in the process (to keep it efficient)? This is also taking into account leap years. Bonus if TimeDate can be converted back into time_t.

share|improve this question
add comment

1 Answer

The C standard library (accessible in C++ by using ctime) provides localtime for exactly that purpose (or gmtime for UTC). You could shoe-horn the resultant struct tm into your own structure after that if there's some reason why the standard one is not sufficient to your needs.

The one thing it doesn't provide is the timezone itself but you can get that (and the offset in ISO 8601 format) by using strftime with the %Z and %z format strings

By way of example, here's a program that demonstrates this in action:

#include <iostream>
#include <cstdlib>
#include <ctime>

int main(void) {
    time_t t;
    struct tm *tim;
    char tz[32];
    char ofs[32];

    std::system ("date");
    std::cout << std::endl;

    t = std::time (0);
    tim = std::localtime (&t);
    std::strftime (tz, sizeof (tz), "%Z", tim);
    std::strftime (ofs, sizeof (ofs), "%z", tim);

    std::cout << "Year:        " << (tim->tm_year + 1900) << std::endl;
    std::cout << "Month:       " << (tim->tm_mon + 1) << std::endl;
    std::cout << "Day:         " << tim->tm_mday << std::endl;
    std::cout << "Hour:        " << tim->tm_hour << std::endl;
    std::cout << "Minute:      " << tim->tm_min << std::endl;
    std::cout << "Second:      " << tim->tm_sec << std::endl;
    std::cout << "Day of week: " << tim->tm_wday << std::endl;
    std::cout << "Day of year: " << tim->tm_yday << std::endl;
    std::cout << "DST?:        " << tim->tm_isdst << std::endl;
    std::cout << "Timezone:    " << tz << std::endl;
    std::cout << "Offset:      " << ofs << std::endl;

    return 0;

When I run this on my box, I see:

Wed Sep 28 20:45:39 WST 2011

Year:        2011
Month:       9
Day:         28
Hour:        20
Minute:      45
Second:      39
Day of week: 3
Day of year: 270
DST?:        0
Timezone:    WST
Offset:      +0800
share|improve this answer
Hi pax, looking at localtime, it puts into a tm structure, of which is days/hours/minutes ... since 1/1/1970. The problem with this is I don't want how many hours have elapsed since 1/1/1970, I want what the present time is (in UTC format with DST/Timezone separate). It also does not supply the timezone employed or the amount of hours the timezone is offset by. –  SSight3 Sep 28 '11 at 11:20
@SSight3: I think you want to read that description again. –  Nemo Sep 28 '11 at 11:24
The fields in struct tm are exactly what you asked for. They have nothing to do with 1970. So I think you need to read the description for it again. –  Nemo Sep 28 '11 at 11:44
@SSight3: you're free to make that decision if you think the standard C stuff doesn't suit your purpose but I've not seen any requirement in your question that it can't meet. I personally think you're wasting your time and that you should rethink your obvious aversion to using the facilities already provided to you, but that's your call, not mine. All I can do is offer advice - lead a horse to water and all that stuff :-) –  paxdiablo Sep 28 '11 at 12:50
@SSight3: He just provided a complete program that does everything you are asking for using 100% standard C++ interfaces. If you do not accept his answer, you need to change your question, because it does everything you asked for in every detail. –  Nemo Sep 28 '11 at 14:34
show 7 more comments

Your Answer


