文字列が ISO 形式の日付かどうかの判定

Beginner

This tutorial is from open-source community. Access the source code

はじめに

この実験では、与えられた文字列が簡略拡張 ISO 形式 (ISO 8601) の有効な日付文字列であるかどうかを判断する方法を探ります。Date コンストラクタとそれに関連するメソッドを使用して、文字列から Date オブジェクトを作成し、その有効性をチェックします。この実験の終わりまでに、JavaScript で日付を扱う方法と、ISO 形式を使って日付を検証する方法をより深く理解するようになります。

ISO 日付形式と JavaScript の Date オブジェクトの理解

コーディングを始める前に、ISO 8601 日付形式とは何か、および JavaScript が日付をどのように扱うかを理解しましょう。

ISO 8601 日付形式

ISO 8601 形式は、日付と時刻を表す国際標準です。簡略拡張 ISO 形式は次のようになります。

YYYY-MM-DDTHH:mm:ss.sssZ

ここで:

  • YYYY は年を表します (4 桁)
  • MM は月を表します (2 桁)
  • DD は日を表します (2 桁)
  • T は日付と時刻を区切るリテラル文字です
  • HH は時を表します (2 桁)
  • mm は分を表します (2 桁)
  • ss は秒を表します (2 桁)
  • sss はミリ秒を表します (3 桁)
  • Z は UTC タイムゾーン (ズールー時間) を示します

たとえば、2023-05-12T14:30:15.123Z は 2023 年 5 月 12 日、UTC 時間の午後 2 時 30 分 15.123 秒を表します。

JavaScript の Date オブジェクト

JavaScript は、日付と時刻を扱うための組み込みの Date オブジェクトを提供しています。新しい Date オブジェクトを作成するときに、ISO 形式の文字列を渡すことができます。

const date = new Date("2023-05-12T14:30:15.123Z");

ターミナルを開いて、Date オブジェクトの操作を練習しましょう。

  1. WebIDE の上部にあるターミナルメニューをクリックして、ターミナルを開きます。
  2. node と入力し、Enter キーを押して Node.js の対話型シェルを起動します。
  3. 現在の時刻の新しい Date オブジェクトを作成します。
const now = new Date();
console.log(now);
node-prompt
  1. この Date オブジェクトを ISO 文字列に変換します。
const isoString = now.toISOString();
console.log(isoString);

次のような出力が表示されるはずです。

2023-05-12T14:30:15.123Z
  1. ISO 文字列から Date オブジェクトを作成します。
const dateFromIso = new Date("2023-05-12T14:30:15.123Z");
console.log(dateFromIso);
node-prompt

これは、JavaScript が ISO 形式の文字列から Date オブジェクトを解析して作成できることを示しています。

ISO 形式の日付文字列を検証する関数の作成

このステップでは、与えられた文字列が有効な ISO 8601 形式であるかどうかをチェックする JavaScript 関数を作成します。

検証関数の作成

ISO 日付検証器用の新しい JavaScript ファイルを作成しましょう。

  1. WebIDE で、左側のサイドバーにあるエクスプローラーアイコンをクリックします。
  2. ファイルエクスプローラー内で右クリックし、「新しいファイル」を選択します。
  3. ファイル名を isISODate.js と入力し、Enter キーを押します。
  4. 以下のコードをファイルに追加します。
/**
 * Checks if a string is a valid ISO 8601 formatted date string
 * @param {string} val - The string to check
 * @return {boolean} - Returns true if the string is in ISO format, false otherwise
 */
const isISOString = (val) => {
  // Create a Date object from the input string
  const d = new Date(val);

  // Check if the date is valid (not NaN) and if the ISO string matches the original
  return !Number.isNaN(d.valueOf()) && d.toISOString() === val;
};

// Export the function so we can use it elsewhere
module.exports = isISOString;

この関数がどのように動作するかを見てみましょう。

  1. new Date(val) は入力文字列から Date オブジェクトを作成します。
  2. d.valueOf() は数値のタイムスタンプ値(1970 年 1 月 1 日からのミリ秒数)を返します。
  3. Number.isNaN(d.valueOf()) は日付が無効であるかどうかをチェックします(NaN は「非数値」を意味します)。
  4. d.toISOString() === val は、Date オブジェクトを ISO 文字列に変換した結果が元の入力と一致することを検証します。

関数のテスト

