« Ruby on RailsでTime.now.to_dateで不具合ejabberdでiRCフロントエンドを使う »

Thunarで時刻が不明に

2007/06/04

  20:40:00 by , Categories: モブログ

Link: http://thunar.xfce.org/index.html

Thunarは軽くて使いやすいファイルマネージャ。 でも、日本語環境特にUTF-8環境で、ファイルの時刻が[不明]と表示される。 なぜなら、g_date_strftime()に与えるバッファ長が短いからではないかな。 問題は、以下の部分 date_string = g_new (gchar, 16); if (g_date_strftime (date_string, 16, date_format, &dfile) != 0) だいたい、生の数字がソース上にあるのがいけない。 typedef char gchar であるので、バイト数と見るのがよい。 LANG=C, POSIX, en環境やヨーロッパ語の環境では、16文字もあれば そこそこ大丈夫そうに見える。 1---5----0----56 2007-05-31, 31 December,2007 これが、EUCの日本語環境では 2007年12月31日:14byte UTF-8になると: 17byte となる。もし、代わったロケールを使っていて、 西暦二〇〇七年一十二月三十一日 という変換をするロケールが定義されていると、 UTF-8で45byteとなる。 ここで、どうやって合理的に確保するバッファのサイズを 求めるか、ということであるが、次の2つの戦略がある。
  1. あらかじめ静的に考えられる最大のサイズxをとることにする。
  2. サイズを保存するstatic変数lを用意し、g_date_strftimeが失敗した場合に、サイズを1word程度増加させておく。ただし、ある最大サイズxを超えては確保しない。いくつかのファイルでUnknownになってしまうかもしれないが、リフレッシュすれば問題なくなり、その後は安定する。
前者の戦略も後者の戦略もうまく動く。
/** * thunar_util_humanize_file_time: * @file_time : a #ThunarVfsFileTime. * * Returns a human readable date representation of the specified * @file_time. The caller is responsible to free the returned * string using g_free() when no longer needed. * * Return value: a human readable date representation of @file_time. **/ gchar* thunar_util_humanize_file_time (ThunarVfsFileTime file_time) { const gchar *date_format; gchar *date_string; GDate dfile; GDate dnow; gint diff; const gsize dslen = 64; /* static gsize dslen = 16; */ /* 2つめの方法の時 */ /* check if the file_time is invalid */ if (G_LIKELY (file_time != 0)) { /* setup the GDate's */ #if GLIB_CHECK_VERSION(2,10,0) g_date_set_time_t (&dfile, file_time); g_date_set_time_t (&dnow, time (NULL)); #else g_date_set_time (&dfile, (GTime) file_time); g_date_set_time (&dnow, (GTime) time (NULL)); #endif /* determine the difference in days */ diff = g_date_get_julian (&dnow) - g_date_get_julian (&dfile); if (diff == 0) { /* TRANSLATORS: file was modified less than one day ago */ return g_strdup (_("Today")); } else if (diff == 1) { /* TRANSLATORS: file was modified less than two days ago */ return g_strdup (_("Yesterday")); } else { if (diff > 1 && diff < 7) date_format = "%A"; /* Days from last week */ else date_format = "%x"; /* Any other date */ /* format the date string accordingly */ date_string = g_new (gchar, dslen); if (g_date_strftime (date_string, dslen, date_format, &dfile) != 0) return date_string; /* dslen = (dslen > 128)? dslen: dslen+4; */ /* 2つめの方法 */ g_free (date_string); } } /* the file_time is invalid */ return g_strdup (_("Unknown")); }

Pages: 1·

No feedback yet


Form is loading...