iPhone や Mac でJavaScript の日付処理がNan表示になる - JavaScript

iPhone や Mac でJavaScript の日付処理がNan表示になる現象と対処法を紹介します。

現象の確認

次のHTMLファイルを作成します。
テキストボックスに入力した日付から10日間を引きテキストボックスに結果を戻す処理のJavaScriptコードです。
<html>
<head>
  <script type="text/javascript">
    function DateCalc() {
      var TextBox_Date = document.getElementById("TextBoxDate");
      var dateString = TextBox_Date.value;

      var dateobj = new Date(dateString);
      dateobj.setDate(dateobj.getDate() - 10);
     
      TextBox_Date.value = GetDateString(dateobj);
    }

    function GetDateString(dateobj) {
      date_string = 'YYYY-MM-DD';
      date_string = date_string.replace(/YYYY/g, dateobj.getFullYear());
      date_string = date_string.replace(/MM/g, dateobj.getMonth() + 1);
      date_string = date_string.replace(/DD/g, dateobj.getDate());
      return date_string;
    }

  </script>
  <meta charset="utf-8" />
  <title></title>
</head>
<body>
  <h1>日付計算のデモ</h1>
  <input type="text" id="TextBoxDate" value="2028-4-9"/>
  <input type="button" onclick="DateCalc();" value="Exec"/>
</body>
</html>

上記のHTMLファイルをMacのSafariのWebブラウザで開きます。下図のページが表示されます。


[Exec]ボタンをクリックします。テキストボックスの表示が "NaN-NaN-Nan" となってしまいます。


なお、Google ChromeやMicrosofr Edgeでは"NaN"表示にはなりません。


原因

以下のコードでDateオブジェクトを作成する処理で、コンストラクタの引数の文字列の形式によっては、SafariでDateオブジェクトを作成できないことが原因です。
  var dateobj = new Date(dateString);

それぞれの入力形式でエラーになるかを確認します。
入力形式 入力値 結果
YYYY/MM/DD 2024/03/07
YYYY/M/D 2024/3/7
YYYY-MM-DD 2024-03-07
YYYY-M-D 2024-3-7 ×

対処法

以下の対処法があります。

YYYY-M-D形式の入力を避ける

YYYY-M-D形式の入力を避け、YYYY-MM-DD 形式でテキストボックスに入力します。

YYYY/M/D形式の入力に変更する

区切り文字を"-"から"/"に変更し、YYYY/M/D 形式の入力にします。

YYYY-M-D形式の入力をYYYY-MM-DDに変換する

YYYY-M-D形式で入力された場合に、YYYY-MM-DD形式に変換します。

対処実装1

今回は、結果の文字列を"YYYY-MM-DD"でテキストボックスに表示する対策をします。
以下のコードに変更します。

コード

<html>
<head>
  <script type="text/javascript">
    function DateCalc() {
      var TextBox_Date = document.getElementById("TextBoxDate");
      var dateString = TextBox_Date.value;

      var dateobj = new Date(dateString);
      dateobj.setDate(dateobj.getDate() - 10);

     
      TextBox_Date.value = GetDateString(dateobj);
    }

    function GetDateString(dateobj) {
      return String(dateobj.getFullYear()).padStart(4,"0") + "-" + String(dateobj.getMonth() + 1).padStart(2, "0") + "-" + String(dateobj.getDate()).padStart(2, "0");
    }

  </script>
  <meta charset="utf-8" />
  <title></title>
</head>
<body>
  <h1>日付計算のデモ</h1>
  <input type="text" id="TextBoxDate" value="2028-04-09"/>
  <input type="button" onclick="DateCalc();" value="Exec"/>
</body>
</html>

解説

HTMLページのテキストボックスの初期値を"2028-04-09"に変更し、"YYYY-MM-DD"形式の文字列にしています。
  <input type="text" id="TextBoxDate" value="2028-04-09"/>
padStartメソッドを呼び出し、年は3桁以下の場合は左側を0で埋めた文字列にする処理を、月と日は1桁の場合は、左側に0を埋めた文字列にする処理を追加しています。 結果の文字列が"YYYY-MM-DD"形式で表示される動作にしています。
0を埋めて桁揃えするコードについてはこちらの記事を参照してください。
  function GetDateString(dateobj) {
    return String(dateobj.getFullYear()).padStart(4,"0") 
      + "-" + String(dateobj.getMonth() + 1).padStart(2, "0")
      + "-" + String(dateobj.getDate()).padStart(2, "0");
  }

対処実装2

YYYY-M-Dの入力を受け付ける修正コードです。
先のコードと同様ですが、YYYY-M-Dの形式が入力された場合に、年、月、日の値を取得して0で桁を埋めて、YYYY-MM-DDの文字列形式に変換して、 Dateオブジェクトのコンストラクタの引数に渡す方法です。

コード

<html>
<head>
  <script type="text/javascript">
    function DateCalc() {
      var TextBox_Date = document.getElementById("TextBoxDate");
      var dateString = TextBox_Date.value;

      var reg = new RegExp("([0-9]+)\-([0-9]{1,2})\-([0-9]{1,2})");
      var result = dateString.match(reg);
      var dateStringFix =  result[1].padStart(4,"0") + "-" + result[2].padStart(2, "0") + "-" + result[3].padStart(2, "0");

      var dateobj = new Date(dateStringFix);
      dateobj.setDate(dateobj.getDate() - 10);

     
      TextBox_Date.value = GetDateString(dateobj);
    }

    function GetDateString(dateobj) {
      return String(dateobj.getFullYear()).padStart(4,"0") + "-" + String(dateobj.getMonth() + 1).padStart(2, "0") + "-" + String(dateobj.getDate()).padStart(2, "0");
    }

  </script>
  <meta charset="utf-8" />
  <title></title>
</head>
<body>
  <h1>日付計算のデモ</h1>
  <input type="text" id="TextBoxDate" value="2028-04-09"/>
  <input type="button" onclick="DateCalc();" value="Exec"/>
</body>
</html>
このページのキーワード
  • iPhone や Mac でJS の日付処理がNan表示になる
著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用
最終更新日: 2024-05-21
作成日: 2024-05-21
iPentec all rights reserverd.