では、関数を試すための簡単なテストファイルを作成しましょう。

  1. testISO.js という名前の別のファイルを作成します。
  2. 以下のコードを追加します。
// Import our isISOString function
const isISOString = require("./isISODate");

// Test with a valid ISO formatted date
console.log("Testing a valid ISO date:");
console.log("2020-10-12T10:10:10.000Z");
console.log("Result:", isISOString("2020-10-12T10:10:10.000Z"));
console.log();

// Test with an invalid format
console.log("Testing a non-ISO date:");
console.log("2020-10-12");
console.log("Result:", isISOString("2020-10-12"));
  1. Node.js を使ってテストファイルを実行します。
node testISO.js

以下のような出力が表示されるはずです。

Testing a valid ISO date:
2020-10-12T10:10:10.000Z
Result: true

Testing a non-ISO date:
2020-10-12
Result: false

これは、私たちの関数が "2020-10-12T10:10:10.000Z" が有効な ISO 形式の日付であり、"2020-10-12" がそうでないことを正しく識別していることを示しています。

様々な日付形式でのテスト

基本的な検証関数ができたので、様々な入力に対する動作を理解するために、異なる日付形式でテストしてみましょう。

テストスイートの作成

様々な日付形式を調べるための包括的なテストスイートを作成しましょう。

  1. dateTester.js という名前の新しいファイルを作成します。
  2. 以下のコードを追加します。
// Import our isISOString function
const isISOString = require("./isISODate");

// Function to test different date strings
function testDate(description, dateString) {
  console.log(`Testing: ${description}`);
  console.log(`Input: "${dateString}"`);
  console.log(`Is ISO Format: ${isISOString(dateString)}`);
  console.log("-----------------------");
}

// Valid ISO date examples
testDate("Standard ISO date with timezone Z", "2023-05-12T14:30:15.123Z");
testDate("ISO date with zero milliseconds", "2020-10-12T10:10:10.000Z");

// Invalid or non-ISO format examples
testDate("Date only (no time component)", "2023-05-12");
testDate("Date and time without milliseconds", "2023-05-12T14:30:15Z");
testDate(
  "Date with time zone offset instead of Z",
  "2023-05-12T14:30:15+01:00"
);
testDate("Invalid date (month 13 does not exist)", "2023-13-12T14:30:15.123Z");
testDate("Non-date string", "Hello World");
  1. ターミナルでテストスイートを実行します。
node dateTester.js

どの文字列が有効な ISO 日付で、どれが無効なのかを示す出力が表示されるはずです。

結果の理解

各テストケースが有効または無効になる理由を分析してみましょう。

  1. 2023-05-12T14:30:15.123Z - これは、UTC タイムゾーンの指示子 (Z) を含む完全な ISO 8601 形式に従っているため、有効です。

  2. 2020-10-12T10:10:10.000Z - ミリ秒が明示的に 000 に設定されているため、これも有効です。

  3. 2023-05-12 - これは有効な日付ですが、時間の部分が欠けているため、ISO 形式ではありません。

  4. 2023-05-12T14:30:15Z - これは ISO 形式のように見えますが、厳密な ISO 形式では必須のミリ秒が欠けています。

  5. 2023-05-12T14:30:15+01:00 - これは 'Z' の代わりにタイムゾーンのオフセット (+01:00) を使用しています。ISO 8601 では有効ですが、私たちの関数は toISOString() が生成する正確な形式(常に 'Z' を使用)を要求しています。

  6. 2023-13-12T14:30:15.123Z - これは無効な日付です(13 月は存在しません)。そのため、new Date() は無効な Date オブジェクトを作成します。

  7. Hello World - これはまったく日付ではないため、new Date() は無効な Date オブジェクトを作成します。

私たちの検証関数は、具体的に 2 つの条件をチェックします。

  1. 文字列は有効な日付に解析できなければなりません(NaN ではない)。
  2. その日付を ISO 文字列に変換したとき、元の入力と完全に一致しなければなりません。

このアプローチにより、JavaScript の toISOString() メソッドが生成する正確な ISO 形式を検証できます。

エッジケースの処理と関数の改善

この最後のステップでは、isISOString 関数を改善してエッジケースを処理し、より堅牢なものにします。

一般的なエッジケース

実際のアプリケーションでデータを検証する際には、様々な予期しない入力を処理する必要があります。いくつかのエッジケースを見てみましょう。

  1. 空文字列
  2. 文字列以外の値(null、undefined、数値、オブジェクト)
  3. 異なるタイムゾーンの表現

