Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2015-11

Timezones

6 messages · 4 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Zachary Vance

I'm reporting a bug the Debian reproducibility team came across (in 2.6.4-1), trying to make Pascal builds reproducible. The end goal is to see UTC timestamped output of ppudump.

My understanding of the current behavior is that the timezone file is chosen something like this:

TIMEZONE_FILE = [CONTENT of /etc/timezone if it exists]:/etc/localtime:/usr/lib/zoneinfo/localtime[:/usr/share/zoneinfo if BSD]:/var/db/timezone/localtime:localtime If TIMEZONE_FILE doesn't start with / (is a relative path), prepend (${TZDIR} or /usr/share/zoneinfo)

This means that if /etc/timezone or /etc/localtime exist, there is no way to specify that UTC should be used.

---

The desired behavior probably be to respect the TZ environment variable, which is currently ignored, so the new list would be:

TIMEZONE_FILE = ${TZ}:[CONTENT of /etc/timezone if it exists]:/etc/localtime:/usr/lib/zoneinfo/localtime[:/usr/share/zoneinfo if BSD]:/var/db/timezone/localtime:localtime If TIMEZONE_FILE doesn't start with / (is a relative path), prepend (${TZDIR} or /usr/share/zoneinfo)

Additionally, POSIX says that if TZ is set but invalid or empty, it should default to UTC, not to localtime.

Reply by email

Michael Van Canneyt
to Zachary Vance
Zachary Vance wrote 17 lines
I'm reporting a bug the Debian reproducibility team came across (in 2.6.4-1), trying to make Pascal builds reproducible. The end goal is to see UTC timestamped output of ppudump. My understanding of the current behavior is that the timezone file is chosen something like this: TIMEZONE_FILE = [CONTENT of /etc/timezone if it exists]:/etc/localtime:/usr/lib/zoneinfo/localtime[:/usr/share/zoneinfo if BSD]:/var/db/timezone/localtime:localtime If TIMEZONE_FILE doesn't start with / (is a relative path), prepend (${TZDIR} or /usr/share/zoneinfo) This means that if /etc/timezone or /etc/localtime exist, there is no way to specify that UTC should be used. --- The desired behavior probably be to respect the TZ environment variable, which is currently ignored, so the new list would be: TIMEZONE_FILE = ${TZ}:[CONTENT of /etc/timezone if it exists]:/etc/localtime:/usr/lib/zoneinfo/localtime[:/usr/share/zoneinfo if BSD]:/var/db/timezone/localtime:localtime If TIMEZONE_FILE doesn't start with / (is a relative path), prepend (${TZDIR} or /usr/share/zoneinfo) Additionally, POSIX says that if TZ is set but invalid or empty, it should default to UTC, not to localtime.

Observing the contents of the TZ variable is of course an option, that should not be a problem. But the default to localtime will most likely not be changed for 2 reasons a) compatibility with Delphi.
b) backwards compatibility.
FPC does not pretend to be POSIX.

Looking at
http://www.gnu.org/software/libc/manual/html_node/TZ-Variable.html

I have the following code to determine the name of the timezone file based on the contents of TZ:

fn:=fpgetenv('TZ');
if (fn'') then
   if (fn[1]=':') then  // :filename
     begin
     delete(fn,1,1); // Strip :
     if (fn'') then
       begin
       if (fn[1]'/') then // not absolute
         Exit('/usr/share/zoneinfo/'+fn)
       Exit(fn);  // absolute
       end;
     end;

Would you say this is correct ?

Michael.

Reply by email

Zachary Vance
to Michael Van Canneyt

Oops. Re-sending this as I apparently replied privately to Michael. Sorry for the duplicate email, Michael.

