[PHP]mktime関数の使い方と活用法 – 日付・時刻をUnixタイムスタンプに変換する完全ガイド

PHP

PHPで日付・時刻を扱う際に欠かせないmktime関数について、基本的な使い方から実際の活用例まで詳しく解説します。日付計算やタイムスタンプ操作をマスターして、より効率的な時間処理を実現しましょう。

mktime関数とは?

mktime(make time)は、指定した日付・時刻情報からUnixタイムスタンプを生成するPHPの関数です。Unixタイムスタンプとは、1970年1月1日 00:00:00 UTC からの経過秒数を表す整数値で、プログラムでの日付処理において標準的に使用されます。

基本構文

mktime(
    int $hour = null,
    int $minute = null, 
    int $second = null,
    int $month = null,
    int $day = null,
    int $year = null
): int|false

パラメータ:

  • $hour: 時(0-23)
  • $minute: 分(0-59)
  • $second: 秒(0-59)
  • $month: 月(1-12)
  • $day: 日(1-31)
  • $year: 年(1970-2038、32bit環境では制限あり)

戻り値:

  • 成功時:Unixタイムスタンプ(整数)
  • 失敗時:false

基本的な使用例

1. 特定の日付・時刻のタイムスタンプ取得

// 2024年3月15日 14:30:45のタイムスタンプ
$timestamp = mktime(14, 30, 45, 3, 15, 2024);
echo $timestamp; // 例: 1710505845

// 日付文字列として確認
echo date('Y-m-d H:i:s', $timestamp); // 2024-03-15 14:30:45

2. 現在時刻のタイムスタンプ取得

// 全パラメータを省略すると現在時刻
$now = mktime();
echo $now;

// time()関数と同じ結果
echo time(); // より効率的

3. 日付のみ指定(時刻は0時0分0秒)

// 2024年12月25日 00:00:00
$christmas = mktime(0, 0, 0, 12, 25, 2024);
echo date('Y-m-d H:i:s', $christmas); // 2024-12-25 00:00:00

実践的な活用例

1. 日付計算システム

class DateCalculator 
{
    /**
     * 指定日からN日後の日付を取得
     */
    public function addDays($year, $month, $day, $addDays) 
    {
        $baseTimestamp = mktime(0, 0, 0, $month, $day, $year);
        $newTimestamp = $baseTimestamp + ($addDays * 24 * 60 * 60);
        
        return [
            'timestamp' => $newTimestamp,
            'date' => date('Y-m-d', $newTimestamp),
            'formatted' => date('Y年m月d日', $newTimestamp)
        ];
    }
    
    /**
     * 月末日を取得
     */
    public function getLastDayOfMonth($year, $month) 
    {
        // 翌月の1日から1日引く
        $firstDayNextMonth = mktime(0, 0, 0, $month + 1, 1, $year);
        $lastDay = $firstDayNextMonth - (24 * 60 * 60);
        
        return date('Y-m-d', $lastDay);
    }
    
    /**
     * 年齢計算
     */
    public function calculateAge($birthYear, $birthMonth, $birthDay) 
    {
        $birthTimestamp = mktime(0, 0, 0, $birthMonth, $birthDay, $birthYear);
        $todayTimestamp = mktime(0, 0, 0);
        
        $ageInSeconds = $todayTimestamp - $birthTimestamp;
        $ageInYears = floor($ageInSeconds / (365.25 * 24 * 60 * 60));
        
        return $ageInYears;
    }
}

// 使用例
$calc = new DateCalculator();

// 30日後の日付
$future = $calc->addDays(2024, 3, 1, 30);
echo $future['formatted']; // 2024年03月31日

// 2024年2月の最終日
echo $calc->getLastDayOfMonth(2024, 2); // 2024-02-29(うるう年)

// 年齢計算
echo $calc->calculateAge(1990, 5, 15) . "歳";

2. イベント管理システム

