GASのいろんな区切り文字や形式の日付っぽいものをYYYY/MM/DD形式で返す関数を作った。

## はじめに
Google Apps Scriptでいろんな形式の日付ファイルを日付に変換する事が必要になったので作成。
YYYY/MM/DDで0埋めもして値を返す。
区切りが「.」「-」「/」に対応。
区切り文字無しはもうYYYYMMDD形式とYYMMDD形式しか受け付けない。
なぜなら2024111や24111は「2024/11/01」と捉えることも」「2024/01/11」と捉える事が出来るからだ。

## つくったもの
``` javascript
// 引数で受け取った様々な形式の日付っぽいものを「YYYY/MM/DD」形式にして返す
// ただし、2024111や24111は「11月1日」派なので「2024/11/01」として返す。
function formatDateToZeroPadding(input) {
  // 前後の文字列を取り除くために、数字と「-」「/」「.」だけを抽出
  var match = input.match(/\d{1,4}[-\/.]?\d{1,2}[-\/.]?\d{1,2}/) || input.match(/\d+/);

  if (!match) {
    return "";  // 有効な日付が見つからない場合は空文字を返す
  }

  var dateStr = match[0];
  var year, month, day;

  if (dateStr.includes('-') || dateStr.includes('/') || dateStr.includes('.')) {
    // 区切り文字がある場合、スプリットして年、月、日を取得
    var parts = dateStr.split(/[-\/.]/);
    if (parts.length < 3) {
      return "";  // 不完全な日付形式の場合は空文字を返す
    }
    // 切り分けた日付を各変数へ
    year = parts[0];
    month = parts[1];
    day = parts[2];
  } else {
    // 区切り文字がない場合（連続した数字）、適切に分割する
    if (dateStr.length === 8) {
      // YYYYMMDD形式
      year = dateStr.substring(0, 4);
      month = dateStr.substring(4, 6);
      day = dateStr.substring(6, 8);
    } else if (dateStr.length === 7) {
      // YYYYMDD形式 (例: 2024131, 2024101)
      year = dateStr.substring(0, 4);
      // 月が12より大きい場合、1桁の月として解釈
      if (parseInt(dateStr.substring(4, 6)) > 12) {
        month = dateStr.substring(4, 5);
        day = dateStr.substring(5, 7);
      } else {
        month = dateStr.substring(4, 6);
        day = dateStr.substring(6, 7);
      }
    } else if (dateStr.length === 6) {
      // YYMMD形式またはYYYYMD形式
      if (dateStr.startsWith('20')) {
        // YYYYMD形式として扱う
        year = dateStr.substring(0, 4);   // 年
        month = dateStr.substring(4, 5);  // 月 (1桁)
        day = dateStr.substring(5, 6);    // 日 (1桁)
      } else {
        // YYMMD形式
        year = '20' + dateStr.substring(0, 2); // 2桁の年を20XXとみなす
        month = dateStr.substring(2, 4);       // 月 (2桁)
        day = dateStr.substring(4, 6);         // 日 (2桁)
      }
    } else if (dateStr.length === 5) {
      // YYMDD形式 (例: 24131, 24101)
      year = '20' + dateStr.substring(0, 2);
      // 月が12より大きい場合、1桁の月として解釈
      if (parseInt(dateStr.substring(2, 4)) > 12) {
        month = dateStr.substring(2, 3);
        day = dateStr.substring(3, 5);
      } else {
        month = dateStr.substring(2, 4);
        day = dateStr.substring(4, 5);
      }
    } else if (dateStr.length === 4) {
      // YYMD形式
        year = '20' + dateStr.substring(0, 2); // 2桁の年を20XXとみなす
        month = dateStr.substring(2, 3);       // 月 (1桁)
        day = dateStr.substring(3, 4);         // 日 (1桁)
    } else {
      return "";  // 無効な日付形式の場合は空文字を返す
    }
  }

  // 年が2桁の場合、"20XX"形式に補完
  if (year.length === 2) {
    year = '20' + year;
  }

  // 月と日が1桁の場合、ゼロパディング
  if (month.length === 1) {
    month = '0' + month;
  }
  if (day.length === 1) {
    day = '0' + day;
  }

  // 日付の妥当性チェック
  // 2024/13/31とか2024/02/31とかを弾く
  var date = new Date(year, parseInt(month) - 1, day);
  if (date.getFullYear() !== parseInt(year) || 
      date.getMonth() !== parseInt(month) - 1 || 
      date.getDate() !== parseInt(day)) {
    return ""; // 無効な日付の場合は空文字を返す
  }
  // YYYY/MM/DDで返す
  return year + '/' + month + '/' + day;
}
```
## おわりに
もう二度と作りたくねぇ。正解はお前が決めろ

