2

time_t this is platform dependent type. I found difftime which returns difference in seconds, but I did not find function for simple subtraction without any convertations. How I know standard does not does not guarantee that will go consistently throughout the whole time continuum and does not told anything about encoding of time_t. Also it does not told that two different time_t will not represent one time moment. But I'm not sure about this in real life.

The time_t datatype is a data type in the ISO C library defined for storing system time values. Such values are returned from the standard time() library function. This type is a typedef defined in the standard header. ISO C defines time_t as an arithmetic type, but does not specify any particular type, range, resolution, or encoding for it. Also unspecified are the meanings of arithmetic operations applied to time values.

Unix and POSIX-compliant systems implement time_t as an integer or real-floating type (typically a 32- or 64-bit integer) which represents the number of seconds since the start of the Unix epoch: midnight UTC of January 1, 1970 (not counting leap seconds). Some systems correctly handle negative time values, while others do not. Systems using a signed 32-bit time_t type are susceptible to the Year 2038 problem.]

https://en.wikipedia.org/w/index.php?title=Time_t&oldid=450752800

I meant I need time_t in return:

time_t v1;
time_t v2;
time_t diff;

diff = some_substract_fct(v2, v1)

Is it safe to compare/substract two time_t without difftime? E.g.:

time_t v1;
time_t v2;
time_t diff;

if (v2 > v1)
{
    ....
}

if (v2 == v1)
{
    ....
}

v3 = v2-v1;

instead

if (difftime(v2, v1) > 0)
{
}

if (difftime(v2, v1) == 0.0)
{
}

