MinGW MSYS, MSVCRT, and TZ environment variable

In short, how to get MSWCRT and MinGW MSYS to share the TZ environment variable without conflict? Or how to make both support time zones without conflicts?

Additional Information

In order to have the MSYS date command displaying the correct local time, and also because MSYS itself uses its own C environment instead of MSVCRT, I set the TZ environment variable according to the GNU C library documentation :

export TZ="BRT+3BRST,M10.3.0/0,M2.3.0/0" 

Unfortunately, this conflicts with the Microsoft C runtime specifications , which dictates for the DST name part:

If daylight saving time never works in the area, set TZ without a value for dzn. C Runtime Library adopts United States Daylight Saving Time (DST) rules

Consequently, the mere presence of the DST name in the TZ variable will cause _tzset dependent programs to crash outside of the United States. This is my case with the Bazaar DVCS, where I get the wrong fixing moments, one hour late because MSVCRT assumes that I have already entered the DST period based on the TZ setting. If I leave TZ blank, the MSYS date displays UTC, but MSVCRT (and Bazaar) is working fine. If I set TZ as above, then MSVCRT adds one hour to the commit time, but the MSYS date displays the local time.

Bazaar is affected because it uses Python, which in turn uses MSVCRT on Windows. Although I can remove everything from the DST name, this will result in the loss of the date command in MSYS. I also tried several TZ values. MSYS does not seem to have any additional time zone support than what is described above in the GNU link. In addition, I wanted to avoid the fact that TZ was not installed only when Bazaar was called, or it was installed only when the date command was called, but rather in a more general solution.

Alternative formats and zoneinfo database

There is an alternative format for TZ, the third in the GNU documentation above, but it does not seem to be supported by MSYS, as indicated:

But the POSIX.1 standard only defines the details of the first two formats,

This third format seems to be just the IANA time zone database, which describes a different format for TZ , which does not seem to be supported by MSYS either, as indicated:

To use the database in an advanced POSIX implementation, set the TZ environment variable to the fully qualified location name, for example, TZ="America/New_York" .

Try to do it. I tried to install IANA zoneinfo manually on MSYS without success. I am not sure if these statements are true and their formats are not even recognized by MSYS, or I simply could not correctly install the zoneinfo data files. I could not find the compiled version and could not compile myself, so I just tried the tzdata package from Ubuntu.

Something strange to me is that in the GNU C library documentation above it already comes with a time zone database (it sounds like zoneinfo to me). However, as said, I cannot find any timezone database installed anywhere in MSYS, nor can I find any mingw-get package associated with timezones. I wonder if the developers just removed it from the release. This is what the documentation says:

The GNU C library comes with a large database of time zones for most regions of the world, supported by a community of volunteers and put in the public domain.

So, if I could do zoneinfo or similar alternative work in MSYS, then I could abandon my current approach to installing TZ, as mentioned above. However, I cannot find any good time zone support information in MSYS.

+4
source share
3 answers

I found out that MSYS should actually determine the time zone automatically without TZ. The following error report reports the problem: MSYS cannot process timers in localized Windows .

Meanwhile

The best solution I have found so far until this error is fixed:

  • Create a script wrapper called, for example, runcrt.sh , accessible by the system path and containing:

     #!/bin/bash env -u TZ $(basename "$0").exe " $@ " 
  • Create NTFS symbolic links for this script, one for each MSVCRT program that I plan to run in MSYS, but without the exe extension and to the actual executables in the system path. For example ruby, python, bzr, etc.

  • For performance reasons, the configuration of the TZ cache (export expression dynamically generated dynamically) in /etc/profile.d/timezone.sh during Windows initialization (in fact, we just need to update TZ once a year, namely, how often DST but whatever).

  • Set BASH_ENV to /etc/profile.d/timezone.sh , so not only interactive bash sessions, but shell scripts can also be timezone aware.

Thus, interactively or from a shell script, calls to bzr commit , for example, will get the correct commit date in the code repository, since this command is executed with TZ disabled. Similarly, TZ is set for all other commands, such as date and ls, so they also print the exact local time. I rejected the opposite approach of installing TZ only for MSYS commands and left it blank for anything else, because the undo operation is much faster than export lookups.

MSYS2 as an alternative

MSYS2, however, is independent of this error and correctly defines the time zone. In fact, it has the correct time zone support:

 $ tzset America/Sao_Paulo $ date +"%T, timezone %Z (%z)" 10:18:12, timezone BRT (-0300) $ TZ=America/Los_Angeles date +"%T, timezone %Z (%z)" 06:18:14, timezone PDT (-0700) 
+1
source

A simple solution is to set the Windows environment variable as you expect, then change the variable in the ~ / .profile file for MSYS to what POSIX expects.

+1
source

In your environment there is no problem starting clean Windows without msys. And you have no problem running pure msys when you are not getting access to native Windows applications like Bazaar. This is what I assume from your question.

Special script wrappers unsetting TZ for every Windows command running under msys seem reasonable, and I think you do. I know that this is not the answer that you expected, or the one that you could write yourself, but since there are no other answers, I thought that at least one should be here :) The least evil.

Finally, I imagine 3 levels of TZ settings:

  • Microsoft value set in Windows system settings
  • Msys value set in /etc/profile or msys.bat
  • The value for Microsoft is again in the shells for running Windows commands in Msys, for example:
    #!/bin/bash
    export TZ=; /usr/bin/bazaar " $@ "
    in the file /usr/local/bin/bazaar

I cannot imagine a more general solution. How can the shell know which version of the TZ variable is preferred for a given command?

0
source

Source: https://habr.com/ru/post/1438212/


All Articles