Michael Van Canneyt wrote 27 lines
On Sat, 14 Nov 2015, Zachary Vance wrote: > I'm reporting a bug the Debian reproducibility team came across (in 2.6.4-1), trying to make Pascal builds reproducible. The end goal is to see UTC timestamped output of ppudump. > > My understanding of the current behavior is that the timezone file is chosen something like this: > > TIMEZONE_FILE = [CONTENT of /etc/timezone if it exists]:/etc/localtime:/usr/lib/zoneinfo/localtime[:/usr/share/zoneinfo if BSD]:/var/db/timezone/localtime:localtime > If TIMEZONE_FILE doesn't start with / (is a relative path), prepend (${TZDIR} or /usr/share/zoneinfo) > > This means that if /etc/timezone or /etc/localtime exist, there is no way to specify that UTC should be used. > > --- > > The desired behavior probably be to respect the TZ environment variable, which is currently ignored, so the new list would be: > > TIMEZONE_FILE = ${TZ}:[CONTENT of /etc/timezone if it exists]:/etc/localtime:/usr/lib/zoneinfo/localtime[:/usr/share/zoneinfo if BSD]:/var/db/timezone/localtime:localtime > If TIMEZONE_FILE doesn't start with / (is a relative path), prepend (${TZDIR} or /usr/share/zoneinfo) > > Additionally, POSIX says that if TZ is set but invalid or empty, it should default to UTC, not to localtime. Observing the contents of the TZ variable is of course an option, that should not be a problem. But the default to localtime will most likely not be changed for 2 reasons a) compatibility with Delphi. b) backwards compatibility. FPC does not pretend to be POSIX.

I'm not suggesting changing behavior for all methods to evaluate the timezone, only specifically if the TZ environment variable is set and empty/invalid. That said, either fix would solve Debian Reproducible Builds' issue.

Show quoted text 22 lines
Looking at http://www.gnu.org/software/libc/manual/html_node/TZ-Variable.html I have the following code to determine the name of the timezone file based on the contents of TZ: fn:=fpgetenv('TZ'); if (fn'') then if (fn[1]=':') then // :filename begin delete(fn,1,1); // Strip : if (fn'') then begin if (fn[1]'/') then // not absolute Exit('/usr/share/zoneinfo/'+fn) Exit(fn); // absolute end; end; Would you say this is correct ? Michael.

Thanks for investigating this, Michael.

I only learnt about the TZ variable investigating this bug and don't know Pascal. That said, this seems to match the page you linked. I'm unclear if the content of literal timezones and timezone files are the same--my local ones on my computer look different, so I'd definitely test to make sure the example strings on the linked page work. If you need someone to test timezone parsing methods because you're not on Linux, try the debian-reproducible IRC. (I'd offer but I don't know fpc at all). You might want to replace '/usr/share/zoneinfo/' by the value of TZDIR if it's defined, for consistency with the rest of fpc?

If you want to try our original failing test case, which is from Arch Linux but should run on any Linux system:
1. Delete /etc/timezone
2. Symlink /etc/localtime to your timezone file (not UTC, please)
3. Run TZ='' ppadump ... [If you're not modifying things, I guess it would be TZ='UTC'] Output currently uses the content of /etc/localtime, but should be in UTC.

Reply by email

Mark Morgan Lloyd
to Zachary Vance
Zachary Vance wrote 14 lines
>> Additionally, POSIX says that if TZ is set but invalid or empty, it should default to UTC, not to localtime. > Observing the contents of the TZ variable is of course an option, that should not be a problem. > But the default to localtime will most likely not be changed for 2 reasons > a) compatibility with Delphi. > b) backwards compatibility. > FPC does not pretend to be POSIX. I only learnt about the TZ variable investigating this bug and don't know Pascal. That said, this seems to match the page you linked. I'm unclear if the content of literal timezones and timezone files are the same--my local ones on my computer look different, so I'd definitely test to make sure the example strings on the linked page work. If you need someone to test timezone parsing methods because you're not on Linux, try the debian-reproducible IRC. (I'd offer but I don't know fpc at all). You might want to replace '/usr/share/zoneinfo/' by the value of TZDIR if it's defined, for consistency with the rest of fpc? If you want to try our original failing test case, which is from Arch Linux but should run on any Linux system: 1. Delete /etc/timezone 2. Symlink /etc/localtime to your timezone file (not UTC, please) 3. Run TZ='' ppadump ... [If you're not modifying things, I guess it would be TZ='UTC'] Output currently uses the content of /etc/localtime, but should be in UTC.

Obeying TZ sounds reasonable to me, subject to considering the Windows situation (some unix-style programs on DOS/Windows honour it).

I remember previous debate on getting a guaranteed UTC timestamp, and this might be a useful way forwards provided obviously that the underlying OS plays ball.

Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues]

Reply by email

