Collin Funk <[email protected]> writes:

Hi Collin,

> Hi Benson,
>
> Benson Muite <[email protected]> writes:
>
>> The date function has an option to output dates in rfc3339 format.  A
>> successor to this format is rfc9557[0].  RFC 9557 adds additional
>> options to use information from tzdata in the output, in particular
>> dates of the form:
>>
>> 2006-08-14T02:34:56-06:00[America/Guatemala]
>>
>> Would there be willingness to consider a patch that adds this
>> functionality?  In additon to changes in date.c changes would be needed
>> in GNUlib as this provides the main functionality and allows for
>> portability through strftime.c can contribute necessary changes to
>> GNULib as well.
>>
>> There has been a little related discussion at:
>> https://lists.gnu.org/archive/html/bug-gnulib/2024-08/msg00007.html
>>
>> GNU/Linux systems using systemd provide timezone information in the
>> form [Region/City], through timedatectl but this is not in rfc9557
>> form.  One may want this functionality on other systems, for example
>> using OpenRC, so having it in the date command would be desirable.
>>
>> Benson
>>
>> [0] https://datatracker.ietf.org/doc/html/rfc9557
>
> Thanks for the detailed message and offering to implement this.
>
> The main question that I have is how would you pick a time zone name
> given the UTC offset?
>
> For example, I am from California so I use Pacific Time:
>
>     $ date --iso-8601=minutes
>     2026-03-16T11:06-07:00
>
> If we were to implement 'date --rfc-9557', how would you chose between
> the following outputs?
>
>     $ date --rfc-9557=minutes
>     2026-03-16T11:06-07:00[America/Los_Angeles]
>
>     $ date --rfc-9557=minutes
>     2026-03-16T11:06-07:00[America/Tijuana]
>

This would depend on the operating system. One could read the TZ
variable. The icu library has some code to determine this for
different operating systems:
https://github.com/unicode-org/icu/blob/main/icu4c/source/common/putil.cpp
though it does not quite work for me on Fedora 43 and expect would not
want it as a dependency of gnulib or coreutils, but some of the
strategies used for different operating systems could be recoded.

```c++
#include <iostream>
#include <string.h>
#include <locale.h>
#include "unicode/coll.h"
#include "unicode/datefmt.h"
#include "unicode/timezone.h"
#include "unicode/urename.h"
#include "unicode/ustdio.h"
#include "unicode/utypes.h"

using namespace icu;
using namespace std; 

int main()
{
 UnicodeString curTZNameEn;

 // Detect host time zone
 TimeZone *tzWest = TimeZone::detectHostTimeZone();

// Print out the Time Zone Name, GMT offset etc.
 curTZNameEn = tzWest->getDisplayName(Locale::getEnglish(),curTZNameEn);
 u_printf("%s\n","Current Time Zone Name in English:");
 u_printf("%S\n", curTZNameEn.getTerminatedBuffer());

 return 0;
}
```

PyICU does work though

```python
from icu import ICUtzinfo
defaultTZ = ICUtzinfo.getDefault()
datetime.now(defaultTZ)
datetime.datetime(2026, 3, 17, 10, 55, 1, 410649, tzinfo=<ICUtzinfo: 
Africa/Nairobi>)
```

If systemd is used one can use `readfile /etc/localtime`
example code below which works for me on Fedora 43

```c
#include <stdio.h>
#include <time.h>
#include <unistd.h>

int main() {
  char buf[1024];
  ssize_t len = readlink("/etc/localtime", buf, 1023);
  int zone0 = 0;
  int zone1 = 0;
  int i;
  if(len != -1) {
    buf[len]='\0';
  } else {
    return 1;
  }
  for(i=0;i<len;i++) {
    if( *(buf + i) == '/' ) {
      zone0 = zone1;
      zone1 = i;
    }
  }     
  printf("tzname: %s\n",buf+zone0+1);
  return 0;
}
```
> Collin
Benson

Reply via email to