class EventManager 
{
    private $events = [];
    
    public function addEvent($title, $year, $month, $day, $hour = 0, $minute = 0) 
    {
        $timestamp = mktime($hour, $minute, 0, $month, $day, $year);
        
        $this->events[] = [
            'title' => $title,
            'timestamp' => $timestamp,
            'date' => date('Y-m-d H:i', $timestamp),
            'is_past' => $timestamp < time()
        ];
        
        return $timestamp;
    }
    
    public function getUpcomingEvents($days = 30) 
    {
        $now = time();
        $futureLimit = $now + ($days * 24 * 60 * 60);
        
        $upcoming = array_filter($this->events, function($event) use ($now, $futureLimit) {
            return $event['timestamp'] >= $now && $event['timestamp'] <= $futureLimit;
        });
        
        // 日付順でソート
        usort($upcoming, function($a, $b) {
            return $a['timestamp'] <=> $b['timestamp'];
        });
        
        return $upcoming;
    }
    
    public function getEventsByMonth($year, $month) 
    {
        $monthStart = mktime(0, 0, 0, $month, 1, $year);
        $monthEnd = mktime(23, 59, 59, $month + 1, 0, $year);
        
        return array_filter($this->events, function($event) use ($monthStart, $monthEnd) {
            return $event['timestamp'] >= $monthStart && $event['timestamp'] <= $monthEnd;
        });
    }
}

// 使用例
$eventManager = new EventManager();

// イベント追加
$eventManager->addEvent('プロジェクト締切', 2024, 4, 15, 17, 0);
$eventManager->addEvent('会議', 2024, 3, 20, 10, 30);
$eventManager->addEvent('休暇', 2024, 5, 1);

// 今後30日のイベント取得
$upcoming = $eventManager->getUpcomingEvents(30);
foreach ($upcoming as $event) {
    echo $event['title'] . ': ' . $event['date'] . "\n";
}

3. 勤怠管理システム

class AttendanceSystem 
{
    /**
     * 営業日のみの日数計算(土日を除く)
     */
    public function getBusinessDays($startYear, $startMonth, $startDay, $endYear, $endMonth, $endDay) 
    {
        $startTimestamp = mktime(0, 0, 0, $startMonth, $startDay, $startYear);
        $endTimestamp = mktime(0, 0, 0, $endMonth, $endDay, $endYear);
        
        $businessDays = 0;
        $currentTimestamp = $startTimestamp;
        
        while ($currentTimestamp <= $endTimestamp) {
            $dayOfWeek = date('w', $currentTimestamp); // 0=日曜, 6=土曜
            if ($dayOfWeek !== '0' && $dayOfWeek !== '6') {
                $businessDays++;
            }
            $currentTimestamp += 24 * 60 * 60; // 1日進める
        }
        
        return $businessDays;
    }
    
    /**
     * 給与計算期間の開始・終了日取得
     */
    public function getPayrollPeriod($year, $month) 
    {
        // 例: 26日〜翌月25日が1つの給与期間
        if ($month === 12) {
            $startDate = mktime(0, 0, 0, $month, 26, $year);
            $endDate = mktime(0, 0, 0, 1, 25, $year + 1);
        } else {
            $startDate = mktime(0, 0, 0, $month, 26, $year);
            $endDate = mktime(0, 0, 0, $month + 1, 25, $year);
        }
        
        return [
            'start' => date('Y-m-d', $startDate),
            'end' => date('Y-m-d', $endDate),
            'start_timestamp' => $startDate,
            'end_timestamp' => $endDate
        ];
    }
}

// 使用例
$attendance = new AttendanceSystem();

// 営業日数計算
$businessDays = $attendance->getBusinessDays(2024, 3, 1, 2024, 3, 31);
echo "3月の営業日数: {$businessDays}日\n";

// 給与計算期間
$payroll = $attendance->getPayrollPeriod(2024, 3);
echo "給与期間: {$payroll['start']} 〜 {$payroll['end']}\n";

