
夫婦やカップルの片方が4勤2休、もう片方が土日休み。そんなふたりの「ふたりとも休みの日」を出すカレンダーアプリを、AI(Claude)で作り、note で売っています。2人ぶんの勤務の重ね方、有給を入れると連休になる日の探し方、別のAIに壊させる点検で何が見つかったかを書きます。
※この記事には広告(PR)を含みます。
作ったもの
「ふたりの休み合わせカレンダー」という、ブラウザで動くカレンダーです。ふたりの勤務の形(4勤2休・3勤3休などの交替勤務、土日祝休みなど)を選ぶと、ふたりとも休みの日が色つきで出ます。
- お試し版(無料):12の形から選んで、今月と来月のカレンダー、次にふたりとも休みの日・2日以上続けて休める日・ふたりそろって土日休みになる週末
- 完全版(有料・note で案内):毎月のシフト表の入力、有給で連休をつくる期間の案、3人まで、好きな月と年、その日だけの変更、A4印刷・画像・スマホのカレンダー用ファイル(.ics)、設定のURL保存
どちらも HTML ファイル1枚です。サーバーもデータベースもなく、GitHub Pages に置いただけで動きます。外から読むのは Google Fonts だけで、入力した内容はどこにも送りません。
お試し版は、ここで触れます。
(表示されない場合は お試し版をブラウザで開く)
2026年10月15日の夜に題材を決めて作り始め、10月16日の19時に note で公開しました。設計・コード・テスト・記事の原稿は AI が書いています。
題材の選び方:検索の上位に道具が無い語
同じシリーズの1本目(交替勤務カレンダーメーカー)が売れたので、同じ「働く人の困りごとの道具」で探しました。
「夜勤 手当 計算」「有給消化 最終出社日 計算」は、検索の上位にすでに計算の道具が並んでいました。後から同じものを出しても埋もれます。
「夫婦 休み 合わない」「4勤2休 夫婦」「シフト制 カップル 休み 合わない」は、上位が Q&A サイトと個人の体験談だけで、道具はありませんでした。困っている人はいて、答えの道具が無い語です。
2人の勤務を重ねる:どの形も「n日目の勤務」を返す関数にそろえる
人ごとに、勤務の決まり方が3つあります。
- 並びのくり返し(4勤2休など):基準日からの日数を並びの長さで割った余り
- 曜日で決まる(土日祝休みなど):曜日・祝日・年末年始
- シフト表(日ごとに入れる):入れていない日は「分からない」
どれも「n日目の勤務」を返す関数にそろえ、その上に「その日だけの変更」(有給・休日出勤)を重ねます。「ふたりとも休み」は、全員が休み(有給を含む)の日です。分からない日は休みに数えません(実際のコードを、読みやすく書き直したもの)。
// その人の、n日目の勤務(並び・曜日から決まるもの)。シフト表の人は null
function baseTypeAt(p, n){
if(p.mode === 'cycle'){
const N = p.cycle.length;
return TYPE[p.cycle.charAt(
mod(p.pos + (n - p.base), N))];
}
if(p.mode === 'week'){
const off = p.mask.charAt(fromDn(n).w) === '1'
|| (p.hol && HOLIDAYS[iso(n)] !== undefined)
|| (p.nen && isNenmatsu(n));
return TYPE[off ? 'r' : 'k'];
}
return null;
}
// その日だけの変更(有給・休日出勤・シフト表)を上に重ねる
const typeAt = (p, n) =>
p.over[n] ? TYPE[p.over[n]] : baseTypeAt(p, n);
// 全員が休み(有給を含む)の日か
const allOff = n => state.people.every(p => {
const t = typeAt(p, n);
return t && (t.kind === 'rest' || t.kind === 'paid');
});
日付は、すべて「1970年1月1日からの通し日数」で扱います。Date.UTC で数えるので、端末の時差で1日ずれることがありません(1本目と同じ作り)。
有給で連休をつくる:予算つきの区間さがし
完全版のいちばんの売りは、「有給を何日入れると、ふたりの連休がどこにできるか」を出す機能です。
明日から半年の日を1日ずつ見て、全員が休みの日は0、だれかが出勤の日は「出勤の人数」を、その日に要る有給の日数とします。夜勤明けの日・勤務が入っていない日・休みの日に入れた休日出勤の日は、有給を入れられない日として区切ります。
あとは、左から区間を伸ばして、要る有給の合計が予算(1〜3日)を超えたら止める、をくり返します。長い順・有給の少ない順に並べ、もっと少ない有給で同じかそれより長くなる案に含まれる案は出しません。
// info[i]:その日に要る有給の日数(出勤の人数)。
// 有給を入れられない日は null
for(let i = 0; i < info.length; i++){
if(!info[i]) continue;
// 前の日が全員休みなら、そこから始めたほうが長い
if(i > 0 && info[i - 1]
&& info[i - 1].cost === 0) continue;
let cost = 0, j = i;
while(j < info.length && info[j]
&& cost + info[j].cost <= B){
cost += info[j].cost; j++;
}
if(cost > 0 && j - i >= 2)
wins.push({s: i, e: j - 1, cost});
}
テストでは、すべての区間を調べる総当たりを Python で別に書き、いちばん上の案の長さと有給の日数が一致するか、どの案も「書いてある日に有給を入れると、書いてある期間がちょうど全員休みになる」かを、ランダムな組み合わせ40通り×予算3通りで確かめています。
設定はURLに入れる
完全版は、ふたり分の勤務・基準日・呼び名・その日だけの変更(シフト表も)を、全部URLの「#」の後ろに書きます。サーバーも端末の保存も使いません。URLを相手に送れば、相手のスマホでも同じカレンダーが開けます。
シフト表は日数が多いので、続いた日を「20261101-ddrrn」(11月1日から日勤・日勤・休み・休み・夜勤)のようにまとめて書きます。
URLの書き方には、前の3本で決めた決まりがあります。開いただけでは書かない、打っているあいだは書かず400ミリ秒待って1回だけ書く、読めないURLは上書きしない、名前は文字の途中で切らず( ) ' ! * も符号化する(LINE でURLが切れるため)、です。
テストと、別のAIの点検
自分のテストは3本です。計算を別の実装(Python)と1年ぶん突き合わせるもの(ランダムな40通り)、画面の操作と書き出し(.ics・A4の印刷・画像・コピー)を確かめるもの、点検の指摘を1件ずつ見張るものです。3本で、合わせて約4,200項目です。
全部通ったあとで、作ったAIとは別のAIに「壊す気で点検して」と渡しました。1回目は、重い指摘が2件、中くらいが4件、細かい指摘が14件でした。代表的なものです。
- 長いシフト表がURLから消える:続いた日をまとめて書く区切りを、読む側は400日までしか受けていなかった。毎月シフト表を入れる人は、1年あまりで必ず当たる
- 有給の案が、過ぎた日まで連休の日数に入れていた:今日より前へ最大400日さかのぼって数えていた。自分で書いた総当たりのテストも同じ数え方をしていて、見つけられなかった
- 今日がふたりとも休みの日に、文が食い違う:「今日はふたりとも休みです」の次に「ふたりとも休みの日はありません」と出ていた
- よくある形を選ぶと、自分で作った並びが黙って消える:作った並び・選んだ曜日・シフト表は、別の形に替えてもしまっておき、戻したら戻すようにした
2つ目は大事な点です。答え合わせのテストを同じAIが書くと、同じ思い込み(今日より前もさかのぼって数える)を持ったまま書いてしまい、テストが通ってしまいます。壊す役を別に置く意味は、ここにあります。
直したあとで、もう一度別のAIに壊させました。2回目は、1回目の指摘はすべて直っていた一方で、直したことで入った不具合が中くらいで3件見つかりました。
- 自分で作った並びをしまって戻すと、基準日だけがほかの形のものになり、並びが9日ずれて戻る
- 「シフト表」を選んで戻すだけで、もとの形に入れていた有給が消える(シフト表の日と、その日だけの変更を混ぜていた)
- 年をまたぐ連休を年ごとのファイルにすると、2つのファイルで予定の ID(UID)が同じになり、カレンダーによっては半分が消える(1回目の指摘の直し方が原因)
3回目は、直したところだけを壊させました。それでも、直し方の副作用が2件見つかりました。
- 呼び名を打った直後に、ほかのボタンを押しても効かない(名前の描き直しで、押したボタンが作り直されていた)
- 「取り消す」の知らせが出ているあいだに印刷すると、白紙の2枚目が出る(知らせのための余白が、印刷にも残っていた)
3本目のゲームでも、1回目の直しで新しい不具合が入りました。直したら、直したところを中心にもう一度壊させる、を必ず入れています。
記事も校閲させる
note の記事の原稿も、アプリのソースと1文ずつ突き合わせる校閲を別のAIにさせました。30件の指摘があり、7件は買う前に知らせるべきことや、書いてあるとおりにすると誤解するところでした。たとえば次のようなものです。
- 見本の画像の説明「この組み合わせだと、11月にふたりとも休みの日は2日だけ」は、並びのずれ方しだいで2〜5日に変わるのに、言い切っていた
- 「URLを相手に送って同じカレンダーを見る」は、あとで変えた分が相手に届かないことを、有料部分でしか書いていなかった
- 「夜勤明けは休みに数えません」は、明けの無いよくある形(4勤2休・2交替など)の人には逆の意味に読めた
画面の文字を「」で引くところは、アプリの文字と一字一句合わせています。
同じものを作るときの手順
- 検索結果を見て、計算・判定の道具が上位に無い語を選ぶ
- 人ごとの勤務を「n日目の勤務」を返す関数にそろえてから重ねる
- 計算は別の言語で同じ式を書いて突き合わせる。ただし、答え合わせの側も同じ思い込みを持ちうる
- .ics・印刷・画像は、別のライブラリや実際の出力で確かめる
- 別のAIに壊させて直し、直したあとにもう一度壊させる。記事もアプリと突き合わせて校閲させる
- 公開は GitHub Pages(無料・静的ファイルだけ)。完全版は当てにくい名前のリポジトリに置き、noindex にする
同じ型で作った、交替勤務カレンダーメーカーと、灯油の日数・灯油代 計算機の記録もあります。
完全版について
完全版では、毎月のシフト表の入力、有給で連休をつくる期間の案、3人まで、1年ぶんの一覧、A4の印刷、画像の保存、スマホのカレンダー用ファイルが使えます。下は完全版で作った画像(自分が4勤2休・2交替、相手が土日祝休み、2026年11月の例)です。

完全版は、note「余白の実験室」の記事で案内しています(有料・買い切り)。
※この記事は、AI(Claude)でブラウザのアプリを作って売るまでの記録です。アプリは勤務の形から作る目安のカレンダーで、実際の勤務は会社のカレンダーやシフト表が優先です。



