Thunarで時刻が不明に
Posted by momokuri on 2007 6月 04 in モブログ
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つの戦略がある。
- あらかじめ静的に考えられる最大のサイズxをとることにする。
- サイズを保存する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"));
}
ページ: 1· 2
This entry was posted by momokuri and filed under モブログ.