Skip to content

Instantly share code, notes, and snippets.

@nipotan
Last active January 17, 2019 03:51
Show Gist options
  • Save nipotan/5abaf8995ce8fcaffdef35d84eab420a to your computer and use it in GitHub Desktop.
Save nipotan/5abaf8995ce8fcaffdef35d84eab420a to your computer and use it in GitHub Desktop.
diff -urN Calendar-Japanese-Holiday-0.04/lib/Calendar/Japanese/Holiday.pm Calendar-Japanese-Holiday-0.05/lib/Calendar/Japanese/Holiday.pm
--- Calendar-Japanese-Holiday-0.04/lib/Calendar/Japanese/Holiday.pm 2015-01-06 21:16:19.000000000 +0900
+++ Calendar-Japanese-Holiday-0.05/lib/Calendar/Japanese/Holiday.pm 2019-01-17 12:46:16.729209680 +0900
@@ -13,14 +13,61 @@
our @EXPORT = qw(getHolidays isHoliday);
-our $VERSION = '0.04';
+our $VERSION = '0.05';
our $FurikaeStr = '振替';
my @StaticHoliday = (
+# 2021年以降、通常の祝日に戻る
+ {'start' => 2021, 'end' => 2999,
+ 'days' => {1 => { 1 => '元日'},
+ 2 => {11 => '建国記念の日',
+ 23 => '天皇誕生日'},
+ 4 => {29 => '昭和の日'},
+ 5 => { 3 => '憲法記念日',
+ 4 => 'みどりの日',
+ 5 => 'こどもの日'},
+ 8 => {11 => '山の日'},
+ 11 => { 3 => '文化の日',
+ 23 => '勤労感謝の日'},
+ },
+ },
+# 天皇誕生日変更 12/23 => 2/23
+# 以下は2020年東京オリンピック・パラリンピック競技大会の円滑な準備及び運営に資するための特例
+# 海の日は東京オリンピック開会式前日に
+# 体育の日は東京オリンピック開会式当日になり、以降スポーツの日に改称
+# 山の日は東京オリンピック閉会式翌日に
+ {'start' => 2020, 'end' => 2020,
+ 'days' => {1 => { 1 => '元日'},
+ 2 => {11 => '建国記念の日',
+ 23 => '天皇誕生日'},
+ 4 => {29 => '昭和の日'},
+ 5 => { 3 => '憲法記念日',
+ 4 => 'みどりの日',
+ 5 => 'こどもの日'},
+ 7 => {23 => '海の日',
+ 24 => 'スポーツの日'},
+ 8 => {10 => '山の日'},
+ 11 => { 3 => '文化の日',
+ 23 => '勤労感謝の日'},
+ },
+ },
+# 天皇陛下退位により天皇誕生日のない年
+ {'start' => 2019, 'end' => 2019,
+ 'days' => {1 => { 1 => '元日'},
+ 2 => {11 => '建国記念の日'},
+ 4 => {29 => '昭和の日'},
+ 5 => { 3 => '憲法記念日',
+ 4 => 'みどりの日',
+ 5 => 'こどもの日'},
+ 8 => {11 => '山の日'},
+ 11 => { 3 => '文化の日',
+ 23 => '勤労感謝の日'},
+ },
+ },
# 山の日を追加
- {'start' => 2016, 'end' => 2999,
+ {'start' => 2016, 'end' => 2018,
'days' => {1 => { 1 => '元日'},
2 => {11 => '建国記念の日'},
4 => {29 => '昭和の日'},
@@ -156,6 +203,8 @@
198902 => {24 => '昭和天皇の大喪の礼'},
199011 => {12 => '即位礼正殿の儀'},
199306 => { 9 => '皇太子徳仁親王の結婚の儀'},
+ 201905 => { 1 => '天皇の即位の日'},
+ 201910 => {22 => '即位礼正殿の儀'},
);
my @daysInMonth = (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
@@ -301,17 +350,27 @@
%holidays = %{$holiday_tbl->{$mon}}; # Copy
}
- # Happy Monday (成人の日、海の日、敬老の日、体育の日)
+ # Happy Monday (成人の日、海の日、敬老の日、体育の日、スポーツの日)
my @mondays = weekdays($year, $mon, 1); # 月曜日の一覧
- if ($year >= 2000) {
+ # 2020年は海の日、スポーツの日がHappy Mondayではなく固定に
+ if ($year == 2020) {
if ($mon == 1) {$holidays{$mondays[1]} = '成人の日';}
- if ($mon == 10){$holidays{$mondays[1]} = '体育の日';}
+ if ($mon == 9) {$holidays{$mondays[2]} = '敬老の日';}
}
+ else {
+ if ($year >= 2000) {
+ if ($mon == 1) {$holidays{$mondays[1]} = '成人の日';}
+ if ($mon == 10){
+ $holidays{$mondays[1]} =
+ $year < 2020 ? '体育の日' : 'スポーツの日';
+ }
+ }
- if ($year >= 2003) {
- if ($mon == 7) {$holidays{$mondays[2]} = '海の日';}
- if ($mon == 9) {$holidays{$mondays[2]} = '敬老の日';}
+ if ($year >= 2003) {
+ if ($mon == 7) {$holidays{$mondays[2]} = '海の日';}
+ if ($mon == 9) {$holidays{$mondays[2]} = '敬老の日';}
+ }
}
# 不定なもの
@@ -328,8 +387,40 @@
# 国民の休日
if ($year >= 1986) {
+ # 月末日前と翌月月初の祝日が平日を挟んで国民の祝日になるケースに対応
+ my @added = ();
+ my $last_day = days_in_month($year, $mon);
+
+ if ($holidays{$last_day - 1}) {
+
+ my($next_year, $next_month) =
+ $mon == 12 ? ($year + 1, 1) : ($year, $mon + 1);
+
+ if (isHoliday($next_year, $next_month, 1)) {
+ my $trailed = $last_day + 1;
+ push @added, $trailed;
+ $holidays{$trailed} = 1;
+ }
+ }
+
+ # 2日と前月末日の祝日が平日を挟んで国民の祝日になるケース
+ if ($holidays{2}) {
+
+ my($prev_year, $prev_month) =
+ $mon == 1 ? ($year - 1, 12) : ($year, $mon - 1);
+
+ my $prev_last_day = days_in_month($prev_year, $prev_month);
+
+ if (isHoliday($prev_year, $prev_month, $prev_last_day)) {
+ my $led = 0;
+ push @added, $led;
+ $holidays{$led} = 1;
+ }
+ }
+
# 祝日に挟まれた平日を探す (祝日A - 平日B - 祝日C)
- while (my ($day, $name) = each %holidays) {
+ for my $day (keys %holidays) {
+ next if $day < 1 || $day >= $last_day;
if ( exists $holidays{$day + 2} &&
!exists $holidays{$day + 1}) {
my $wday = (localtime(timelocal(0, 0, 0,
@@ -342,6 +433,22 @@
$holidays{$day + 1} = '国民の休日';
}
+ if (exists $holidays{$day - 2} &&
+ !exists $holidays{$day - 1}) {
+ my $wday = (localtime(timelocal(0, 0, 0,
+ $day, $mon - 1, $year)))[6];
+ # 祝日Cの時は平日Bはただの振り替え休日
+ next if $wday == 2;
+
+ # 平日Bが日曜の場合も国民の休日とはならない
+ next if $wday == 1;
+
+ $holidays{$day - 1} = '国民の休日';
+ }
+ }
+
+ if (@added) {
+ delete $holidays{$_} for @added;
}
}
diff -urN Calendar-Japanese-Holiday-0.04/t/Calendar-Japanese-Holiday.t Calendar-Japanese-Holiday-0.05/t/Calendar-Japanese-Holiday.t
--- Calendar-Japanese-Holiday-0.04/t/Calendar-Japanese-Holiday.t 2015-01-06 21:51:15.000000000 +0900
+++ Calendar-Japanese-Holiday-0.05/t/Calendar-Japanese-Holiday.t 2019-01-17 12:40:42.101163760 +0900
@@ -2,7 +2,7 @@
use utf8;
-use Test::More tests => 60;
+use Test::More tests => 72;
BEGIN { use_ok('Calendar::Japanese::Holiday') };
#########################
@@ -214,7 +214,11 @@
ok(checkHoliday(2007, $ED, 4, 29, '昭和の日'), 'Shouwai(2007-)');
ok(checkHoliday(1949, 1988, 4, 29, '天皇誕生日'), 'TennouTanjoubi(-1988)');
-ok(checkHoliday(1989, $ED,12, 23, '天皇誕生日'), 'TennouTanjoubi(1989-)');
+ok(checkHoliday(1989, 2018,12, 23, '天皇誕生日'), 'TennouTanjoubi(1989-2018)');
+# 2019年は天皇誕生日がない
+ok(checkHoliday(2019, 2019,12, 23, ''), 'TennouTanjoubi(2019)');
+# 2020年以降天皇誕生日は2/23に
+ok(checkHoliday(2020, $ED, 2, 23, '天皇誕生日'), 'TennouTanjoubi(2020-)');
ok(checkHoliday(1949, $ED, 5, 3, '憲法記念日'), 'Kenpou');
@@ -235,6 +239,7 @@
ok(checkHoliday(1966, 1999,10, 10, '体育の日'), 'Taiiku(1966-1999)');
ok(checkHoliday(2000, 2000,10, 10, ''), 'Taiiku(2000 !Happy Monday)');
ok(checkHoliday(2007, 2007,10, 8, '体育の日'), 'Taiiku(2007 Happy Monday)');
+ok(checkHoliday(2021, 2021,10,11, 'スポーツの日'), 'Sports(2021 Happy Monday)');
ok(checkHoliday( $ST, $ED,11, 3, '文化の日'), 'Bunka');
@@ -244,9 +249,32 @@
ok(checkHoliday(1989, 1989, 2, 24, '昭和天皇の大喪の礼'), 'Exceptional');
ok(checkHoliday(1990, 1990,11, 12, '即位礼正殿の儀'), 'Exceptional');
ok(checkHoliday(1993, 1993, 6, 9, '皇太子徳仁親王の結婚の儀'), 'Exceptional');
+ok(checkHoliday(2019, 2019, 5, 1, '天皇の即位の日'), 'Exceptional');
+ok(checkHoliday(2019, 2019,10, 22, '即位礼正殿の儀'), 'Exceptional');
+
+# 2019年天皇の即位前後の平日は皇室慶弔行事と祝日に挟まれた国民の休日
+ok(cmpHash(getHolidays(2019, 4, 1),
+ {29 => '昭和の日',
+ 30 => '国民の休日'}),
+ "getHolidays - Kokumin-no-hi in April (2019)");
+ok(cmpHash(getHolidays(2019, 5, 1),
+ {1 => '天皇の即位の日',
+ 2 => '国民の休日',
+ 3 => '憲法記念日',
+ 4 => 'みどりの日',
+ 5 => 'こどもの日',
+ 6 => '振替'}),
+ "getHolidays - Kokumin-no-hi in May (2019)");
ok(checkHoliday( $ST, 2015, 8, 11, ''), 'Yama(-2015)');
-ok(checkHoliday(2016, $ED, 8, 11, '山の日'), 'Yama(2016-2020)');
+ok(checkHoliday(2016, 2019, 8, 11, '山の日'), 'Yama(2016-2019)');
+ok(checkHoliday(2020, 2020, 8, 11, ''), 'Yama(2020)');
+ok(checkHoliday(2021, $ED, 8, 11, '山の日'), 'Yama(2016-2020)');
+
+# 2020年東京オリンピック・パラリンピック対応
+ok(checkHoliday(2020, 2020, 7, 23, '海の日'), 'Umi(2020)');
+ok(checkHoliday(2020, 2020, 7, 24, 'スポーツの日'), 'Sports(2020)');
+ok(checkHoliday(2020, 2020, 8, 10, '山の日'), 'Yama(2020)');
ok(checkShunbunShuubun(), 'Shunbun/Shuubun');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment