開発情報・ナレッジ

投稿者: ShiningStar株式会社 2025年10月20日 (月)

SPIRALライブラリで取得した日付処理を楽にするPHPお役立ち関数セット

SPIRALのPHPライブラリで取得したレコードの日付や時刻フィールド、
「そのままでは比較しづらい」「曜日や和暦を手軽に表示したい」と感じたことはありませんか?
この記事では、日付・時刻処理を便利にする、コピペで使えるPHPのお役立ち関数セットを紹介します。
APIの戻り値をPHPの標準的な日付オブジェクトに変換することで、より柔軟な操作が可能になります。

この関数で出来ること

  • 日本語日付文字列を、PHPの標準日付オブジェクトに変換
  • 曜日、和暦、12時間表記(午前/午後)の取得
  • 「3時間前」「5日後」のような相対時間の計算
  • 週末(土日)かどうかの判定

実装の概要

1. PHPスクリプト上部の設定エリアで、ご自身のDBのフィールド識別名を指定します。
2. 提供するPHPコードを、APIでレコードを取得するPHPファイルにコピー&ペーストします。
3. あとは、サンプルコードを参考に、使いたい関数を呼び出すだけです。

お役立ち関数コード

以下のPHPコードを、お使いのPHPスクリプトの任意の位置にコピーして貼り付けてください。

コピー
//------------------------------
// 日付・時刻お役立ち関数
//------------------------------

/**
 * SPIRALから取得した日本語の日付・時刻文字列を DateTimeImmutable オブジェクトに変換します。
 * この関数がライブラリの基本となります。
 */
function parseSpiralV1DateTime(?string $value): ?DateTimeImmutable
{
    if ($value === null || $value === '') {
        return null;
    }

    try {
        $normalizedValue = $value;
        // 日本語の単位を削除し、標準的なフォーマットに近づける
        $replacements = [
            '年' => '-', '月' => '-', '日' => '',
            '時' => ':', '分' => ':', '秒' => ''
        ];
        $normalizedValue = str_replace(array_keys($replacements), array_values($replacements), $normalizedValue);
        $normalizedValue = preg_replace('/\s+/u', ' ', $normalizedValue);
        $normalizedValue = trim($normalizedValue);
        $normalizedValue = rtrim($normalizedValue, '-:');

        // 「10-7」のような月日形式の場合、年を補う
        if (preg_match('/^\d{1,2}-\d{1,2}$/', $normalizedValue)) {
             return new DateTimeImmutable(date('Y') . '-' . $normalizedValue);
        }

        // 「2025-10」のような年月形式の場合、日を補う
        if (preg_match('/^\d{4}-\d{1,2}$/', $normalizedValue)) {
             return new DateTimeImmutable($normalizedValue . '-01');
        }

        if (preg_match('/^\d{4}-\d{1,2}-\d{1,2}$/', $normalizedValue)) {
            $normalizedValue .= ' 00:00:00';
        } elseif (preg_match('/^\d{4}-\d{1,2}-\d{1,2} \d{1,2}$/', $normalizedValue)) {
            $normalizedValue .= ':00:00';
        } elseif (preg_match('/^\d{4}-\d{1,2}-\d{1,2} \d{1,2}:\d{1,2}$/', $normalizedValue)) {
            $normalizedValue .= ':00';
        } elseif (preg_match('/^\d{1,2}$/', $normalizedValue)) {
            $normalizedValue .= ':00';
        }

        return new DateTimeImmutable($normalizedValue);

    } catch (Exception $e) {
        return null;
    }
}
/**
 * 西暦の日付を和暦(元号)形式の文字列に変換します。
 */
