std::chronoのformatについて
2024年9月21日現在のcpprefjpのstd::chronoのformatについての記述においてこのように書かれている
%EC では "令和" (元号)
しかし、VS2022(Version 17.11.2)において以下の出力は「20」で2024を100で割った値になっている。
std::locale loc{ "ja_JP" };
std::cout << std::format(loc, "{:L%EC}\n", now); // 20
The modified command %EC writes the locale's alternative representation of the century.
もちろん和暦に関して書いているわけもなく・・・
たぶんこれがドラフトの文章?
「例」の列が独自で足されていて、そこがVS2022の出力結果と乖離している。
というか%EC
が「representation of the century」というのであれば英語ロケールだと20
じゃなくて21
を返すべきじゃない?
%EC
が英語ロケールだと「21(世紀)」で(理想の)日本語ロケールだと「令和6年」になるの、粒度がかみ合ってないけどいいのか?
令和についてはたしか、strftimeで動作確認して書いた気がしますね
GCC, Clang, MSVCでstrftimeの動作確認を改めてやったら20と出力されました。。。私が書きましたが「令和」は出所不明ですね…
ページの処理系の確認が全て❌️になっていたので動作確認していないものかと思っていました。
各ロケールで何が出力されるべきなのか分からないので難しいですね…
ひとまず世紀のロケール表現はどこも実装していないので、元号の例は削除しておきました。
また、世紀の例も21 → 20に直しました。
調査ありがとうございますー
era
と書かれてる!
// %EC Locale's alternative preresentation of the century (era name).
それなら令和と書かれていてもおかしくない
if (__mod == 'E')
{
// TODO: %EC, %Ey or %EY
// return __out;
}
って%EC
とかがTODOにされとる!
GCCだとE
がつかない表記と同じ表示になっているのかな。
世界の誰もこのあたりの紀年法表記について気にしてない説。
こんな紀年法表記を気にしている人がいたのね。
if (__mod) [[unlikely]]
{
struct tm __tm{};
__tm.tm_year = (int)__y - 1900;
return _M_locale_fmt(std::move(__out), _M_locale(__ctx), __tm,
__conv, __mod);
}
// ...
// Use the formatting locale's std::time_put facet to produce
// a locale-specific representation.
template<typename _Iter>
_Iter
_M_locale_fmt(_Iter __out, const locale& __loc, const struct tm& __tm,
char __fmt, char __mod) const
{
basic_ostringstream<_CharT> __os;
const auto& __tp = use_facet<time_put<_CharT>>(__loc);
__tp.put(__os, __os, _S_space, &__tm, __fmt, __mod);
if (__os)
__out = __format::__write(std::move(__out), __os.view());
return __out;
}
- (std::)use_facetってなに?
- 各種言語でどう表すかを統一的にまとめたもの?
- 日付にかかわらず数字やお金などのカテゴリがありそう
- 例えばtolower()のロケール版は
std::use_facet<std::ctype<charT>>(loc).tolower(c)
を返すらしい
- 例えばtolower()のロケール版は
話を最初に戻すと%EC
はVS2022では未実装の可能性があるので何とも言えない。(英語ロケールでは21を返すべきではないかという気はするが)
ただ、cpprefjpの%C
では「100で切り下げ除算した年 (世紀)」として例が「21」と表記されているが%C
自体は世紀を表すものではなく、単に100の切り下げ除算なので「20」と表記するのが正しそう。
自分の解釈があっているか不安だったのでC++20 ライブラリ機能 1の%C
について確認してみたら「100 で切り上げた年(2 桁の世紀)」で出力例が「20」で???となった。
ここは切り捨てのような気がするし、切り上げなら出力例は「21」になるはず。