4

要するに、MSVCRT と MinGW MSYS の両方が競合することなく TZ 環境変数を共有する方法を教えてください。または、競合することなく両方のタイムゾーンをサポートする方法は?

さらに詳しい情報

MSYS の date コマンドで正しい現地時間を表示するために、また MSYS 自体が MSVCRT ではなく独自の C ランタイムを使用するため、GNU C ライブラリのドキュメントに従ってTZ 環境変数を設定しました。

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

残念ながら、これは DST 名の部分を規定するMicrosoft C ランタイム仕様と競合します。

地域で夏時間がまったく実施されていない場合は、dzn の値を指定せずに TZ を設定します。C ランタイム ライブラリは、夏時間 (DST) の計算を実装するための米国の規則を想定しています。

したがって、TZ 変数に DST 名が存在するだけで、に依存するプログラム_tzsetが米国外で誤動作する原因になります。これは Bazaar DVCS の場合で、MSVCRT は TZ 設定に基づいて DST 期間に既に入っていると想定しているため、1 時間遅れて間違ったコミット時間を取得しています。TZ を空のままにしておくと、MSYS の日付には UTC 時間が表示されますが、MSVCRT (および Bazaar) は問題なく動作します。上記のように TZ を設定すると、MSVCRT はコミット時間に 1 時間を追加しますが、MSYS の日付には現地時間が表示されます。

Bazaar が影響を受けるのは、Windows で MSVCRT を使用する Python を使用しているためです。DST名からすべてを削除できますが、MSYSの日付コマンドが壊れます。TZ の値もいくつか試しました。MSYS は、上記の GNU リファレンスで説明されている以外のタイムゾーン サポートを欠いているようです。また、Bazaar を呼び出すときだけ TZ を設定しないようにするか、date コマンドを呼び出すときだけ TZ を設定するのではなく、より一般的な解決策にしたいと考えました。

代替フォーマットと zoneinfo データベース

上記の GNU ドキュメントの 3 番目の形式である TZ の代替形式がありますが、次のように MSYS ではサポートされていないようです。

しかし、POSIX.1 標準は、最初の 2 つの形式の詳細のみを指定します。

この 3 番目の形式は、次のように、MSYS でもサポートされていないように思われるTZ の別の形式を記述しているIANA のタイム ゾーン データベースにすぎないようです。

拡張 POSIX 実装でデータベースを使用するには、TZ 環境変数を場所の完全な名前に設定しますTZ="America/New_York"

IANA の zoneinfo を手動で MSYS にインストールしようとしても成功しませんでした。これらの記述が正しく、そのフォーマットが MSYS によって認識されないのか、それとも単に zoneinfo データ ファイルを正しくインストールできなかっただけなのか、私にはわかりません。コンパイルされたバージョンが見つからず、自分でコンパイルすることもできなかったので、Ubuntu の tzdata パッケージを試してみました。

しかし、私にとって奇妙なことは、上記の GNU C ライブラリのドキュメントが、タイムゾーン データベースが既に付属していることを示していることです (私には zoneinfo のように聞こえます)。ただし、前述のように、MSYS のどこにもインストールされているタイムゾーン データベースが見つかりません。また、タイムゾーンに関連する mingw-get パッケージも見つかりません。開発者が単にリリースから削除したのだろうか。ドキュメントには次のように書かれています。

GNU C ライブラリには、世界のほとんどの地域のタイム ゾーン情報の大規模なデータベースが付属しています。このデータベースは、ボランティアのコミュニティによって維持され、パブリック ドメインに置かれています。

つまり、MSYS で zoneinfo または同様の代替作業を行うことができれば、上記のように TZ を設定する現在のアプローチを放棄できます。ただし、MSYS でのタイムゾーン サポートに関する適切な情報は見つかりません。

4

3 に答える 3

1

MSYSは実際にはTZなしでタイムゾーンを自動的に検出する必要があることがわかりました。次のバグレポートは、問題を文書化しています。MSYSは、ローカライズされたWindowsでtimeozonesを処理できません

その間

このバグが修正されない間に私がこれまでに見つけた最良の解決策は次のとおりです。

  1. たとえばruncrt.sh、システムパスから利用可能で、以下を含むという名前のラッパースクリプトを作成します。

    #!/bin/bash
    env -u TZ $(basename "$0").exe "$@"
    
  2. このスクリプトへのNTFSシンボリックリンクを作成します。MSYSで実行する予定のMSVCRTプログラムごとに1つですが、exe拡張子はなく、システムパスの実際の実行可能ファイルの前に作成します。たとえば、ruby、python、bzrなどです。

  3. パフォーマンス上の理由から、TZ(動的に生成されるエクスポートステートメント)の構成を/etc/profile.d/timezone.shWindowsの初期化にキャッシュします(実際には、TZを1年に1回更新する必要があります。これは、DST期間が変更される可能性がありますが、何でもかまいません)。

  4. BASH_ENVを/etc/profile.d/timezone.shに設定すると、インタラクティブなbashセッションだけでなく、シェルスクリプトもタイムゾーンを認識できるようになります。

このように、インタラクティブに、またはシェルスクリプトから、bzr commitたとえば、への呼び出しは、そのコマンドがTZを設定せずに実行されているため、コードリポジトリに正しいコミット日を取得します。同様に、日付やlsなどの他のすべてのコマンドにもTZが設定されているため、正しい現地時間も出力されます。未設定の操作はエクスポートをソーシングするよりもはるかに高速であるため、MSYSコマンドに対してのみTZを設定し、それ以外の場合は空白のままにするという反対のアプローチを廃止しました。

代替としてのMSYS2

ただし、MSYS2はこのバグの影響を受けず、タイムゾーンを正しく認識します。実際、適切なタイムゾーンがサポートされています。

$ 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)
于 2012-10-29T17:21:21.667 に答える
1

簡単な解決策は、Windows 環境変数を期待どおりに設定し、MSYS の ~/.profile ファイル内の変数を POSIX が期待するものに変更することです。

于 2012-10-16T11:53:40.730 に答える
0

お使いの環境では、msys なしで純粋な Windows を実行しても問題はありません。また、Bazaar などのネイティブ Windows アプリにアクセスしない場合は、純粋な msys を実行しても問題はありません。それがあなたの質問から私が推測することです。

msysの下で実行されるすべてのWindowsコマンドの設定を解除する特別なスクリプトラッパーTZは合理的であるように思われ、それがあなたのしていることだと思います。これはあなたが期待した答えでも、自分で書いた答えでもないことはわかっていますが、他に答えがないので、少なくとも1つはここにあるはずだと思いました:)少なくとも悪。

最後に、3 つのレベルの設定を想像しますTZ

  1. Windows システム設定で設定された Microsoft の値
  2. /etc/profileまたはに設定された Msys の値msys.bat
  3. Msys 内で Windows コマンドを実行するためのラッパーでの Microsoft の値
    #!/bin/bash
    export TZ=; /usr/bin/bazaar "$@"
    /usr/local/bin/bazaar

より一般的な解決策を想像することはできません。シェルは、指定されたコマンドでどのバージョンのTZ変数が優先されるかをどのように知ることができますか?

于 2012-10-09T07:39:27.857 に答える