function getJapaneseEra(?DateTimeImmutable $dateObj): ?string
{
    if ($dateObj === null) return null;

    $eras = [
        ['name' => '令和', 'start_date' => '2019-05-01'],
        ['name' => '平成', 'start_date' => '1989-01-08'],
        ['name' => '昭和', 'start_date' => '1926-12-25'],
        ['name' => '大正', 'start_date' => '1912-07-30'],
        ['name' => '明治', 'start_date' => '1868-01-25'],
    ];

    $year = (int)$dateObj->format('Y');
    $month = (int)$dateObj->format('m');
    $day = (int)$dateObj->format('d');

    foreach ($eras as $era) {
        $eraStartDate = new DateTimeImmutable($era['start_date']);
        if ($dateObj >= $eraStartDate) {
            $eraYear = $year - (int)$eraStartDate->format('Y') + 1;
            $eraYearStr = ($eraYear === 1) ? '元' : (string)$eraYear;
            return sprintf('%s%s年%d月%d日', $era['name'], $eraYearStr, $month, $day);
        }
    }

    return $dateObj->format('Y年m月d日');
}

/**
 * 指定された日時文字列と現在時刻との差を相対時間で返します。
 */
function getRelativeTime(?DateTimeImmutable $dateObj, string $timezone = 'Asia/Tokyo'): ?string
{
    if ($dateObj === null) return null;

    $now = new DateTimeImmutable('now', new DateTimeZone($timezone));
    $diff = $now->diff($dateObj);
    $isPast = $diff->invert === 1;
    $unit = $isPast ? '前' : '後';

    if ($diff->y > 0) return $diff->y . '年' . $unit;
    if ($diff->m > 0) return $diff->m . 'ヶ月' . $unit;
    if ($diff->d > 0) return $diff->d . '日' . $unit;
    if ($diff->h > 0) return $diff->h . '時間' . $unit;
    if ($diff->i > 0) return $diff->i . '分' . $unit;

    return 'たった今';
}
                
2. 関数の呼び出し
PHPライブラリで取得したレコードリスト(
$result
)をループ処理し、中で各関数を呼び出します。
月日や時刻など、既に目的の形式で取得できている項目は、そのまま利用するのが効率的です。
//------------------------------
// お役立ち関数の利用例
//------------------------------

echo "<pre>";
echo "--- APIレスポンスをループ処理して日付をフォーマットする例 ---\n";

if (isset($result['count']) && $result['count'] > 0) {
    foreach ($result['data'] as $record) {
        echo "\n--- Record ID: " . $record['id'] . " ---\n";

        // --- オブジェクトに変換して処理する例 ---
        
        // 曜日を取得する
        $dateObj = parseSpiralV1DateTime($record[DATE_FULL_FIELD]);
        $week = ['日', '月', '火', '水', '木', '金', '土'];
        $dayOfWeek = $week[(int)$dateObj->format('w')];
        echo "曜日                  : (" . $dayOfWeek . ")\n";

        // 和暦に変換する
        $japaneseEra = getJapaneseEra($dateObj);
        echo "日付 (和暦)           : " . $japaneseEra . "\n";

        // 週末かどうか判定する
        $dayOfWeekInt = (int)$dateObj->format('w');
        $isWeekend = ($dayOfWeekInt === 0 || $dayOfWeekInt === 6);
        echo "週末判定              : " . ($isWeekend ? '週末です' : '平日です') . "\n";

        // 午前/午後 をつけて表示する
        $dateTimeObj = parseSpiralV1DateTime($record[DATETIME_MIN_FIELD]);
        $am_pm = ((int)$dateTimeObj->format('G') < 12) ? '午前' : '午後';
        echo "日時 (12時間表記)     : " . $dateTimeObj->format('Y/m/d ') . $am_pm . $dateTimeObj->format(' g:i') . "\n";

        // 相対時間を表示する
        $relativeTime = getRelativeTime($dateTimeObj);
        echo "日時 (相対)           : " . $relativeTime . "\n";
    }
} else {
    echo "レコードが見つかりませんでした。";
}

echo "</pre>";
            

実行結果

上記のサンプルコードを実行すると、以下のような結果が出力されます。

--- APIレスポンスをループ処理して日付をフォーマットする例 ---
--- Record ID: 1 ---
曜日                  : (火)
日付 (和暦)           : 令和7年10月7日
週末判定              : 平日です
日時 (12時間表記)     : 2025/10/07 午後 3:35
日時 (相対)           : 1時間前

