外部プログラム (制御できない) によって記録されたデータ ファイルを解析するアプリケーションを C で作成しています。バイナリ データを格納します。その 1 つのフィールドは、標準 UNIX の「エポック」形式 (UTC の 1970 年 1 月 1 日からの秒数) の時間です。
もう 1 つのフィールドはタイムゾーンで、UTC からの秒単位のオフセットとして保存されます。
いいですね、記録されたタイムゾーンでその情報を表す日付/時刻文字列を作成するために必要なものはすべて揃っていますよね? うーん...そうではないようです、および/またはそれを行う方法がわかりません。
私はかなり単純なテストケースに物事を煮詰めました:
#include <stdio.h>
#include <time.h>
int main(void)
{
time_t t;
struct tm *tm;
char buf[BUFSIZ];
int offset = 4980; /* slightly bizarre, just to test this - an hour
* and 23 minutes ahead of UTC */
t = time(NULL);
tm = localtime(&t);
strftime(buf, BUFSIZ, "%FT%T%z", tm);
printf("before: %s\n", buf);
/* since we're not telling localtime anything different,
* compensate here (by subtracting applied offset, and adding
* desired one): */
t += offset - tm->tm_gmtoff;
tm = localtime(&t);
tm->tm_zone = "XYZ"; // not used -- but it was in an earlier version
tm->tm_gmtoff = offset;
// on macos, I used to also have %+, which referenced tm_zone
strftime(buf, BUFSIZ, "%FT%T%z", tm);
printf("after: %s\n", buf);
return 0;
}
これを MacOS X 10.6 で実行すると、次のようになります。
before: 2011-02-23T00:53:04-0800
after: 2011-02-23T10:16:04-0800
私が期待する(そして実際にLinuxボックスで得られる)のは次のとおりです。
before: 2011-02-23T00:53:04-0800
after: 2011-02-23T10:16:04+0123
TZ
環境変数を変更する必要がありますか (おそらく を呼び出しますtzset
)? データ構造を操作して正しいものを取得する方法があるはずですが、上記は確かに機能していません (とにかく MacOS X 10.6 では -- Linux ではうまく機能します)。
回避策として、フォーマット文字列から %z を削除して、その部分を自分で作成できると思います。
ただし、理想的には、 my の変更struct tm
、または使用できる他の関数呼び出し (strftime のように、追加のパラメーターまたは何か、または代わりに localtime の代替形式を使用) のいずれかが必要です。物事を正しく行う。
Linux は動作しているように見えるので (それでも、上記の解決策は理想的ではありません。なぜなら、私は自分のtime_t
値をstruct tm
ごまかしているからです。 MacOSに対するバグとして?
あるいは、サードパーティ (GNU 関係者の何か、私が想像している) ライブラリが必要になったとしても、呼び出すことができるライブラリ ルーチンの別のセットはありますか? ObjC または C++ のオプションを検討しますが、私は C のままにしたいと思います。