5

私は C に不慣れです。C を練習して時間を隠して tm を前後に構造化します。私はいくつかの違いに気付きました。私が間違ったことをアドバイスしてください。

#include <string.h>
#include <stdio.h>
#include <time.h>

/* 
test different format string to strptime
" %A, %b %d, %X %z %Y "
" %A, %b %d, %X %Z %Y "
*/
int main(int argc,char *argv[])
{

   char date[] = "6 Mar 2001 12:33:45";
   char fmt[80];
   struct tm tm;

   if (argc==1) return 0;
   strcpy(fmt,argv[1]);
   memset(&tm, 0, sizeof(struct tm));
   if (strptime(date,"%d %b %Y %H:%M:%S",&tm)==NULL) printf("error\n");
   char buf[128];
   strftime(buf, sizeof(buf), fmt, &tm);
   printf("%s\n", buf);
   printf("%d\n", tm.tm_isdst);
   if (strptime(buf,fmt,&tm)==NULL) printf("error\n");
   else {
   printf("year: %d; month: %d; day: %d;\n",
         tm.tm_year, tm.tm_mon, tm.tm_mday);
   printf("hour: %d; minute: %d; second: %d\n",
         tm.tm_hour, tm.tm_min, tm.tm_sec);
   printf("week day: %d; year day: %d\n", tm.tm_wday, tm.tm_yday);
   }
   return 0;
}

" %A, %b %d, %X %z %Y " を変換形式の引数として使用すると、コードは次のような結果を提供します。

 ~/user$ ./test_time " %A, %b %d, %X %z %Y "
 Tuesday, Mar 06, 12:33:45 +0000 2001 
 0
 year: 101; month: 2; day: 6;
 hour: 12; minute: 33; second: 45
 week day: 2; year day: 64

引数を " %A, %b %d, %X %Z %Y " に変更すると、コードは strftime によって生成された時間文字列をまったく同じ形式で解析できません。

 ~/user$ ./test_time " %A, %b %d, %X %Z %Y "
  Tuesday, Mar 06, 12:33:45 EET 2001 
 0
 error

strptime がタイムゾーン名を正しく解析できるようにするために何かを見逃していましたか?

前もって感謝します、

アルバート

4

1 に答える 1

10

あなたがしていることがうまくいくかどうかはわかりません。githubのglibc ソース コードには、この問題について次のように書かれています。

case 'Z':
    /* XXX How to handle this? */
    break

続いて、小文字のもののもう少し「肉付きの良い」処理が続きます'z':-)

したがって、ここで発生している可能性が最も高いのは、文字列ポインターがEETフォーマット文字列が のときにを超えて進まない%Zため、 を処理しようとすると%Y、当然のことながら、それEETは有効な年ではないと文句を言うことです。これは、コードが実際に入力文字列ポインターを進める単純なケースによって確認"%%"れます。rp

case '%':
    /* Match the `%' character itself.  */
    match_char ('%', *rp++);
    break;

Linux のマニュアル ページには、拡張機能についても記載されています (そのうちの'Z'1 つです)。

対称性の理由から、glibc は strftime(3) と同じフォーマット文字を strptime() でサポートしようとします。(ほとんどの場合、対応するフィールドは解析されますが、tm のフィールドは変更されません。)

さらに、GNU ドキュメントの状態 (イタリック体):

%Z:タイムゾーン名。注: 現在、これは完全には実装されていません。フォーマットは認識され、入力は消費されますが、tm のフィールドは設定されません。

Zしたがって、私は実際にはこれをバグと考えていますが、ドキュメントを変更して、タイプのタイムゾーンを処理できるふりをやめることで簡単に修正できます。

関連するバグが bugzilla に見つからないので、glibc でバグを報告しました。こちらで追跡できます


補遺: 前の段落のバグ レポート リンクとglibc 2.19 リリース通知に従って、コードをドキュメントに合わせるために提案した変更が加えられました。うまくいけば、バグが含まれていないか、コードが 5 行しかないことを考えると、かなりばかげているように見えます。

于 2012-11-25T22:45:05.513 に答える