## 追記（2025/06/06）
変な人が変なハイフンで日付作り始めたので対応
ハイフンって、6種類あんねん。←？？？？
ハイフンってもう何。

``` diff
// 引数で受け取った様々な形式の日付っぽいものを「YYYY/MM/DD」形式にして返す
// ただし、2024111や24111は「11月1日」派なので「2024/11/01」として返す。
function formatDateToZeroPadding(input) {
+  // 似た記号や全角記号を正規の記号に統一
+  input = input
+    .replace(/[ー–−―ｰ]/g, "-")   // ハイフン類似を通常の "-" に統一
+    .replace(/[／]/g, "/")       // 全角スラッシュを半角に
+    .replace(/[．。]/g, ".");     // 全角ピリオドを半角に
  // 前後の文字列を取り除くために、数字と「-」「/」「.」だけを抽出
  var match = input.match(/\d{1,4}[-\/.]?\d{1,2}[-\/.]?\d{1,2}/) || input.match(/\d+/);

  if (!match) {
    return "";  // 有効な日付が見つからない場合は空文字を返す
  }

  var dateStr = match[0];
  var year, month, day;

  if (dateStr.includes('-') || dateStr.includes('/') || dateStr.includes('.')) {
    // 区切り文字がある場合、スプリットして年、月、日を取得
    var parts = dateStr.split(/[-\/.]/);
    if (parts.length < 3) {
      return "";  // 不完全な日付形式の場合は空文字を返す
    }
    // 切り分けた日付を各変数へ
    year = parts[0];
    month = parts[1];
    day = parts[2];
  } else {
    // 区切り文字がない場合（連続した数字）、適切に分割する
    if (dateStr.length === 8) {
      // YYYYMMDD形式
      year = dateStr.substring(0, 4);
      month = dateStr.substring(4, 6);
      day = dateStr.substring(6, 8);
    } else if (dateStr.length === 7) {
      // YYYYMDD形式 (例: 2024131, 2024101)
      year = dateStr.substring(0, 4);
      // 月が12より大きい場合、1桁の月として解釈
      if (parseInt(dateStr.substring(4, 6)) > 12) {
        month = dateStr.substring(4, 5);
        day = dateStr.substring(5, 7);
      } else {
        month = dateStr.substring(4, 6);
        day = dateStr.substring(6, 7);
      }
    } else if (dateStr.length === 6) {
      // YYMMD形式またはYYYYMD形式
      if (dateStr.startsWith('20')) {
        // YYYYMD形式として扱う
        year = dateStr.substring(0, 4);   // 年
        month = dateStr.substring(4, 5);  // 月 (1桁)
        day = dateStr.substring(5, 6);    // 日 (1桁)
      } else {
        // YYMMD形式
        year = '20' + dateStr.substring(0, 2); // 2桁の年を20XXとみなす
        month = dateStr.substring(2, 4);       // 月 (2桁)
        day = dateStr.substring(4, 6);         // 日 (2桁)
      }
    } else if (dateStr.length === 5) {
      // YYMDD形式 (例: 24131, 24101)
      year = '20' + dateStr.substring(0, 2);
      // 月が12より大きい場合、1桁の月として解釈
      if (parseInt(dateStr.substring(2, 4)) > 12) {
        month = dateStr.substring(2, 3);
        day = dateStr.substring(3, 5);
      } else {
        month = dateStr.substring(2, 4);
        day = dateStr.substring(4, 5);
      }
    } else if (dateStr.length === 4) {
      // YYMD形式
        year = '20' + dateStr.substring(0, 2); // 2桁の年を20XXとみなす
        month = dateStr.substring(2, 3);       // 月 (1桁)
        day = dateStr.substring(3, 4);         // 日 (1桁)
    } else {
      return "";  // 無効な日付形式の場合は空文字を返す
    }
  }

  // 年が2桁の場合、"20XX"形式に補完
  if (year.length === 2) {
    year = '20' + year;
  }

  // 月と日が1桁の場合、ゼロパディング
  if (month.length === 1) {
    month = '0' + month;
  }
  if (day.length === 1) {
    day = '0' + day;
  }

  // 日付の妥当性チェック
  // 2024/13/31とか2024/02/31とかを弾く
  var date = new Date(year, parseInt(month) - 1, day);
  if (date.getFullYear() !== parseInt(year) || 
      date.getMonth() !== parseInt(month) - 1 || 
      date.getDate() !== parseInt(day)) {
    return ""; // 無効な日付の場合は空文字を返す
  }
  // YYYY/MM/DDで返す
  return year + '/' + month + '/' + day;
}
```