strftime の %U 書式

>[C言語] 時間を扱う
https://qiita.com/edo_m18/items/364ffc6713b81c4d1c87

上記でも紹介されていますが C言語で日付・時刻を扱う構造体
struct tm での暦月の扱いは、

>int tm_mon; /* 月 [0-11] 0から始まることに注意 */

です。

この種のオープンソースの実装からは英語圏の慣習を垣間見ることが
できますが tm_mon が 1~12 ではなく 0~11 なのは興味深い。

もちろん 9/11 が2001年のアメリカ同時多発テロ事件を指すように
September が9月であることは当然ですが、おそらく日本語よりは
暦月を数ではなく月名で呼ぶ[1][2]ことが多いのでしょう。

そこで気になるのが、昨日紹介した同じく C言語の strftime 関数。

| [2] 世の中には他にに strftime の %U 書式のようなものもあります。
 …
>年の初めからの通算の週番号 (10 進数表記) (00-53)。
>その年の最初の日曜日を、第1週の始まりとして計算する。

1月1日が日曜日であればその年は第1週から始まりますが、そうで
なければその年は第0週から始まるわけです[3]

一方、この strftime 関数には、

・週は日曜に始まり土曜に終わる
・グレゴリオ暦の1月1日を含む週を当年の第1週とする

という週番号を扱う書式(以下※と表記)は定義されていません。
1月1日が日曜日以外の場合、※方式と%U 書式では番号が1ズレます。

このことは慣習的に英語圏で※方式が使われていないことを意味する
のでしょうか?慣習的に使われているのであれば、そのための書式が
定義されているはずのようにも思われます。

[1] 「明治改暦以前は暦月を数ではなく和名で呼ぶ方が普通だった」
  という誤解が一部にあるようですが、江戸時代の頒暦でも暦月は
  正月以外は数字で表されるのが普通でした。
[2] C言語では配列が Zero Origin [3]なので、
   char *MonthName[12];
  のような宣言をして、
   MonthName[tm_mon]
  のように使うことを想定しているのでしょう。
[3] 一昨日の話題にも通じます。

[補足]

strftimewhen_exe Gem の CalDateクラスでも使用できます。

require 'when_exe'
include When

date = tm_pos(2021, 1, 1)

p date.class
#=> When::TM::CalDate

10.times do
 p [date, date.strftime('%a %U')] #=>
# [2021-01-01, Fri 00]
# [2021-01-02, Sat 00]
# [2021-01-03, Sun 01]
# …
# [2021-01-09, Sat 01]
# [2021-01-10, Sun 02]
 date += P1D
end

[関連記事] 2014-09-29 12時間制とstrftime

この記事へのコメント

五角塲
2021年06月01日 00:48
一昨日の「0は自然数か」もそうですが、
0始まりのほうが簡単になる場合があります。

4月始まりの会社で数百万件の支出データが入った台帳を会計年度別に集計したい。
ある会社の経理をしていたときに、こんな作業がしょっちゅうありました。
取引日がy年m月、切り捨て関数をfloor( )とすると、会計年度FYは
FY = floor( { 12 * y + ( m - 4 ) } / 12 )。
これは年度初4月を0、年度末3月を11としていることに相当します。
4月を1、3月を12としたら、上の{12*y + (m-4)}が12で割り切れるかどうかの場合分けが発生し、簡単ではなくなります。

この記事へのトラックバック