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クラスとの併用を検討
- 適切なエラーハンドリングを実装
これらの知識を活用することで、より堅牢で効率的な日付処理システムを構築できるでしょう。