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] 一昨日の話題にも通じます。
[補足]
strftime は when_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
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] 一昨日の話題にも通じます。
[補足]
strftime は when_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
この記事へのコメント
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で割り切れるかどうかの場合分けが発生し、簡単ではなくなります。