--- Record ID: 2 ---
曜日                  : (金)
日付 (和暦)           : 平成13年12月21日
週末判定              : 平日です
日時 (12時間表記)     : 2001/12/21 午前 12:00
日時 (相対)           : 23年前
            

サンプルコード全文

<?php

//------------------------------
// フィールド名設定
//------------------------------
// ご自身のDBで利用しているフィールド識別名に合わせて書き換えてください
define("DATETIME_FULL_FIELD", "datetime_full"); //日付(○年○月○日 ○時○分○秒)
define("DATETIME_MIN_FIELD", "datetime_min"); //日付(○年○月○日 ○時○分)
define("DATETIME_HOUR_FIELD", "datetime_hour"); //日付(○年○月○日 ○時)
define("DATE_FULL_FIELD", "date_full"); //日付(○年○月○日)
define("DATE_MONTH_FIELD", "date_month"); //日付(○年○月)
define("MONTH_DAY_FIELD", "month_day"); //月日(○月○日)
define("TIME_ONLY_FIELD", "time_only"); //時刻(○時○分)

     $db = $SPIRAL->getDataBase("db_name");
     $db->addSelectFields(
        "id",
         DATETIME_FULL_FIELD, 
         DATETIME_MIN_FIELD, 
         DATETIME_HOUR_FIELD, 
         DATE_FULL_FIELD, 
         DATE_MONTH_FIELD, 
         MONTH_DAY_FIELD, 
         TIME_ONLY_FIELD
     );
     $db->setLinesPerPage(500);
     $result = $db->doSelect();
     

//------------------------------
// 日付・時刻お役立ち関数
//------------------------------

/**
 * SPIRALから取得した日本語の日付・時刻文字列を DateTimeImmutable オブジェクトに変換します。
 * この関数がライブラリの基本となります。
 */
function parseSpiralV1DateTime(?string $value): ?DateTimeImmutable
{
    if ($value === null || $value === '') {
        return null;
    }

    try {
        $normalizedValue = $value;
        // 日本語の単位を削除し、標準的なフォーマットに近づける
        $replacements = [
            '年' => '-', '月' => '-', '日' => '',
            '時' => ':', '分' => ':', '秒' => ''
        ];
        $normalizedValue = str_replace(array_keys($replacements), array_values($replacements), $normalizedValue);
        $normalizedValue = preg_replace('/\s+/u', ' ', $normalizedValue);
        $normalizedValue = trim($normalizedValue);
        $normalizedValue = rtrim($normalizedValue, '-:');

        // 「10-7」のような月日形式の場合、年を補う
        if (preg_match('/^\d{1,2}-\d{1,2}$/', $normalizedValue)) {
             return new DateTimeImmutable(date('Y') . '-' . $normalizedValue);
        }

        // 「2025-10」のような年月形式の場合、日を補う
        if (preg_match('/^\d{4}-\d{1,2}$/', $normalizedValue)) {
             return new DateTimeImmutable($normalizedValue . '-01');
        }

        if (preg_match('/^\d{4}-\d{1,2}-\d{1,2}$/', $normalizedValue)) {
            $normalizedValue .= ' 00:00:00';
        } elseif (preg_match('/^\d{4}-\d{1,2}-\d{1,2} \d{1,2}$/', $normalizedValue)) {
            $normalizedValue .= ':00:00';
        } elseif (preg_match('/^\d{4}-\d{1,2}-\d{1,2} \d{1,2}:\d{1,2}$/', $normalizedValue)) {
            $normalizedValue .= ':00';
        } elseif (preg_match('/^\d{1,2}$/', $normalizedValue)) {
            $normalizedValue .= ':00';
        }

        return new DateTimeImmutable($normalizedValue);

    } catch (Exception $e) {
        return null;
    }
}

/**
 * 西暦の日付を和暦(元号)形式の文字列に変換します。
 */