Levente Polyak
to Zachary Vance: Oops. Re-sending this as I apparently replied privately to Michael. Sorry for the…
Zachary Vance wrote 66 lines
Oops. Re-sending this as I apparently replied privately to Michael. Sorry for the duplicate email, Michael. On 11/15/2015 03:00 AM, Michael Van Canneyt wrote: > > > On Sat, 14 Nov 2015, Zachary Vance wrote: > >> I'm reporting a bug the Debian reproducibility team came across (in 2.6.4-1), trying to make Pascal builds reproducible. The end goal is to see UTC timestamped output of ppudump. >> >> My understanding of the current behavior is that the timezone file is chosen something like this: >> >> TIMEZONE_FILE = [CONTENT of /etc/timezone if it exists]:/etc/localtime:/usr/lib/zoneinfo/localtime[:/usr/share/zoneinfo if BSD]:/var/db/timezone/localtime:localtime >> If TIMEZONE_FILE doesn't start with / (is a relative path), prepend (${TZDIR} or /usr/share/zoneinfo) >> >> This means that if /etc/timezone or /etc/localtime exist, there is no way to specify that UTC should be used. >> >> --- >> >> The desired behavior probably be to respect the TZ environment variable, which is currently ignored, so the new list would be: >> >> TIMEZONE_FILE = ${TZ}:[CONTENT of /etc/timezone if it exists]:/etc/localtime:/usr/lib/zoneinfo/localtime[:/usr/share/zoneinfo if BSD]:/var/db/timezone/localtime:localtime >> If TIMEZONE_FILE doesn't start with / (is a relative path), prepend (${TZDIR} or /usr/share/zoneinfo) >> >> Additionally, POSIX says that if TZ is set but invalid or empty, it should default to UTC, not to localtime. > > Observing the contents of the TZ variable is of course an option, that should not be a problem. > But the default to localtime will most likely not be changed for 2 reasons > a) compatibility with Delphi. > b) backwards compatibility. > FPC does not pretend to be POSIX. I'm not suggesting changing behavior for all methods to evaluate the timezone, only specifically if the TZ environment variable is set and empty/invalid. That said, either fix would solve Debian Reproducible Builds' issue. > > Looking at > http://www.gnu.org/software/libc/manual/html_node/TZ-Variable.html > > I have the following code to determine the name of the timezone file based on the contents of TZ: > > fn:=fpgetenv('TZ'); > if (fn'') then > if (fn[1]=':') then // :filename > begin > delete(fn,1,1); // Strip : > if (fn'') then > begin > if (fn[1]'/') then // not absolute > Exit('/usr/share/zoneinfo/'+fn) > Exit(fn); // absolute > end; > end; > > Would you say this is correct ? > > Michael. Thanks for investigating this, Michael. I only learnt about the TZ variable investigating this bug and don't know Pascal. That said, this seems to match the page you linked. I'm unclear if the content of literal timezones and timezone files are the same--my local ones on my computer look different, so I'd definitely test to make sure the example strings on the linked page work. If you need someone to test timezone parsing methods because you're not on Linux, try the debian-reproducible IRC. (I'd offer but I don't know fpc at all). You might want to replace '/usr/share/zoneinfo/' by the value of TZDIR if it's defined, for consistency with the rest of fpc? If you want to try our original failing test case, which is from Arch Linux but should run on any Linux system: 1. Delete /etc/timezone 2. Symlink /etc/localtime to your timezone file (not UTC, please) 3. Run TZ='' ppadump ... [If you're not modifying things, I guess it would be TZ='UTC'] Output currently uses the content of /etc/localtime, but should be in UTC.

Hey all, Hey Michael,

I hope not to generate noise, but just as a confirmation and summary I think my reply may hopefully be useful:

The offered code looks correct as someone can set TZ to any value that exists in /usr/share/zoneinfo/ (in our case we could assign UTC to the TZ env var)

However as its not part of the diff I wanted to remind that the above is fine from out requirements as long as it supersedes/overrides any other possibly set value (either via /etc/timezone, /etc/localtime or any other possibility) so we can override anything to UTC just by setting an environment var.

Thanks a lot!

cheers,
Levente

Reply by email

Michael Van Canneyt
to Levente Polyak
Levente Polyak wrote 10 lines
Hey all, Hey Michael, I hope not to generate noise, but just as a confirmation and summary I think my reply may hopefully be useful: The offered code looks correct as someone can set TZ to any value that exists in /usr/share/zoneinfo/ (in our case we could assign UTC to the TZ env var)

I have committed a slightly modified (observing both TZ and TZDIR) patch in revision 32369.

Michael.

Reply by email