Wireshark-dev: Re: [Wireshark-dev] Problems with r40742

From: Guy Harris <guy@xxxxxxxxxxxx>
Date: Thu, 16 Feb 2012 16:12:30 -0800
On Feb 16, 2012, at 2:47 PM, Jeff Morriss wrote:

> Stephen Fisher wrote:
>> r40742 is causing compilation problems on FreeBSD (64-bit 9.0-RELEASE):
>>    packet-smpp.c: In function 'smpp_mktime':
>>    packet-smpp.c:1189: error: invalid operands to binary -
>> With reference to this code:
>> 	*secs -= timezone;
>> ... for which Jeff had concerns about its portability in the commit comment:
>> "1) subtract the 'timezone' (or '_timezone' on Windows) back out after calling
>>   mktime()
>> ...
>> (I *think* (1) is portable: POSIX says that variable should exist...)"
> 
> Shoot.
> 
> Looks like FreeBSD provides a timezone() function which they admit[1] is not POSIX compliant[2].

Yeah, because this operating system called "The UNIX Time-Sharing System, Seventh Edition", from a place called "Bell Laboratories", had it, and that passed it on to UNIX/32V, from which the Third and Fourth Berkeley Software Distribution was derived, and {Free,Net,Open,DragonFly}BSD were derived from that.

So, no, the FreeBSD guys didn't invent timezone(); Ken, Dennis, and company did.  Others at AT&T invented the "timezone" variable.

And, according to

	http://pubs.opengroup.org/onlinepubs/009695399/functions/timezone.html

the timezone variable is part of the "XSI extension", which presumably is the "all the stuff in the earlier System V Interface Definition-derived X/Open specs".  At least one system that is a UNIX(TM):

	http://www.opengroup.org/openbrand/register/brand3581.htm

has - not surprising, given its BSD heritage - timezone()-as-a-function, so, actually, POSIX/the Single Unix Specification *doesn't* require it.

If the goal is to have a function that is to mktime() as gmtime() is to localtime() - i.e., that converts a UTC-style date/time specification of year/month/day/hour/minute/second into a so-called "seconds since the Epoch" value (which is not actually a count of the number of seconds that have elapsed since the Epoch, as the), try this bit from the Single Unix Specification:

	4.15 Seconds Since the Epoch

	A value that approximates the number of seconds that have elapsed since the Epoch. A Coordinated Universal Time name (specified in terms of seconds (tm_sec), minutes (tm_min), hours (tm_hour), days since January 1 of the year (tm_yday), and calendar year minus 1900 (tm_year)) is related to a time represented as seconds since the Epoch, according to the expression below.

	If the year is <1970 or the value is negative, the relationship is undefined. If the year is >=1970 and the value is non-negative, the value is related to a Coordinated Universal Time name according to the C-language expression, where tm_sec, tm_min, tm_hour, tm_yday, andtm_year are all integer types:

	tm_sec + tm_min*60 + tm_hour*3600 + tm_yday*86400 + (tm_year-70)*31536000 + ((tm_year -69)/4)*86400 - ((tm_year-1)/100)*86400 + ((tm_year+299)/400)*86400

	The relationship between the actual time of day and the current value for seconds since the Epoch is unspecified.

	How any changes to the value of seconds since the Epoch are made to align to a desired relationship with the current actual time is implementation-defined. As represented in seconds since the Epoch, each and every day shall be accounted for by exactly 86400 seconds.

At least as I read section 4.7.23.4 "Absolute Time Format" of the SMPP V5.0 spec, an Absolute Time Stamp has a (non-Y2.1K-safe!) date/time value that I infer from "in UTC format" is UTC, plus an indication of the time zone offset from local time (presumably the time zone offset *at the specified time* - the offset, of course, varies over time).  If so, then, yes, you want said function.

(Given that the spec says "second (00-59)", they don't support leap seconds, so POSIX's crufty "seconds since the Epoch assuming that all the clocks in the universe freeze during a positive leap second" doesn't get in the way, and the simple calculation there should work.)