mktime関数の特殊な機能

1. 範囲外の値の自動調整

// 13月は翌年1月に自動調整
$timestamp = mktime(0, 0, 0, 13, 1, 2024);
echo date('Y-m-d', $timestamp); // 2025-01-01

// 32日は翌月に自動調整
$timestamp = mktime(0, 0, 0, 2, 32, 2024);
echo date('Y-m-d', $timestamp); // 2024-03-03

// 負の値で過去に遡ることも可能
$timestamp = mktime(0, 0, 0, 1, -10, 2024);
echo date('Y-m-d', $timestamp); // 2023-12-21

2. 相対的な日付計算

// 来月の同じ日
$nextMonth = mktime(0, 0, 0, date('n') + 1, date('j'), date('Y'));

// 3ヶ月前の同じ日
$threeMonthsAgo = mktime(0, 0, 0, date('n') - 3, date('j'), date('Y'));

// 来年の同じ日
$nextYear = mktime(0, 0, 0, date('n'), date('j'), date('Y') + 1);

echo date('Y-m-d', $nextMonth) . "\n";
echo date('Y-m-d', $threeMonthsAgo) . "\n";
echo date('Y-m-d', $nextYear) . "\n";

注意点とベストプラクティス

1. タイムゾーンの考慮

// デフォルトタイムゾーンを設定
date_default_timezone_set('Asia/Tokyo');

$timestamp = mktime(12, 0, 0, 6, 15, 2024);
echo date('Y-m-d H:i:s T', $timestamp); // 2024-06-15 12:00:00 JST

2. 32bit環境での制限

// 32bit環境では2038年問題に注意
if (PHP_INT_MAX === 2147483647) {
    echo "32bit環境: 2038年1月19日以降は扱えません\n";
} else {
    echo "64bit環境: より広い範囲の日付を扱えます\n";
}

3. 現代的な代替手段

// ❌ 古い方法
$old = mktime(12, 30, 45, 3, 15, 2024);

// ✅ 現代的な方法(PHP 5.2以降)
$new = DateTime::createFromFormat('Y-m-d H:i:s', '2024-03-15 12:30:45');
$timestamp = $new->getTimestamp();

// ✅ さらに簡潔な方法(PHP 5.3以降)
$newest = (new DateTime('2024-03-15 12:30:45'))->getTimestamp();

エラーハンドリング

function safeMktime($hour, $minute, $second, $month, $day, $year) 
{
    // 入力値の検証
    if (!is_numeric($year) || !is_numeric($month) || !is_numeric($day)) {
        throw new InvalidArgumentException('日付パラメータは数値である必要があります');
    }
    
    if ($month < 1 || $month > 12) {
        throw new OutOfRangeException('月は1-12の範囲で指定してください');
    }
    
    $timestamp = mktime($hour, $minute, $second, $month, $day, $year);
    
    if ($timestamp === false) {
        throw new RuntimeException('有効な日付を生成できませんでした');
    }
    
    return $timestamp;
}

try {
    $timestamp = safeMktime(25, 0, 0, 2, 29, 2023); // 無効な時刻
} catch (Exception $e) {
    echo 'エラー: ' . $e->getMessage();
}

まとめ

mktime関数は、PHPにおける日付・時刻処理の基礎となる重要な関数です。Unixタイムスタンプの生成を通じて、複雑な日付計算や時間比較を簡単に実現できます。

重要なポイント:

  • パラメータの順序に注意(時、分、秒、月、日、年)
  • 範囲外の値は自動調整される特性を活用
  • タイムゾーンとPHPの環境制限を考慮
  • 現代的な開発ではDateTimeクラスとの併用を検討
  • 適切なエラーハンドリングを実装

これらの知識を活用することで、より堅牢で効率的な日付処理システムを構築できるでしょう。

タイトルとURLをコピーしました