関数の強化

これらのエッジケースを処理するように isISODate.js ファイルを更新しましょう。

  1. WebIDE で isISODate.js ファイルを開きます。
  2. 既存のコードを以下の改善版に置き換えます。
/**
 * Checks if a string is a valid ISO 8601 formatted date string
 * @param {string} val - The string to check
 * @return {boolean} - Returns true if the string is in ISO format, false otherwise
 */
const isISOString = (val) => {
  // Check if input is a string
  if (typeof val !== "string") {
    return false;
  }

  // Check if string is empty
  if (val.trim() === "") {
    return false;
  }

  try {
    // Create a Date object from the input string
    const d = new Date(val);

    // Check if the date is valid and if the ISO string matches the original
    return !Number.isNaN(d.valueOf()) && d.toISOString() === val;
  } catch (error) {
    // If any error occurs during validation, return false
    return false;
  }
};

// Export the function
module.exports = isISOString;

この改善された関数は、以下のことを行います。

  1. 処理する前に入力が文字列であることをチェックします。
  2. 空文字列を処理します。
  3. 検証中に発生する可能性のあるエラーを処理するために try-catch ブロックを使用します。
  4. 依然として核心的な検証ロジックを実行します。

改善された関数のテスト

エッジケースで改善された関数を検証するための最後のテストファイルを作成しましょう。

  1. edgeCaseTester.js という名前の新しいファイルを作成します。
  2. 以下のコードを追加します。
// Import our improved isISOString function
const isISOString = require("./isISODate");

// Function to test and display results
function testCase(description, value) {
  console.log(`Testing: ${description}`);
  console.log(`Input: ${value === "" ? "(empty string)" : value}`);
  console.log(`Type: ${typeof value}`);
  console.log(`Is ISO Format: ${isISOString(value)}`);
  console.log("-----------------------");
}

// Test with various edge cases
testCase("Valid ISO date", "2023-05-12T14:30:15.123Z");
testCase("Empty string", "");
testCase("Null value", null);
testDate("Undefined value", undefined);
testCase("Number value", 12345);
testCase("Object value", {});
testCase("Current date as ISO string", new Date().toISOString());
  1. テストファイルを実行します。
node edgeCaseTester.js

実際のアプリケーションでの使用

実際のアプリケーションでは、isISOString 関数は以下のようなシナリオで使用できます。

  1. 日付フィールドのユーザー入力を検証する
  2. 外部 API から受け取った日付をチェックする
  3. データベース内の日付形式を一貫性を保つ
  4. 処理前のデータ検証

たとえば、フォーム検証関数では以下のように使用できます。

function validateForm(formData) {
  // Other validations...

  if (formData.startDate && !isISOString(formData.startDate)) {
    return {
      valid: false,
      error: "Start date must be in ISO format"
    };
  }

  // More validations...

  return { valid: true };
}

改善された関数は、予期しない入力を処理し、ISO 形式の日付文字列に対する信頼性の高い検証を提供するのに十分な堅牢性を備えています。

まとめ

この実験では、文字列が簡略化拡張 ISO 形式(ISO 8601)であるかどうかを検証する方法を学びました。以下はあなたが達成したことです。

  1. ISO 8601 日付形式とその構造について学びました。
  2. JavaScript の Date オブジェクトが ISO 形式の文字列とどのように動作するかを理解しました。
  3. 文字列が正確な ISO 形式であるかを検証する関数を作成しました。
  4. 様々な日付形式で関数をテストしました。
  5. エッジケースを処理するように関数を改善し、より堅牢なものにしました。

このスキルは、API、データベース、または日付形式の一貫性が重要なシステムで作業する際に特に有用です。ISO 8601 形式は、曖昧さを排除し、日付と時刻を表す標準化された方法を提供するため、広く使用されています。

この実験からの重要なポイントは以下の通りです。

  • ISO 8601 形式は特定のパターン YYYY-MM-DDTHH:mm:ss.sssZ に従います。
  • JavaScript の Date.prototype.toISOString() メソッドは常にこの形式で日付を出力します。
  • 日付の検証には、有効性と形式の両方をチェックする必要があります。
  • 適切なエラー処理により、検証関数がより堅牢になります。

これで、日付と時刻のデータを正しく処理する、より信頼性の高いアプリケーションを構築するためにこの知識を適用することができます。