Shopifyで出荷予定日をJavascriptで表示（アプリなし）

## はじめに
ECサイトで商品を購入する際には出荷予定日が表示されていると、購入する側からすると安心ですよね。
今回アプリを使用しないで、Javascriptのみで商品出荷予定日を表示できるよう実装しました！
詳細は以下の通りです。
- 商品購入日が平日で9時前であれば当日の日付を表示
- 商品購入日が平日で10時以降であれば翌日の日付を表示
- 翌日が休日の場合は休日明けの日付を表示（翌日が土曜日であれば月曜を表示、お盆休みや正月休みも休み明けの日を表示）
- 商品購入日が休日の場合も同様に休日明けの日付を表示

今回の実装ではAPI連携を行わずに、祝日やお盆休みをJavascript内に配列として定義しています。

## 実際のコード
```js
<script>
document.addEventListener('DOMContentLoaded', function() {
  // 購入日の日付を取得
  const purchaseDate = new Date();  // 仮の購入日として今の日時を設定
  
  // 出荷日を計算
  const shippingDate = calculateShippingDate(purchaseDate);

  // 出荷日を表示する要素に設定
  const shippingDateElement = document.createElement('p');
  shippingDateElement.innerHTML = '出荷日予定日: ' + formatDate(shippingDate);
  // .shipping-dateのクラス名を持つdivタグ内に出荷日を表示するpタグを追加
  document.querySelector('.shipping-date').appendChild(shippingDateElement);
});

// 出荷日を計算する関数
function calculateShippingDate(purchaseDate) {
  const shippingDate = new Date(purchaseDate);

  if( isHoliday(shippingDate) ){
    do {
    shippingDate.setDate(shippingDate.getDate() + 1);
    } while (!isBusinessDay(shippingDate));
    return shippingDate;

  }else if( isWeekday(shippingDate) && purchaseDate.getHours() < 9 ){
    return shippingDate;

  }else{
    do {
    shippingDate.setDate(shippingDate.getDate() + 1);
    } while (!isBusinessDay(shippingDate));
    return shippingDate;
  }

}

// 平日かどうかを判定する関数
function isWeekday(date) {
  const dayOfWeek = date.getDay();
  return dayOfWeek >= 1 && dayOfWeek <= 5;  // 1は月曜日、5は金曜日
}

// 営業日かどうかを判定する関数（土日と休暇を考慮）
function isBusinessDay(date) {
  return isWeekday(date) && !isHoliday(date);
}

// 休業日かどうかを判定する関数
function isHoliday(date) {
  const holidays = [
    { start: new Date(2024, 7, 10), end: new Date(2024, 7, 16) }, // お盆休み（8月10日〜8月16日）
    { start: new Date(2024, 11, 30), end: new Date(2025, 0, 3) }, // 正月休み（12月31日〜1月3日）
    { start: new Date(2024, 1, 12), end: new Date(2024, 1, 12) },
    { start: new Date(2024, 1, 23), end: new Date(2024, 1, 23) },
    { start: new Date(2024, 2, 20), end: new Date(2024, 2, 20) },
    { start: new Date(2024, 3, 29), end: new Date(2024, 3, 29) },
    { start: new Date(2024, 4, 3), end: new Date(2024, 4, 6) },
    { start: new Date(2024, 6, 15), end: new Date(2024, 6, 15) },
    { start: new Date(2024, 7, 11), end: new Date(2024, 7, 12) },
    { start: new Date(2024, 8, 16), end: new Date(2024, 8, 16) },
    { start: new Date(2024, 8, 22), end: new Date(2024, 8, 23) },
    { start: new Date(2024, 9, 14), end: new Date(2024, 9, 14) },
    { start: new Date(2024, 10, 3), end: new Date(2024, 10, 4) },
    { start: new Date(2024, 10, 23), end: new Date(2024, 10, 23) }
    // 他の休業期間を必要に応じて追加
  ];

  // 時間を初期化する 
  const targetDate = new Date(date.getFullYear(), date.getMonth(), date.getDate());

  return holidays.some(holiday => {
    return targetDate >= holiday.start && targetDate <= holiday.end;
  });
}

// 日付をフォーマットする関数
function formatDate(date) {
  const year = date.getFullYear();
  const month = ('0' + (date.getMonth() + 1)).slice(-2);
  const day = ('0' + date.getDate()).slice(-2);
  return year + '-' + month + '-' + day;
}

</script>
```
こちらの関数では現在の日時を取得`const purchaseDate = new Date();`していますが、仮に正しく動作するかテストする場合は、こちらの記述を`const purchaseDate = new Date(2024, 7, 10, 9, 0, 0, 0);`（今回のお盆休み初日の日時）などに変更して動作テストしてください！

例えば毎年この日時は固定で休みにしたいということであれば、休暇を配列で定義している箇所を以下のように書き換えてください！
```js
const holidays = [
    { start: new Date(date.getFullYear(), 7, 13), end: new Date(date.getFullYear(), 7, 16) }, // お盆休み（8月13日〜8月16日）
    { start: new Date(date.getFullYear(), 11, 30), end: new Date(date.getFullYear(), 11, 31) } // 年末休み（12月30日〜12月31日）
    { start: new Date(date.getFullYear(), 0, 1), end: new Date(date.getFullYear(), 0, 3) } // 正月休み（1月1日〜1月3日）
    // 他の休業期間を必要に応じて追加
  ];
```

## 終わりに
今回これだけ複雑な記述をしたのが初めてだったのでかなり大変でした...
本当はもっと関数を細分化して分けるといいと思うのですが、今回はそこまでの実装は行なっていません。
ネットで検索をしてもアプリを使って日付を表示するという記事が多かったので、同じようにJavascriptで表示したいという方の助けになれば嬉しいです！