The following issue has been SUBMITTED. 
====================================================================== 
https://austingroupbugs.net/view.php?id=1533 
====================================================================== 
Reported By:                steffen
Assigned To:                
====================================================================== 
Project:                    1003.1(2016/18)/Issue7+TC2
Issue ID:                   1533
Category:                   Base Definitions and Headers
Type:                       Enhancement Request
Severity:                   Editorial
Priority:                   normal
Status:                     New
Name:                       steffen 
Organization:                
User Reference:              
Section:                    time.h 
Page Number:                425 
Line Number:                14451 
Interp Status:              --- 
Final Accepted Text:         
====================================================================== 
Date Submitted:             2021-11-08 22:04 UTC
Last Modified:              2021-11-08 22:04 UTC
====================================================================== 
Summary:                    struct tm: add tm_gmtoff (and tm_zone) field(s)
Description: 
Hello.

Regarding the MUA i maintain i was pinged by a user who needs to
use the timezone Europe/Dublin.  He wrote

      In 2018, the tzdata maintainers (IANA) corrected a historical
mistake
      with the Europe/Dublin timezone. The mistake was rooted in a
      misunderstanding of whether IST meant "Irish Summer Time" or "Irish
      Standard Time".

      The problem was discussed at great length
      (http://mm.icann.org/pipermail/tz/2018-January/thread.html) and it
was
      concluded that IST really meant Irish *Standard* Time (in constrast
      with, say, British *Summer* Time), and that this standard time is
      defined as UTC+0100.
[.]
      Once the question was settled, the only possible solution for
keeping
      the Irish local time in sync with the rest of the world (for
example,
      Belfast & London) was for IANA to _reverse_ the functioning of the
DST
      flag for Ireland. The result is that in the current IANA timezone
      database (2021e), Europe/Dublin has DST applied in *winter*, with an
      adjustment of -1h (that is, negative).
[.]
      It turns out that the introduction of a negative DST adjustment
caused
      all sorts of bugs back in 2018; in the source distribution of IANA's
      tzdata, one can spot this inside ./europe:

        # In January 2018 we discovered that the negative SAVE values in
the
        # Eire rules cause problems with tests for ICU [...] and with
tests
        # for OpenJDK [...]
        # To work around this problem, the build procedure can translate
the
        # following data into two forms, one with negative SAVE values and
the
        # other form with a traditional approximation for Irish timestamps
        # after 1971-10-31 02:00 UTC; although this approximation has
tm_isdst
        # flags that are reversed, its UTC offsets are correct and this
often
        # suffices.  This source file currently uses only nonnegative SAVE
        # values, but this is intended to change and downstream code
should
        # not rely on it.

      So, a temporary hack was put in place in order to allow distro
      maintainers to retain the old broken convention of IST and support
      buggy software, but it is clear that the current (and technically,
and
      politically, correct) implementation of a negative DST adjustment
for
      Ireland is there to stay.
      As a matter of fact, the distro maintainer can choose to compile
      tzdata to keep buggy software happy ("make DATAFORM=rearguard"),
      which replicates the behaviour of tzdata prior to 2018. Many distros
      seem to be doing that for one reason or another, while some have
passed
      the upstream change down to their users (probably, without knowing).

Anyhow, all the simple minded software, including the MUA
i maintain, used to do something like

   if((t2 = mktime(gmtime(&t))) == (time_t)-1){
      t = 0;
      goto jredo;
   }
   tzdiff = t - t2;
   if((tmp = localtime(&t)) == NULL){
      t = 0;
      goto jredo;
   }

   tzdiff_hour = (int)(tzdiff / 60);
   tzdiff_min = tzdiff_hour % 60;
   tzdiff_hour /= 60;
   if (tmp->tm_isdst > 0)
      tzdiff_hour++;

Note the .tm_isdst plus positive summer time adjustment.
This was overly primitive, and i recognize that POSIX supports the
%z (and %Z) formats for strftime(3), and in general code as below
is used by projects, so doing it right is very expensive but
doable with POSIX as of today.

However, all BSDs and Linux with either of GNU and musl C library
support the .tm_gmtoff (and .tm_zone) members of "struct tm", in
general all users of the public domain (and standardized) IANA TZ
project can bake it in upon their own desire..  With .tm_gmtoff
being available, code gets as simple as
  s64
  time_tzdiff(s64 secsepoch, struct tm const *utcp_or_nil,
        struct tm const *localp_or_nil){
     struct tm tmbuf[2], *tmx;
     time_t t;
     s64 rv;
     UNUSED(utcp_or_nil);

     rv = 0;

     if(localp_or_nil == NIL){
        t = S(time_t,secsepoch);
        while((tmx = localtime(&t)) == NIL){
           if(t == 0)
              goto jleave;
           t = 0;
        }
        tmbuf[0] = *tmx;
        localp_or_nil = &tmbuf[0];
     }

  #ifdef HAVE_TM_GMTOFF
     rv = localp_or_nil->tm_gmtoff;

  #else
     if(utcp_or_nil == NIL){
        t = S(time_t,secsepoch);
        while((tmx = gmtime(&t)) == NIL){
           if(t == 0)
              goto jleave;
           t = 0;
        }
        tmbuf[1] = *tmx;
        utcp_or_nil = &tmbuf[1];
     }

     rv = ((((localp_or_nil->tm_hour - utcp_or_nil->tm_hour) * 60) +
           (localp_or_nil->tm_min - utcp_or_nil->tm_min)) * 60) +
           (localp_or_nil->tm_sec - utcp_or_nil->tm_sec);

     if((t = (localp_or_nil->tm_yday - utcp_or_nil->tm_yday)) != 0){
        s64 const ds = 24 * 60 * 60;

        rv += (t == 1) ? ds : -S(s64,ds);
     }
  #endif

  jleave:
     return rv;
  }
Desired Action: 
Insert at the given location

<code>
 int         tm_gmtoff   Seconds east of UTC
 const char *tm_zone     Timezone abbreviation
</code>

Maybe cross-reference with strftime(3) and note relationship to the %z and
%Z formats.
====================================================================== 

Issue History 
Date Modified    Username       Field                    Change               
====================================================================== 
2021-11-08 22:04 steffen        New Issue                                    
2021-11-08 22:04 steffen        Name                      => steffen         
2021-11-08 22:04 steffen        Section                   => time.h          
2021-11-08 22:04 steffen        Page Number               => 425             
2021-11-08 22:04 steffen        Line Number               => 14451           
======================================================================


  • [1003.1(2016... Austin Group Bug Tracker via austin-group-l at The Open Group
    • [1003.1... Austin Group Bug Tracker via austin-group-l at The Open Group
    • [1003.1... Austin Group Bug Tracker via austin-group-l at The Open Group
    • [1003.1... Austin Group Bug Tracker via austin-group-l at The Open Group
    • [1003.1... Austin Group Bug Tracker via austin-group-l at The Open Group
    • [1003.1... Austin Group Bug Tracker via austin-group-l at The Open Group
    • [1003.1... Austin Group Bug Tracker via austin-group-l at The Open Group
    • [1003.1... Austin Group Bug Tracker via austin-group-l at The Open Group
    • [1003.1... Austin Group Bug Tracker via austin-group-l at The Open Group
    • [1003.1... Austin Group Bug Tracker via austin-group-l at The Open Group
    • [1003.1... Austin Group Bug Tracker via austin-group-l at The Open Group

Reply via email to