Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

Here's the sort of time formatting I'm after:

2009-10-08 04:31:33.918700000 -0500

I'm currently using this:

strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S %Z", ts);

Which gives:

2009-10-11 13:42:57 CDT

Which is close, but not exact. I can't seem to find anything on displaying -0500 at the end. Plus I'm getting the seconds as an int.

How can I resolve these two issues?

share|improve this question
add comment

3 Answers

up vote 8 down vote accepted

I came up with this:

    char            fmt[64], buf[64];
    struct timeval  tv;
    struct tm       *tm;

    gettimeofday(&tv, NULL);
    if((tm = localtime(&tv.tv_sec)) != NULL)
    {
            strftime(fmt, sizeof fmt, "%Y-%m-%d %H:%M:%S.%%06u %z", tm);
            snprintf(buf, sizeof buf, fmt, tv.tv_usec);
            printf("'%s'\n", buf); 
    }

Fixes for the problems you had:

  • Use gettimeofday(), and struct timeval, which has a microseconds member for the higher precision.
  • Use a two-step approach, where we first build a string containing all the data except the microseconds.
  • Use lower-case 'z' for the timezone offset. This seems to be a GNU extension.

I tried re-creating the timezone offset manually, through the second struct timezone * argument of gettimeofday(), but on my machine it returns an offset of 0 which is not correct. The manual page for gettimefday() has quite a lot to say about the handling of timezones under Linux (which is the OS I tested on).

share|improve this answer
    
%z is still non-standard =) –  gnud Oct 11 '09 at 20:18
    
Thanks, this is the closest I've gotten so far. The '%%06u' is just throwing garbage data back at me right now but the rest works well. P.S Yes, I know the %z is non-standard, but I'll take it :) –  Vlad the Impala Oct 11 '09 at 20:40
    
@aditya: That's weird ... The code above should work. Make sure you provide the second snprintf() call with a proper unsigned microseconds value to use for the %06u format. You can try printing the result after the strftime() call, you should see your final output except for the %06u sequence after the period. –  unwind Oct 11 '09 at 20:55
2  
It seems everyone here have missed the fact that %z is completely standard C99. It's in (the freely available) draft n1256 (tc3 working paper) as well as the official standard document, and it is also specified in POSIX (pubs.opengroup.org/onlinepubs/9699919799/functions/…). –  Quantumboredom Mar 21 '13 at 19:11
    
tv.tv_usec is type suseconds_t. Have not found a % modifier for it. Maybe a cast to (unsigned long) and use %06lu. (or cast to (uintmax_t) and use PRIuMAX. –  chux Aug 25 '13 at 0:47
add comment

"%Y-%m-%d %T %z", but it seems %z is a GNU extension.

share|improve this answer
2  
%T does not give the sub-second digits asked for in the question. –  unwind Oct 11 '09 at 20:22
add comment

%z (lower case z).

However, this does not appear in the Posix specification. Google took me in a circle back here.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.