[Dshield] Various Updates

Bruce Lilly blilly at erols.com
Thu Aug 9 14:47:42 GMT 2001


> From: "Kenneth McKinlay" <km-web at home.com>
> To: dshield at dshield.org
> Date: Wed, 8 Aug 2001 20:50:03 -0400
> Subject: Re: [Dshield] Various Updates
> Reply-To: dshield at dshield.org
> 
> The perl script that I "borrowed" to do the timezone determination in
> my scripts is this function:
> 
> -----------
> # calculate TZ based on gmtime and localtime
> # from a UseNet posting by Larry Rosler on February 13, 1999
> #
> sub tz_offset {
>         my $now = time;
>         my ($l_min, $l_hour, $l_year, $l_yday) = (localtime $now)[1, 2, 5, 7];
>         my ($g_min, $g_hour, $g_year, $g_yday) = (gmtime $now)[1, 2, 5, 7];
>         my $tz=($l_min - $g_min)/60 + $l_hour - $g_hour + 24 * ($l_year - $g_year || $l_yday - $g_yday);
> 
>         my $return=sprintf "%+03d:%02d",int $tz, ($tz - int $tz) * 60;
>         $return;
> }
> ------------
> 
> All I have to do is call it like this:
>         $tz=tz_offset();
> 
> As far as I know, this should work for figuring out that stupid DST
> issue.
> 
> Ken McKinlay
> Ottawa, Canada

I suspect that that won't work properly at the end of a year,
and it almost certainly won't work at the end of a leap year.
Here's what C code to compute the local offset looks like:
=================================================================
#include <sys/types.h>  /* time_t */
#include <time.h>       /* gmtime, localtime */

        time_t          now;
        struct tm       tms_local,      tms_utc;
        int             hhmm,   ndays,  yr;

        (void) time(&now);
        tms_local = *localtime(&now);
        tms_utc = *gmtime(&now);
        if (tms_local.tm_year > tms_utc.tm_year)
                yr = 1900 + tms_utc.tm_year;
        else
                yr = 1900 + tms_local.tm_year;
        if ((yr % 4 == 0) && ((yr % 100 != 0) || (yr % 400 == 0)))
                ndays = 366;
        else
                ndays = 365;
        hhmm = (((tms_local.tm_year - tms_utc.tm_year) * ndays
                + tms_local.tm_yday - tms_utc.tm_yday) * 24
                + tms_local.tm_hour - tms_utc.tm_hour) * 100
                + tms_local.tm_min - tms_utc.tm_min;
==================================================================
hhmm is in the format used by RFCs 821/822/2821/2822.

At the end of a year, the tm_yday fields are potentially offset
by more than 1 day. The difference will depend on whether or not
the earlier year (gmtime or localtime) is a leap year.

Note that either of the above methods will only work if the user
has correctly set the local time zone.

Your sprintf format is non-portable: %+03d may yield -001 (e.g.)
on some systems. %+0.2d is portable (I use %+0.4d with hhmm to
generate RFC-compliant offsets).




More information about the list mailing list