2

It seems remarkably difficult to find out what a valid range of values is for time_t.

It is on some platforms 32 bit, on most 64 bit, and so can easily enough be set to LONG_MAX. However trying to then use that value doesn't really work properly. For instance you can't pass it to localtime and change it into a struct tm.

A quick test program to binary search the value tells me it is 67768036191676799. That corresponds to the end of year 2147483647, so that makes sense as a value. But is it this specified anywhere, and is there any reasonable, platform independent value for a maximum usable time_t?

asc99c
  • 3,815
  • 3
  • 31
  • 54
  • possible duplicate of [What is ultimately a time\_t typedef to?](http://stackoverflow.com/questions/471248/what-is-ultimately-a-time-t-typedef-to) – egrunin Feb 07 '13 at 17:27
  • 1
    possible duplicate of [Maximum values for time\_t (struct timespec)](http://stackoverflow.com/questions/5617925/maximum-values-for-time-t-struct-timespec) – Charles Salvia Feb 07 '13 at 17:27
  • 3
    I don't believe it is a duplicate. Neither existing question references my question of the largest usable value for time_t? – asc99c Feb 07 '13 at 17:35
  • aren't we in transition towards 64bit? – जलजनक Feb 07 '13 at 17:37
  • @asc99c: some of the answers touch on the issue, but I agree with you that neither of the questions does. And to the extent that the answers touch on it I suspect they might get it wrong for this purpose. They're really not considering what you can actually use with `localtime`. ;-) – Steve Jessop Feb 07 '13 at 17:37
  • 1
    keep in mind that even with the biggest numerically value of a time_t, there's implementations where the some (usually large) time_t are producing utter gibberish by standard functions such as e.g. localtime() – nos Feb 07 '13 at 17:40
  • Yes that is exactly the point of my question. The application in question has it's own time format, but our internal maximum time (essentially DBL_MAX) when converted back to a time_t leads to all kinds of problems passing it through standard time libraries. – asc99c Feb 08 '13 at 17:03

3 Answers3

1

Indeed, the specification for time_t and clock_t are implementation defined (C99 7.23.1).

This is one of those things where I would recommend not generating these values yourself, but rely on the implementation to create them for you such as with mktime(), and use the struct tm for directly manipulating the time. -1 is the only value of time_t that is a "good" value you can use on your own.

I would specifically suggest that you not treat it as a 32 bit value of any type, as jgm suggests. You just never know if some strange embedded compiler will want to use a 16 bit time or 18 or who knows.

Peter M
  • 1,918
  • 16
  • 24
0

The safest way to use it is as a 32-bit signed, as long as you're happy with it not working 25 years from now.

Otherwise you're going to have to test the type yourself on whichever platforms you run on and act accordingly.

  • Or even safer treat it as a 31 bit unsigned, because you might well see implementations where it's a 32 bit signed. – Steve Jessop Feb 07 '13 at 17:30
  • Yeah, that 25 year limit just isn't reasonable any more. I was hoping by now a proper solution should be implemented! – asc99c Feb 07 '13 at 17:33
  • It is; you have a 64-bit value. But there are lots of legacy systems and code still laying around. If you're building from scratch then a 64-bit value won't be a problem, but if you're using other libraries and/or integrating with older systems you will have to check each of them. The good news is that it's relatively painless to write a bit of test code to find out quickly how well they handle it. –  Feb 07 '13 at 17:37
  • @asc99c: indeed, you wouldn't think it'd be difficult for the standard to include a `TIME_MAX` and a `TIME_MIN` that are endpoints of a range guaranteed to "work" in the context of `localtime`, `gmtime` and `mktime`. The only saving is that the standard states that it's implementation-defined, so the implementation has to document it. Somewhere. – Steve Jessop Feb 07 '13 at 17:41
0

tm_year has type int, so if you will be converting to struct tm, the largest meaningful time_t is the value corresponding to year INT_MAX.

R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711
  • So to be portable, you have to cope with the case where the upper bound is due to the max value of `time_t` and also with the case where the upper bound is due to the max value of `tm_year`, but not with any other sources of limitations? Is `localtime` allowed to flake out not because `tm_year` has overflowed but because the implementers have chosen not to make predictions about leap years that far ahead, and just return null? The earth won't be spinning at an even vaguely similar rate in 2 billion years, so the Gregorian calendar is toast even if human civilisation isn't ;-) – Steve Jessop Feb 07 '13 at 18:04
  • Yes. C is pretty vague about if/when functions are allowed to fail. POSIX would allow it to fail for implementation-defined reasons, but the implementation would have to choose a new, appropriate error code; it's not allowed to reuse one of the existing ones specified for `localtime`. If the goal is to have *consistent* behavior between diverse systems, it's probably best to avoid using the standard functions and just work with POSIX seconds-since-the-epoch time in `int64_t` yourself, or something similar... – R.. GitHub STOP HELPING ICE Feb 07 '13 at 19:00