- 技術 💻
祝日判定と営業日計算|内閣府CSVでPython・Java・JS・SQL・Excel
祝日の判定は、内閣府が公開している「国民の祝日」の CSV を読み込み、日付がその一覧にあるかで判断するのがいちばん確実です。 春分の日と秋分の日は法律で日付が決まっておらず、毎年2月の官報で翌年の日付が公表されるため、計算式だけで祝日を作ると将来の年で外れることがあります。
営業日は「土日でない・祝日でない・会社の休み(年末年始など)でない日」として判定し、N営業日後や営業日数はその判定を1日ずつ積み上げて求めます。この記事では、2026年のゴールデンウィークとシルバーウィーク(9月21日〜23日の3連休が祝日)を例に、Python・Java・JavaScript・SQL・Excel で同じ答えになるコードを載せています。
確認環境:Python 3.11.15、OpenJDK 21.0.10、Node.js 22.22.2、PostgreSQL 16.15、LibreOffice Calc 24.2(Excel と同名の WORKDAY・NETWORKDAYS 関数)。祝日は内閣府の CSV(2026年10月10日に取得した内容)を使用(確認日 2026年10月10日)。
早見表:やりたいこと別
| やりたいこと | Python | Excel | SQL(PostgreSQL) |
|---|---|---|---|
| 祝日か | d in HOLIDAYS |
=COUNTIF(祝日,A2)>0 |
EXISTS (SELECT 1 FROM holiday ...) |
| 営業日か | is_business_day(d) |
=WORKDAY(A2-1,1,祝日)=A2 |
business_calendar.is_business_day |
| N営業日後 | add_business_days(d, n) |
=WORKDAY(A2,N,祝日) |
営業日の通し番号+N で結合 |
| 期間の営業日数 | count_business_days(s, e) |
=NETWORKDAYS(開始,終了,祝日) |
COUNT(*) FILTER (WHERE is_business_day) |
| 第N営業日 | nth_business_day(y, m, n) |
=WORKDAY(月初-1,N,祝日) |
array_agg(...)[N] |
| 月末の最終営業日 | last_business_day(y, m) |
=WORKDAY(翌月1日,-1,祝日) |
MAX(cal_date) FILTER (...) |
| 土日以外の休み方(日曜のみ休み等) | is_business_day を書き換え |
=WORKDAY.INTL(A2,N,11,祝日) |
is_business_day の条件を変更 |
2026年の答え(年末年始12月29日〜1月3日を会社の休みとした場合):
| 問い | 答え |
|---|---|
| 2026年4月28日の5営業日後 | 2026年5月11日(4/29・5/3〜5/6 が休み) |
| 2026年9月18日(金)の1営業日後 | 2026年9月24日(9/21 敬老の日・9/22 休日・9/23 秋分の日) |
| 2026年9月の営業日数 | 19日 |
| 2027年1月の第3営業日 | 2027年1月6日 |
| 2026年12月の最終営業日 | 2026年12月28日 |
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「祝日判定と営業日計算|内閣府CSVでPython・Java・JS・SQL・Excel」
内閣府の祝日 CSV の中身
| 項目 | 内容 |
|---|---|
| URL | https://www8.cao.go.jp/chosei/shukujitsu/syukujitsu.csv |
| 収録期間 | 昭和30年(1955年)〜令和9年(2027年)(確認日時点) |
| 文字コード | Shift_JIS(UTF-8 として開くと文字化けする) |
| 形式 | 1行目が見出し「国民の祝日・休日月日,国民の祝日・休日名称」、2行目から 2026/1/1,元日 |
| 日付の書き方 | yyyy/M/d(月・日は0埋めしない) |
| 更新 | 翌年の祝日は前年の2月に掲載(令和10年分は令和9年2月) |
2026年分(18日)はこの内容です。
2026/1/1,元日
2026/1/12,成人の日
2026/2/11,建国記念の日
2026/2/23,天皇誕生日
2026/3/20,春分の日
2026/4/29,昭和の日
2026/5/3,憲法記念日
2026/5/4,みどりの日
2026/5/5,こどもの日
2026/5/6,休日
2026/7/20,海の日
2026/8/11,山の日
2026/9/21,敬老の日
2026/9/22,休日
2026/9/23,秋分の日
2026/10/12,スポーツの日
2026/11/3,文化の日
2026/11/23,勤労感謝の日
名称が「休日」の行は、振替休日と国民の休日です。 2026年5月6日は5月3日(日)の振替休日、2026年9月22日は敬老の日と秋分の日に挟まれた「国民の休日」です。CSV にはどちらも1行として入っているので、振替休日を自分で計算しなくても判定できます。
取り込みのときに気をつけること
| 注意点 | 対処 |
|---|---|
| 文字コードが Shift_JIS | Python は encoding='cp932'、Java は Windows-31J、Node.js は TextDecoder('shift_jis')、PostgreSQL は ENCODING 'SJIS' |
| 1行目が見出し | 読み飛ばす |
| 月日が0埋めされていない | yyyy/M/d の形式で解析する(yyyy/MM/dd だと Java では読めない) |
| 翌年より先が無い | 2028年の日付を判定すると「祝日なし」と答えてしまう。対象年が CSV の範囲に入っているかを確認する |
| 毎年の更新 | 2月の公表後に取り込み直す。URL が変わる可能性もあるので、自社のサーバーやストレージに保存したものを読む構成にしておく |
Python:標準ライブラリだけで書く
"""内閣府の祝日CSVで、祝日判定と営業日計算をする(標準ライブラリのみ)"""
import csv
from datetime import date, datetime, timedelta
from pathlib import Path
def load_holidays(path='syukujitsu.csv') -> dict[date, str]:
# 内閣府の CSV は Shift_JIS(cp932)。1行目は見出し
with Path(path).open(encoding='cp932', newline='') as f:
rows = list(csv.reader(f))[1:]
return {datetime.strptime(d, '%Y/%m/%d').date(): name for d, name in rows}
HOLIDAYS = load_holidays()
COMPANY_OFF = {(12, 29), (12, 30), (12, 31), (1, 2), (1, 3)} # 会社の休み(年末年始)
def is_holiday(d: date) -> bool:
return d in HOLIDAYS
def is_business_day(d: date) -> bool:
return d.weekday() < 5 and d not in HOLIDAYS and (d.month, d.day) not in COMPANY_OFF
def add_business_days(d: date, n: int) -> date:
"""n 営業日後(n が負なら前)。d 自身は数えない"""
step = 1 if n >= 0 else -1
while n:
d += timedelta(days=step)
if is_business_day(d):
n -= step
return d
def next_business_day(d: date) -> date:
"""d が営業日なら d、休みなら翌営業日"""
while not is_business_day(d):
d += timedelta(days=1)
return d
def count_business_days(start: date, end: date) -> int:
"""start〜end(両端を含む)の営業日数"""
return sum(is_business_day(start + timedelta(i)) for i in range((end - start).days + 1))
def nth_business_day(year: int, month: int, n: int) -> date:
"""その月の第 n 営業日"""
return add_business_days(date(year, month, 1) - timedelta(days=1), n)
def last_business_day(year: int, month: int) -> date:
first_next = date(year + month // 12, month % 12 + 1, 1)
return add_business_days(first_next, -1)
if __name__ == '__main__':
for d in [date(2026, 5, 6), date(2026, 9, 22), date(2026, 10, 10)]:
print(d, '祝日' if is_holiday(d) else '-', HOLIDAYS.get(d, ''), '営業日' if is_business_day(d) else '休み')
print('4/28の5営業日後 ', add_business_days(date(2026, 4, 28), 5))
print('9/18の1営業日後 ', add_business_days(date(2026, 9, 18), 1))
print('5/7の1営業日前 ', add_business_days(date(2026, 5, 7), -1))
print('9/19(土)の翌営業日 ', next_business_day(date(2026, 9, 19)))
print('2026年9月の営業日数 ', count_business_days(date(2026, 9, 1), date(2026, 9, 30)))
print('2027年1月の第3営業日 ', nth_business_day(2027, 1, 3))
print('2026年12月の最終営業日 ', last_business_day(2026, 12))
$ python3 bizday.py
2026-05-06 祝日 休日 休み
2026-09-22 祝日 休日 休み
2026-10-10 - 休み
4/28の5営業日後 2026-05-11
9/18の1営業日後 2026-09-24
5/7の1営業日前 2026-05-01
9/19(土)の翌営業日 2026-09-24
2026年9月の営業日数 19
2027年1月の第3営業日 2027-01-06
2026年12月の最終営業日 2026-12-28
add_business_daysは「起点の日は数えない」決まりです(Excel のWORKDAYと同じ)。起点が休みの日でも動きますcount_business_daysは両端を含みます(Excel のNETWORKDAYSと同じ)- 会社の休みは
COMPANY_OFFに月日で入れています。創立記念日や夏季休業など年ごとに変わる休みは、日付の集合を別に持ちます
ライブラリを使う場合
jpholiday(pip install jpholiday)は、祝日の規則を計算で判定するライブラリです。2026年・2027年の祝日を内閣府の CSV と突き合わせたところ、35日すべて一致しました。
import jpholiday
from datetime import date
jpholiday.is_holiday(date(2026, 9, 22)) # True
jpholiday.is_holiday_name(date(2026, 9, 22)) # '国民の休日'
jpholiday.year_holidays(2026) # [(date(2026, 1, 1), '元日'), ...]
春分の日・秋分の日のように将来の日付が公表前の年は、ライブラリの予測になります。業務で使うなら、ライブラリの更新時期と、内閣府の公表(毎年2月)を確認できる運用にしておきます。
Java:BusinessCalendar クラス
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.MonthDay;
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
/** 内閣府の祝日CSVで、祝日判定と営業日計算をする */
public class BusinessCalendar {
private static final DateTimeFormatter CSV_DATE = DateTimeFormatter.ofPattern("yyyy/M/d");
private static final Set<MonthDay> COMPANY_OFF = Set.of( // 会社の休み(年末年始)
MonthDay.of(12, 29), MonthDay.of(12, 30), MonthDay.of(12, 31),
MonthDay.of(1, 2), MonthDay.of(1, 3));
private final Map<LocalDate, String> holidays = new TreeMap<>();
public BusinessCalendar(Path csv) throws IOException {
// 内閣府の CSV は Shift_JIS(Windows-31J)。1行目は見出し
var lines = Files.readAllLines(csv, Charset.forName("Windows-31J"));
for (String line : lines.subList(1, lines.size())) {
String[] p = line.split(",");
holidays.put(LocalDate.parse(p[0], CSV_DATE), p[1]);
}
}
public boolean isHoliday(LocalDate d) { return holidays.containsKey(d); }
public boolean isBusinessDay(LocalDate d) {
return d.getDayOfWeek() != DayOfWeek.SATURDAY && d.getDayOfWeek() != DayOfWeek.SUNDAY
&& !holidays.containsKey(d) && !COMPANY_OFF.contains(MonthDay.from(d));
}
/** n 営業日後(n が負なら前)。d 自身は数えない */
public LocalDate addBusinessDays(LocalDate d, int n) {
int step = n >= 0 ? 1 : -1;
while (n != 0) {
d = d.plusDays(step);
if (isBusinessDay(d)) n -= step;
}
return d;
}
/** start〜end(両端を含む)の営業日数 */
public long countBusinessDays(LocalDate start, LocalDate end) {
return start.datesUntil(end.plusDays(1)).filter(this::isBusinessDay).count();
}
public LocalDate nthBusinessDay(YearMonth ym, int n) {
return addBusinessDays(ym.atDay(1).minusDays(1), n);
}
public LocalDate lastBusinessDay(YearMonth ym) {
return addBusinessDays(ym.plusMonths(1).atDay(1), -1);
}
public static void main(String[] args) throws IOException {
var cal = new BusinessCalendar(Path.of("syukujitsu.csv"));
System.out.println("2026-09-22 は祝日か : " + cal.isHoliday(LocalDate.of(2026, 9, 22)));
System.out.println("4/28の5営業日後 : " + cal.addBusinessDays(LocalDate.of(2026, 4, 28), 5));
System.out.println("9/18の1営業日後 : " + cal.addBusinessDays(LocalDate.of(2026, 9, 18), 1));
System.out.println("2026年9月の営業日数 : " + cal.countBusinessDays(LocalDate.of(2026, 9, 1), LocalDate.of(2026, 9, 30)));
System.out.println("2027年1月の第3営業日 : " + cal.nthBusinessDay(YearMonth.of(2027, 1), 3));
System.out.println("2026年12月の最終営業日 : " + cal.lastBusinessDay(YearMonth.of(2026, 12)));
}
}
$ java -Dstdout.encoding=UTF-8 BusinessCalendar.java
2026-09-22 は祝日か : true
4/28の5営業日後 : 2026-05-11
9/18の1営業日後 : 2026-09-24
2026年9月の営業日数 : 19
2027年1月の第3営業日 : 2027-01-06
2026年12月の最終営業日 : 2026-12-28
CSV の日付は 2026/1/1 のように0埋めされていないため、パターンは yyyy/M/d にしています。yyyy/MM/dd だと DateTimeParseException になります。文字コードは Windows-31J(Shift_JIS の Windows 拡張)を指定します。
JavaScript:Node.js とブラウザ共通
// 内閣府の祝日CSVで、祝日判定と営業日計算をする(Node.js 18以降・ブラウザ共通)
const COMPANY_OFF = new Set(['12-29', '12-30', '12-31', '01-02', '01-03']); // 会社の休み
// CSV の文字列(Shift_JIS をデコード済み)から Map<'YYYY-MM-DD', 名称> を作る
export function parseHolidays(text) {
const map = new Map();
for (const line of text.trim().split(/\r?\n/).slice(1)) {
const [d, name] = line.split(',');
const [y, m, day] = d.split('/');
map.set(`${y}-${m.padStart(2, '0')}-${day.padStart(2, '0')}`, name);
}
return map;
}
// 日付は UTC の0時で持ち、'YYYY-MM-DD' で比べる(タイムゾーンで日がずれないように)
const ymd = (dt) => dt.toISOString().slice(0, 10);
const addDays = (dt, n) => new Date(dt.getTime() + n * 86400000);
export function makeCalendar(holidays) {
const isBusinessDay = (dt) => {
const w = dt.getUTCDay();
return w !== 0 && w !== 6 && !holidays.has(ymd(dt)) && !COMPANY_OFF.has(ymd(dt).slice(5));
};
const addBusinessDays = (s, n) => {
let dt = new Date(s + 'T00:00:00Z');
const step = n >= 0 ? 1 : -1;
while (n !== 0) { dt = addDays(dt, step); if (isBusinessDay(dt)) n -= step; }
return ymd(dt);
};
const countBusinessDays = (s, e) => {
let c = 0;
for (let dt = new Date(s + 'T00:00:00Z'); ymd(dt) <= e; dt = addDays(dt, 1)) if (isBusinessDay(dt)) c++;
return c;
};
return { isHoliday: (s) => holidays.has(s), isBusinessDay: (s) => isBusinessDay(new Date(s + 'T00:00:00Z')),
addBusinessDays, countBusinessDays };
}
// Node.js で動かす例
if (import.meta.url === `file://${process.argv[1]}`) {
const { readFile } = await import('node:fs/promises');
const text = new TextDecoder('shift_jis').decode(await readFile('syukujitsu.csv'));
const cal = makeCalendar(parseHolidays(text));
console.log('2026-09-22 は祝日か :', cal.isHoliday('2026-09-22'));
console.log('4/28の5営業日後 :', cal.addBusinessDays('2026-04-28', 5));
console.log('9/18の1営業日後 :', cal.addBusinessDays('2026-09-18', 1));
console.log('2026年9月の営業日数 :', cal.countBusinessDays('2026-09-01', '2026-09-30'));
}
$ node bizday.mjs
2026-09-22 は祝日か : true
4/28の5営業日後 : 2026-05-11
9/18の1営業日後 : 2026-09-24
2026年9月の営業日数 : 19
日付は Date の UTC の0時で持ち、'YYYY-MM-DD' の文字列で比べています。getDay()(端末の時刻)を使うと、日本以外のタイムゾーンで動いたときに曜日が1日ずれるためです。
ブラウザで使う場合は、CSV を自社のサーバーに置いて fetch し、new TextDecoder('shift_jis').decode(await res.arrayBuffer()) で文字列にしてから parseHolidays に渡します。毎回内閣府のサイトから読むより、自社に置いたファイルのほうが表示も速く、更新の時期も自分で決められます。
SQL:祝日テーブルと営業日カレンダー
SQL では、祝日のテーブルと「1日1行の営業日カレンダー」を作っておくと、N営業日後や営業日数が結合1回で求まります。
-- 1) 祝日テーブルに内閣府の CSV を取り込む(Shift_JIS、見出し行あり)
CREATE TABLE holiday (
holiday_date DATE PRIMARY KEY,
name VARCHAR(20) NOT NULL
);
CREATE TEMP TABLE holiday_raw (d TEXT, name TEXT);
\copy holiday_raw FROM '/tmp/syukujitsu.csv' WITH (FORMAT csv, HEADER true, ENCODING 'SJIS')
INSERT INTO holiday SELECT to_date(d, 'YYYY/MM/DD'), name FROM holiday_raw;
-- 2) 営業日カレンダー(1日1行。営業日には通し番号を振る)
CREATE TABLE business_calendar AS
SELECT d::date AS cal_date,
(EXTRACT(ISODOW FROM d) < 6
AND NOT EXISTS (SELECT 1 FROM holiday h WHERE h.holiday_date = d::date)
AND to_char(d, 'MM-DD') NOT IN ('12-29','12-30','12-31','01-02','01-03')) AS is_business_day
FROM generate_series(DATE '2026-01-01', DATE '2027-12-31', INTERVAL '1 day') AS d;
ALTER TABLE business_calendar ADD COLUMN biz_no INT;
UPDATE business_calendar c SET biz_no = n.no
FROM (SELECT cal_date, ROW_NUMBER() OVER (ORDER BY cal_date) AS no
FROM business_calendar WHERE is_business_day) n
WHERE c.cal_date = n.cal_date;
CREATE INDEX ON business_calendar (biz_no);
biz_no は営業日だけに振った通し番号です。N営業日後は「番号+N の日」、営業日数は「番号の差」で求まります。
-- 2026-04-28 の5営業日後
SELECT c2.cal_date AS after_5_business_days
FROM business_calendar c1
JOIN business_calendar c2 ON c2.biz_no = c1.biz_no + 5
WHERE c1.cal_date = DATE '2026-04-28';
-- 休みの日(2026-09-19 土)から1営業日後:その日以前の最後の営業日番号に +1
SELECT c2.cal_date AS next_business_day
FROM business_calendar c2
WHERE c2.biz_no = (SELECT MAX(biz_no) FROM business_calendar WHERE cal_date <= DATE '2026-09-19') + 1;
-- 2026年9月の営業日数
SELECT COUNT(*) FILTER (WHERE is_business_day) AS business_days
FROM business_calendar
WHERE cal_date BETWEEN DATE '2026-09-01' AND DATE '2026-09-30';
-- 月ごとの第3営業日と最終営業日(2027年1〜3月)
SELECT date_trunc('month', cal_date)::date AS month,
(array_agg(cal_date ORDER BY cal_date) FILTER (WHERE is_business_day))[3] AS third_business_day,
MAX(cal_date) FILTER (WHERE is_business_day) AS last_business_day
FROM business_calendar
WHERE cal_date BETWEEN DATE '2027-01-01' AND DATE '2027-03-31'
GROUP BY 1 ORDER BY 1;
after_5_business_days
-----------------------
2026-05-11
next_business_day
-------------------
2026-09-24
business_days
---------------
19
month | third_business_day | last_business_day
------------+--------------------+-------------------
2027-01-01 | 2027-01-06 | 2027-01-29
2027-02-01 | 2027-02-03 | 2027-02-26
2027-03-01 | 2027-03-03 | 2027-03-31
MySQL では、LOAD DATA LOCAL INFILE '/tmp/syukujitsu.csv' INTO TABLE holiday_raw CHARACTER SET cp932 FIELDS TERMINATED BY ',' IGNORE 1 LINES; で取り込み、日付は STR_TO_DATE(d, '%Y/%c/%e') で変換します。カレンダーの行は、再帰 CTE か連番テーブルで作ります。
Excel:WORKDAY と NETWORKDAYS
祝日(と会社の休み)の一覧を1列に並べ、その範囲を3番目の引数に渡します。下は H 列に2026〜2027年の祝日と年末年始を並べ、LibreOffice Calc で計算した結果です。
| やりたいこと | 数式 | 結果 |
|---|---|---|
| 4/28の5営業日後 | =WORKDAY(DATE(2026,4,28),5,$H$1:$H$40) |
2026/05/11 |
| 9/18の1営業日後 | =WORKDAY(DATE(2026,9,18),1,$H$1:$H$40) |
2026/09/24 |
| 9/19(土)の翌営業日 | =WORKDAY(DATE(2026,9,19)-1,1,$H$1:$H$40) |
2026/09/24 |
| 2026年9月の営業日数 | =NETWORKDAYS(DATE(2026,9,1),DATE(2026,9,30),$H$1:$H$40) |
19 |
| 2027年1月の第3営業日 | =WORKDAY(DATE(2027,1,1)-1,3,$H$1:$H$40) |
2027/01/06 |
| 2026年12月の最終営業日 | =WORKDAY(DATE(2027,1,1),-1,$H$1:$H$40) |
2026/12/28 |
| 祝日か(2026/9/22) | =COUNTIF($H$1:$H$40,DATE(2026,9,22))>0 |
TRUE |
| 日曜だけ休みの5営業日後 | =WORKDAY.INTL(DATE(2026,4,28),5,11,$H$1:$H$40) |
2026/05/08 |
- 「その日が休みなら翌営業日」は
=WORKDAY(日付-1,1,祝日)と、前日から1営業日進めます WORKDAY.INTLの3番目の引数は休みの曜日です(1土日、11日曜のみ、"0000011"のような7文字の指定も可)- 祝日の範囲は「テーブル」にしておくと、翌年分を追加したときに数式を直さずに済みます
Google Apps Script:Google カレンダーの祝日を使う
スプレッドシートで使うなら、Google カレンダーの「日本の祝日」カレンダーを読む方法もあります。
const HOLIDAY_CAL = 'ja.japanese#holiday@group.v.calendar.google.com';
function isHoliday(date) {
const cal = CalendarApp.getCalendarById(HOLIDAY_CAL);
return cal.getEventsForDay(date).length > 0;
}
function isBusinessDay(date) {
const w = date.getDay();
return w !== 0 && w !== 6 && !isHoliday(date);
}
getEventsForDay は1日ずつカレンダーに問い合わせるため、1年分を判定すると遅くなります。多くの日付を判定する場合は、getEvents(開始, 終了) で期間の祝日をまとめて取り、Set に入れてから判定します。Google カレンダーの祝日カレンダーは内閣府の CSV とは別に管理されているため、法律上の祝日以外の行事が含まれていないかを、使う前に一覧で確かめます。
営業日の決まりごと(チームで先に決めておくこと)
| 決めること | 例 | 決めていないと起きること |
|---|---|---|
| 起点の日を数えるか | 「5営業日後」は起点を数えない | 1日ずれた納期が出る |
| 起点が休みの日の扱い | 翌営業日から数える/そのまま数える | 土日に受け付けた依頼の期限がずれる |
| 会社の休み | 年末年始(12/29〜1/3)、創立記念日、夏季休業 | 祝日だけで判定して、休みの日に期限が来る |
| 半日営業 | 営業日として数える/数えない | 担当者ごとに数え方が違う |
| 祝日データの更新 | 毎年2月の公表後に取り込む担当と手順 | 翌年の春分の日・秋分の日が反映されない |
| 祝日法の改正 | 臨時の祝日(2019年の即位の日など)の取り込み | 特別な年だけ判定が外れる |
よくある質問
Q. 振替休日は自分で計算する必要がありますか。 A. 内閣府の CSV を使う場合は不要です。振替休日と国民の休日は「休日」という名称の行として入っています。計算で判定するライブラリを使う場合は、ライブラリが振替休日に対応しているかを確認します。
Q. 春分の日・秋分の日は計算で求められますか。 A. 天文の計算でおおよその日付は求められますが、正式な日付は国立天文台が前年2月に官報で公表するものです。業務の判定には公表された日付(内閣府の CSV)を使うのが確実です。
Q. 内閣府の CSV を毎回ダウンロードしてよいですか。 A. アクセスのたびに取得するより、年に1回(2月の公表後)取り込み、自社のデータベースやファイルとして持つほうが安定します。取り込み時に件数と最終年を確認すると、更新漏れに気づけます。
Q. 土曜日が営業日の会社です。
A. is_business_day の土曜の条件を外し、Excel なら WORKDAY.INTL の休みの曜日を 11(日曜のみ)にします。
まとめ
- 祝日の判定は内閣府の CSV(Shift_JIS)を読み込んで、一覧にあるかで判定するのが確実。振替休日・国民の休日も「休日」として入っている
- 営業日は「土日でない・祝日でない・会社の休みでない」。N営業日後は1日ずつ進めて数える
- 起点の日は数えない(WORKDAY と同じ)、期間の日数は両端を含む(NETWORKDAYS と同じ) に合わせると、Excel と結果をそろえられる
- SQL は営業日カレンダーに通し番号を振ると、N営業日後・営業日数が結合1回で求まる
- CSV の範囲(確認日時点で2027年まで)と毎年2月の更新を運用に組み込む
参考・出典
確認日はいずれも 2026年10月10日です。
- 内閣府「国民の祝日について」:https://www8.cao.go.jp/chosei/shukujitsu/gaiyou.html
- 内閣府「国民の祝日」CSV:https://www8.cao.go.jp/chosei/shukujitsu/syukujitsu.csv
- e-Gov 法令検索「国民の祝日に関する法律」:https://laws.e-gov.go.jp/law/323AC1000000178
- jpholiday(PyPI):https://pypi.org/project/jpholiday/
- Java SE 21 API「DateTimeFormatter」:https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/time/format/DateTimeFormatter.html
- MDN「TextDecoder」:https://developer.mozilla.org/ja/docs/Web/API/TextDecoder
- PostgreSQL 16 文書「COPY」:https://www.postgresql.org/docs/16/sql-copy.html
- Microsoft サポート「WORKDAY 関数」「NETWORKDAYS 関数」「WORKDAY.INTL 関数」:https://support.microsoft.com/ja-jp/excel/functions/workday-function 、https://support.microsoft.com/ja-jp/excel/functions/networkdays-function 、https://support.microsoft.com/ja-jp/excel/functions/workday-intl-function
- Google Apps Script「CalendarApp」:https://developers.google.com/apps-script/reference/calendar/calendar-app
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「祝日判定と営業日計算|内閣府CSVでPython・Java・JS・SQL・Excel」
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。