diff = some_substract_fct(v2, v1)
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • It's not safe to use `-` as the representation is implementation specific see here: https://stackoverflow.com/a/13855956/8051589. This also holds for the comparison operators, see also here: https://stackoverflow.com/a/25198359/8051589. As the represention is implementation defined this timestamp value `time_t` could not save a time difference. Why is a double value not the right for you? – Andre Kampling Aug 10 '17 at 13:18
  • Most implementations (that I used so far) will use an integer value with an increasing number where `-`, `<`, `>`, `!=` and `==` will work. But that is not guaranteed. – Andre Kampling Aug 10 '17 at 13:25
  • 1
    @Andre Kampling: Since I have some task manager with time's calculations, operations, scheduling etc. and I want to work with one type (`time_t`) without any conversions. If I will need time difference I will call `difftime`. If I need decode `time_t` (with time zone processing) I will call `localtime`. E.g. add to `time_t` some diff. Is it really need to convert `time_t` to `tm` then do some processing and convert results back to `time_t`? I'm hope that exist more tiny way without conversions. E.g. `time_t diff = some_fct(t2-t1)` – Alexander Symonenko Aug 10 '17 at 13:29
  • If you want to add the `time_t` you have to do it like here: https://codereview.stackexchange.com/a/5101. Use the `mktime()` function to adjust the values in the structure because the seconds may be out of range. – Andre Kampling Aug 10 '17 at 13:37
  • Most people "live dangerously" and assume that you can do direct arithmetic on `time_t` values. Be aware that if you port to an extraordinary system, you might have to fix your code, but so would everyone else, and it would be an extraordinarily foolhardy system vendor who did not provide a simple type. Said vendor could appeal to the standard and they'd be right; the programmers would probably vote with their feet and ignore it. Be aware that there is a theoretical issue. Don't worry about it in practice unless you work on a very peculiar system. – Jonathan Leffler Aug 10 '17 at 13:41
  • Why don't use your own type that is large enough to avoid "consequences". Like `typedef int64_t my_time_t;` and then use it: `((my_time_t) t1) - ((my_time_t) t2)` – myaut Aug 10 '17 at 13:49
  • 1
    `time_t` is an arithmetic type, so subtraction in itself is not a question. The _sign_ of the difference is certainly as expected, later times have greater values. Yet the scale and epoch of `time_t` are not known. Recommend to wrap your subtraction in a helper function. – chux - Reinstate Monica Aug 10 '17 at 13:53
  • Note: `(time_t) -1` is specified as the error return value from various time functions. – chux - Reinstate Monica Aug 10 '17 at 13:54
  • 2Jonathan Leffler: thx for your point of view. It seems there is really no normal call for typical operations. It is really amazing that they (ISO) have type but they does not have operations for work with this type. It's ammazing. All need to do through roundabout ways with some hemorrhoids: convert it to some other type (`tm`), do some operations, convert it back (`mktime`). – Alexander Symonenko Aug 10 '17 at 13:58
  • 2chux How I know standard does not told anything about encoding of `time_t` type so you assumption is statement. Right? But it told that `difftime` will return seconds which can compare. So if time point of `t2` value > time point of `t1` value then I will sure that `difftime` will return value > 0. – Alexander Symonenko Aug 10 '17 at 14:06
  • 1
    Note that you need to use an `@` not a `2` to get the notification to an individual (`@Jonathan` would work, `2Jonathan` does not). – Jonathan Leffler Aug 10 '17 at 14:17
  • The `difftime()` function was created by the standards committee; there must have been a sufficiently compelling reason for them to do so, but it is also, as you note, a very peculiar half-baked decision because there is no `addtime()` function, etc. I'm not aware of a system where `time_t` is not an integer type (but there are lots of things I'm unaware of). If I ever have the misfortune to need to port code to a system where `time_t` isn't manipulable by ordinary arithmetic, then the time-manipulating code will have to be analyzed and revised. Until then, it is a spurious problem. – Jonathan Leffler Aug 10 '17 at 14:21
  • Of ``, the standard says (§7.27.1): _The types declared are `size_t` (described in 7.19); `clock_t` and `time_t` which are real types capable of representing times;_ The term 'real types' is specified in §6.2.5 — ¶17 _The integer and real floating types are collectively called real types._ So, `time_t` can be manipulated by the ordinary `+`, `-`, `*` and `/` operators (but not necessarily by `%` — it might not be an integer type). There's no specification of what the different values mean, though. – Jonathan Leffler Aug 10 '17 at 14:29
  • The one thing that `difftime()` does is guarantee that the difference is measured in seconds — there is no guarantee that the units of `time_t` are seconds (though I don't know of a system with another specification). The values in `time_t` could be milliseconds, or ten second units, or … The `difftime()` function guarantees the result is measured in seconds. – Jonathan Leffler Aug 10 '17 at 14:31

1 Answers1

3

Quoting the C11 Standard:

7.27.2.4 The time function

Description

The time function determines the current calendar time. The encoding of the value is unspecified.

Returns

The time function returns the implementation’s best approximation to the current calendar time. The value (time_t)(-1) is returned if the calendar time is not available. If timer is not a null pointer, the return value is also assigned to the object it points to.

Hence you cannot make any assumptions on the encoding or meaning of time_t values. Different values may represent the same time, comparison with < etc. are meaningless, and the same for the regular arithmetic subtraction with -.

On POSIX compliant systems however, the time_tvalue, whose type is still unspecified, represents the number of seconds since Jan 1st, 1970 UTC. So you can compare, subtract and add values with the expected behavior. On other systems, you may need to use system specific functions to retrieve the current time in a specified format or use difftime() to compute time differences in seconds.

Note also that another standard function might be available on your system that will provide more accurate timestamps in a specified format:

7.27.2.5 The timespec_get function

Synopsis

 #include <time.h>
 int timespec_get(struct timespec *ts, int base);

Description

The timespec_get function sets the interval pointed to by ts to hold the current calendar time based on the specified time base. If base is TIME_UTC, the tv_sec member is set to the number of seconds since an implementation defined epoch, truncated to a whole value and the tv_nsec member is set to the integral number of nanoseconds, rounded to the resolution of the system clock.

Returns

If the timespec_get function is successful it returns the nonzero value base; otherwise, it returns zero.

chqrlie
  • 131,814
  • 10
  • 121
  • 189
  • The `timespec_get()` function is not available everywhere (macOS Sierra 10.12.6 doesn't have it, for example). And although `` declares it, my Ubuntu 16.04 system does not have a man page entry for it (though I'm quite willing to believe it is because I am missing the man page rather than that it is undocumented). – Jonathan Leffler Aug 10 '17 at 14:46