2019/04/25

glibcのstrftime()における2019年5月からの和暦新元号(令和)対応

glibcを使用したOS(GNU/Linuxの大部分)において、strftime()関数はE修飾子を用いることで和暦の元号を用いた年表記が行える。

2019年5月1日に日本の元号が切り替わるが、これを考慮していない従来バージョンのglibcでは2019年5月1日からの日時が与えられたときに “平成31年5月” などのように正確ではない表記になってしまう。

  1. glibcプロジェクトにおける修正の適用状況
  2. ディストリのパッケージによるパッチの先行適用
  3. テストプログラム

glibcプロジェクトにおける修正の適用状況

https://sourceware.org/bugzilla/show_bug.cgi?id=22964

にあるように、Gitリポジトリにおいて新元号発表後の早い段階で新元号に対応させるための修正が2.29系に対して適用されており、過去のバージョン系統(2.27系と2.28系)に対しても適用済みとなっている。各バージョン系統において、この次のリリースからが修正済みのバージョンとなる。将来の2.30以上からのバージョンも修正済みとなる。

ディストリのパッケージによるパッチの先行適用

幾つかのディストリでは、2019年4月(次のglibcのリリースよりも前)の段階で既にパッチが適用されている。

  • Ubuntu: 2.29-0ubuntu2のバージョンにおいてGitリポジトリの修正が提供されており、この中に新元号パッチが含まれている
  • Gentoo: glibc-2.29-r2の時点では追加のパッチ群の中に新元号パッチが含まれている

テストプログラム

下のプログラムを日本語ロケール(ja_JP.UTF-8)上で実行すると

  • 2019年4月30日 23時59分59秒
  • 2019年5月1日 0時0分0秒

の日時が和暦で表示される。

[任意]ファイル名:strftime-reiwa-test.c ライセンス:CC0
/*
 * gcc -O2 -Wall -Wextra strftime-reiwa-test.c -o strftime-reiwa-test
 * clang -O2 -Wall -Wextra strftime-reiwa-test.c -o strftime-reiwa-test
 */

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

int
main ()
{
    char out[128];
    char oldera[16], newera[16];
    struct tm *tm;
    time_t t;

    setlocale (LC_TIME, "ja_JP.UTF-8");

    t = 1556636399;  /* 2019/04/30 23:59:59 */
    tm = localtime (&t);
    strftime (out, sizeof (out), "%EC%Ey年%B%d日 %X", tm);
    strftime (oldera, sizeof (oldera), "%EC", tm);
    printf ("%s\n", out);

    t++;             /* 2019/05/01 00:00:00 */
    tm = localtime (&t);
    strftime (out, sizeof (out), "%EC%Ey年%B%d日 %X", tm);
    strftime (newera, sizeof (newera), "%EC", tm);
    printf ("%s\n", out);

    if (strcmp (oldera, newera) == 0)
    {
        printf ("未対応 (%s -> %s)\n", oldera, newera);
        return EXIT_FAILURE;
    }
    printf ("対応済 (%s -> %s)\n", oldera, newera);

    return EXIT_SUCCESS;
}

Ubuntu 19.04上でテストプログラムを実行すると下のような結果となる。

$ ./strftime-reiwa-test
平成31年4月30日 23時59分59秒
令和01年5月01日 00時00分00秒
対応済 (平成 -> 令和)

古いディストリなど、未対応のglibcでの実行結果は下のようになる。

$ ./strftime-reiwa-test
平成31年4月30日 23時59分59秒
平成31年5月01日 00時00分00秒
未対応 (平成 -> 平成)

関連URL: