看到 william 再次針對華文世界 RSS 的亂象,提出呼籲,希望能夠使用正確的時間格式:《MSN 一起 PO(兼談「華文世界 RSS 亂象」)》,從列出來的格式差異,幾乎可以 99% 確定,是沒有注意到設定 locale 而產生之效應的緣故:

MSN 一起 PO(RSS 例子)
錯誤的日期格式:星期二, 01 四月 2008 02:59:35 GMT
正確的日期格式:Tue, 01 Apr 2007 02:59:35 GMT

其中,「Tue」變成了「星期二」,「Apr」變成了「四月」。這個日期格式,多半是透過 strftime() 之類的函式,利用這個 %a, %d %b %Y %H:%M:%S GMT 格式字串產生:

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

int main()
{
    time_t now;
    char buf[1024];

    setlocale(LC_ALL, ""); // set to OS-specified locale

    time(&now);
    strftime(buf, sizeof(buf), "%a, %d %b %Y %H:%M:%S GMT", gmtime(&now));
    printf("%s\n", buf);

    return 0;
}

依據 MSDN,%a 與 %b 分別會被代換為 abbreviated weekday name 與 abbreviated month name,而很不幸地,這兩個縮名,會受到 locale 設定的影響。因此,上面的程式,在 en-us 裡,會印出 Tue, 01 Apr 2008 05:56:53 GMT,但在中文 Windows 裡,則會印出 星期二, 01 四月 2008 05:56:53 GMT[1]

會產生這樣的 bug,其根源當然是因為 C 的 locale 是 global locale,牽一髮而動全身。不過因為 C locale 的影響深遠,所以要解決這個 bug,必須針對這個時間格式,打造一個不受 locale 影響的 strftime() 才行。


  1. 在 FreeBSD 7 zh_TW.UTF-8 之下,則是印出 二, 01  4 2008 05:56:53 GMT,也沒有多好。