function getJapaneseEra(?DateTimeImmutable $dateObj): ?string
{
    if ($dateObj === null) return null;

    $eras = [
        ['name' => '令和', 'start_date' => '2019-05-01'],
        ['name' => '平成', 'start_date' => '1989-01-08'],
        ['name' => '昭和', 'start_date' => '1926-12-25'],
        ['name' => '大正', 'start_date' => '1912-07-30'],
        ['name' => '明治', 'start_date' => '1868-01-25'],
    ];

    $year = (int)$dateObj->format('Y');
    $month = (int)$dateObj->format('m');
    $day = (int)$dateObj->format('d');

    foreach ($eras as $era) {
        $eraStartDate = new DateTimeImmutable($era['start_date']);
        if ($dateObj >= $eraStartDate) {
            $eraYear = $year - (int)$eraStartDate->format('Y') + 1;
            $eraYearStr = ($eraYear === 1) ? '元' : (string)$eraYear;
            return sprintf('%s%s年%d月%d日', $era['name'], $eraYearStr, $month, $day);
        }
    }

    return $dateObj->format('Y年m月d日');
}

/**
 * 指定された日時文字列と現在時刻との差を相対時間で返します。
 */
function getRelativeTime(?DateTimeImmutable $dateObj, string $timezone = 'Asia/Tokyo'): ?string
{
    if ($dateObj === null) return null;

    $now = new DateTimeImmutable('now', new DateTimeZone($timezone));
    $diff = $now->diff($dateObj);
    $isPast = $diff->invert === 1;
    $unit = $isPast ? '前' : '後';

    if ($diff->y > 0) return $diff->y . '年' . $unit;
    if ($diff->m > 0) return $diff->m . 'ヶ月' . $unit;
    if ($diff->d > 0) return $diff->d . '日' . $unit;
    if ($diff->h > 0) return $diff->h . '時間' . $unit;
    if ($diff->i > 0) return $diff->i . '分' . $unit;

    return 'たった今';
}


//------------------------------
// お役立ち関数の利用例
//------------------------------

echo "<pre>";
echo "--- APIレスポンスをループ処理して日付をフォーマットする例 ---\n";

if (isset($result['count']) && $result['count'] > 0) {
    foreach ($result['data'] as $record) {
        echo "\n--- Record ID: " . $record['id'] . " ---\n";

        // --- オブジェクトに変換して処理する例 ---
        
        // 曜日を取得する
        $dateObj = parseSpiralV1DateTime($record[DATE_FULL_FIELD]);
        $week = ['日', '月', '火', '水', '木', '金', '土'];
        $dayOfWeek = $week[(int)$dateObj->format('w')];
        echo "曜日                  : (" . $dayOfWeek . ")\n";

        // 和暦に変換する
        $japaneseEra = getJapaneseEra($dateObj);
        echo "日付 (和暦)           : " . $japaneseEra . "\n";

        // 週末かどうか判定する
        $dayOfWeekInt = (int)$dateObj->format('w');
        $isWeekend = ($dayOfWeekInt === 0 || $dayOfWeekInt === 6);
        echo "週末判定              : " . ($isWeekend ? '週末です' : '平日です') . "\n";

        // 午前/午後 をつけて表示する
        $dateTimeObj = parseSpiralV1DateTime($record[DATETIME_MIN_FIELD]);
        $am_pm = ((int)$dateTimeObj->format('G') < 12) ? '午前' : '午後';
        echo "日時 (12時間表記)     : " . $dateTimeObj->format('Y/m/d ') . $am_pm . $dateTimeObj->format(' g:i') . "\n";

        // 相対時間を表示する
        $relativeTime = getRelativeTime($dateTimeObj);
        echo "日時 (相対)           : " . $relativeTime . "\n";
    }
} else {
    echo "レコードが見つかりませんでした。";
}

echo "</pre>";

?>

            

まとめ

本記事では、SPIRALのPHPライブラリから取得した日付・時刻フィールドをPHPの標準日付オブジェクトに変換し、柔軟に扱うための関数セットを紹介しました。
ぜひ、ご自身のプロジェクトに合わせてカスタマイズしてご活用ください。
不具合やご質問がある場合は、下記の「コンテンツに関しての要望はこちら」からご連絡ください。
解決しない場合はこちら コンテンツに関しての
要望はこちら