Kotchasan Framework Documentation

Kotchasan Framework Documentation

Date Class - Date and Time Manipulation Utilities

EN 05 Feb 2026 02:15

Date Class - Date and Time Manipulation Utilities

The Date class provides utilities for date/time manipulation, age calculation, date formatting, and human-readable time conversion. Supports multiple languages including Thai (Buddhist Era) and localized month/day names.

Namespace

Kotchasan\Date

Overview

Date class provides methods for:

  • Calculating date differences (age, duration)
  • Formatting dates by language (supports BE/CE, Thai month/day names)
  • Converting dates to "time ago" format (5 minutes ago)
  • Parsing and validating date formats

API Reference

compare()

Calculate the difference between two dates, returning days, years, months, and days

public static function compare($begin_date, $end_date): array

Parameters:

  • $begin_date - Start date (Unix timestamp or Y-m-d format)
  • $end_date - End date (Unix timestamp or Y-m-d format)

Returns: ['days' => int, 'year' => int, 'month' => int, 'day' => int]

  • days - Total days (can be negative if begin_date > end_date)
  • year - Years
  • month - Months (0-11)
  • day - Days (0-30)

Example:

use Kotchasan\Date;

// Calculate age
$birthDate = '1990-05-15';
$age = Date::compare($birthDate, date('Y-m-d'));
echo "Age: {$age['year']} years {$age['month']} months {$age['day']} days";

// Unix timestamp
$start = strtotime('2024-01-01');
$end = time();
$duration = Date::compare($start, $end);
echo "Elapsed: {$duration['days']} days";

// Work duration
$hireDate = '2020-03-15';
$workDuration = Date::compare($hireDate, date('Y-m-d'));
echo "Tenure: {$workDuration['year']} years";

// Age check
if ($age['year'] >= 18) {
    echo "Adult";
}

// Expiry check
$expiryDate = '2025-12-31';
$remaining = Date::compare(date('Y-m-d'), $expiryDate);
if ($remaining['days'] > 0) {
    echo "{$remaining['days']} days remaining";
} else {
    echo "Expired";
}

age()

Return age as readable text (uses Language placeholders)

public static function age(string $date): string

Parameters:

  • $date - Birth date or start date

Returns: String format "X {LNG_year} Y {LNG_month} Z {LNG_days}"

Example:

use Kotchasan\Date;

// Display age
$birthDate = '1990-05-15';
echo Date::age($birthDate);
// "34 {LNG_year} 6 {LNG_month} 17 {LNG_days}"
// (Translates to: "34 years 6 months 17 days")

// With database
$users = $db->select('users', ['name', 'birth_date']);
foreach ($users as $user) {
    echo "{$user->name}: " . Date::age($user->birth_date);
}

// Membership duration
$member = $db->first("SELECT join_date FROM members WHERE id=?", [1]);
echo "Member for: " . Date::age($member->join_date);

timeDiff()

Calculate time difference in seconds

public static function timeDiff($firstTime, $lastTime): int

Parameters:

  • $firstTime - First time (string parseable by strtotime())
  • $lastTime - Last time (string parseable by strtotime())

Returns: Number of seconds (can be negative)

Example:

use Kotchasan\Date;

// Calculate duration
$start = '2024-12-01 10:00:00';
$end = '2024-12-01 10:05:30';
$seconds = Date::timeDiff($start, $end);
echo "Duration: {$seconds} seconds"; // 330

// Convert to minutes
$minutes = $seconds / 60;
echo "Duration: " . number_format($minutes, 2) . " minutes"; // 5.50

// Session duration
$session = $db->first("SELECT login_time, logout_time FROM sessions WHERE id=1");
$duration = Date::timeDiff($session->login_time, $session->logout_time);
echo "Session: " . gmdate("H:i:s", $duration);

// Time remaining
$deadline = '2024-12-31 23:59:59';
$timeLeft = Date::timeDiff(date('Y-m-d H:i:s'), $deadline);
$days = floor($timeLeft / 86400);
$hours = floor(($timeLeft % 86400) / 3600);
echo "Remaining: {$days} days {$hours} hours";

dateName()

Convert number (0-6) to day name in current language

public static function dateName(int $date, bool $short_date = true): string

Parameters:

  • $date - Number 0-6 (0=Sunday, 1=Monday, ..., 6=Saturday)
  • $short_date - true = short name (Sun, Mon), false = full name (Sunday, Monday)

Returns: Day name in configured language

Example:

use Kotchasan\Date;

// Short day names (default)
echo Date::dateName(0); // "Sun" (Sunday)
echo Date::dateName(1); // "Mon" (Monday)
echo Date::dateName(6); // "Sat" (Saturday)

// Full day names
echo Date::dateName(0, false); // "Sunday"
echo Date::dateName(1, false); // "Monday"

// Today
$today = date('w'); // 0-6
echo "Today: " . Date::dateName($today, false);

// Calendar header
for ($i = 0; $i < 7; $i++) {
    echo Date::dateName($i) . " ";
}
// "Sun Mon Tue Wed Thu Fri Sat"

// Appointments
$appointments = $db->select('appointments', ['appointment_date']);
foreach ($apt as $apt) {
    $dayNum = date('w', strtotime($apt->appointment_date));
    echo "Appt on " . Date::dateName($dayNum, false);
}

format()

Format date according to specified format (supports custom placeholders)

public static function format($time = 0, ?string $format = null): string

Parameters:

  • $time - Unix timestamp, date string, or 0 (= current time)
  • $format - Format (if not specified, uses DATE_FORMAT from Language)

Returns: Formatted date string

Custom Format Placeholders:

  • Y - Year in Buddhist Era (adds YEAR_OFFSET from Language, e.g. +543)
  • F - Full month name (January, ..., December)
  • M - Short month name (Jan, ..., Dec)
  • L - Full day name (Sunday, ..., Saturday)
  • l - Short day name (Sun, ..., Sat)
  • Others - Standard date() format (d, m, H, i, s, ...)

Example:

use Kotchasan\Date;

// Today (uses Language config format)
echo Date::format(); // Uses DATE_FORMAT

// Unix timestamp
$timestamp = strtotime('2024-12-01 15:30:00');
echo Date::format($timestamp, 'd/m/Y H:i');
// "01/12/2567 15:30" (if YEAR_OFFSET = 543)

// String date
echo Date::format('2024-12-01', 'd F Y');
// "01 December 2567"

// Full Thai format
echo Date::format(time(), 'l, d F Y');
// "Sunday, 03 February 2569"

// Time only
echo Date::format(time(), 'H:i:s'); // "20:10:00"

// Database data
$posts = $db->select('posts', ['title', 'created_at']);
foreach ($posts as $post) {
    $formatted = Date::format($post->created_at, 'd/m/Y H:i');
    echo "{$post->title} - {$formatted}";
}

// Short date
echo Date::format('2024-12-01', 'd M Y');
// "01 Dec 2567"

monthName()

Convert number (1-12) to month name in current language

public static function monthName(int $month, bool $short_month = true): string

Parameters:

  • $month - Number 1-12 (1=January, ..., 12=December)
  • $short_month - true = short name (Jan, Dec), false = full name (January, December)

Returns: Month name in configured language

Example:

use Kotchasan\Date;

// Short month names (default)
echo Date::monthName(1); // "Jan"
echo Date::monthName(12); // "Dec"

// Full month names
echo Date::monthName(1, false); // "January"
echo Date::monthName(12, false); // "December"

// Current month
$currentMonth = date('n'); // 1-12
echo "This month: " . Date::monthName($currentMonth, false);

// Month list
for ($m = 1; $m <= 12; $m++) {
    echo $m . ". " . Date::monthName($m, false) . "\n";
}

// Dropdown
echo '<select name="month">';
for ($i = 1; $i <= 12; $i++) {
    $name = Date::monthName($i, false);
    echo "<option value='{$i}'>{$name}</option>";
}
echo '</select>';

// Monthly report
$sales = $db->query("SELECT MONTH(sale_date) as m, SUM(amount) as total
                     FROM sales GROUP BY m");
foreach ($sales as $row) {
    $monthName = Date::monthName($row->m, false);
    echo "{$monthName}: " . number_format($row->total);
}

parse()

Parse date string into array of components

public static function parse(string $date): array|false

Parameters:

  • $date - Date string in YYYY-MM-DD or YYYY-MM-DD HH:II:SS format

Returns: Array ['y', 'm', 'd', 'h', 'i', 's'] or false (invalid format)

Example:

use Kotchasan\Date;

// Parse date
$parsed = Date::parse('2024-12-01');
print_r($parsed);
// ['y' => '2024', 'm' => '12', 'd' => '01']

// Parse datetime
$parsed = Date::parse('2024-12-01 15:30:45');
print_r($parsed);
// ['y' => '2024', 'm' => '12', 'd' => '01',
//  'h' => '15', 'i' => '30', 's' => '45']

// Validate user input
$userDate = $_POST['date'] ?? '';
$parsed = Date::parse($userDate);

if ($parsed) {
    echo "Year: {$parsed['y']}, Month: {$parsed['m']}, Day: {$parsed['d']}";

    if (isset($parsed['h'])) {
        echo ", Time: {$parsed['h']}:{$parsed['i']}";
    }
} else {
    echo "Invalid date format";
}

// Validation
function validateDate($dateStr) {
    $parsed = Date::parse($dateStr);
    if (!$parsed) return false;

    return checkdate($parsed['m'], $parsed['d'], $parsed['y']);
}

if (validateDate('2024-02-30')) {
    echo "Valid date";
} else {
    echo "Invalid date"; // ← Will get this
}

// Convert format
$parsed = Date::parse('2024-12-01');
if ($parsed) {
    $timestamp = mktime(0, 0, 0, $parsed['m'], $parsed['d'], $parsed['y']);
    echo date('d/m/Y', $timestamp); // "01/12/2024"
}

timeAgo()

Convert date to human-readable "time ago" format

public static function timeAgo(string $date): string

Parameters:

  • $date - Date to convert

Returns: String format "{N} {LNG_unit} {LNG_ago}" or "{LNG_now}"

Time Units (in order):

  • Years: {N} {LNG_year} {LNG_ago}
  • Months: {N} {LNG_month} {LNG_ago}
  • Weeks: {N} {LNG_week} {LNG_ago} (> 7 days)
  • Days: {N} {LNG_days} {LNG_ago} (> 2 days)
  • Hours: {N} {LNG_hours} {LNG_ago}
  • Minutes: {N} {LNG_minutes} {LNG_ago}
  • Now: {LNG_now} (< 1 minute)

Example:

use Kotchasan\Date;

// 5 minutes ago
echo Date::timeAgo('2024-12-01 10:00:00');
// "5 {LNG_minutes} {LNG_ago}" → "5 minutes ago"

// 2 hours ago
echo Date::timeAgo('2024-12-01 08:00:00');
// "2 {LNG_hours} {LNG_ago}" → "2 hours ago"

// 1 month ago
echo Date::timeAgo('2024-11-01');
// "1 {LNG_month} {LNG_ago}" → "1 month ago"

// Social posts
$posts = $db->select('posts', ['content', 'created_at']);
foreach ($posts as $post) {
    echo "<div>";
    echo "<p>{$post->content}</p>";
    echo "<small>" . Date::timeAgo($post->created_at) . "</small>";
    echo "</div>";
}

// Comments
$comments = $db->select('comments', ['comment', 'created_at']);
foreach ($comments as $comment) {
    $timeAgo = Date::timeAgo($comment->created_at);
    echo "{$comment->comment} - {$timeAgo}";
}

// Notifications
$notifications = $db->select('notifications',
    ['message', 'created_at'],
    ['user_id' => $userId]
);
foreach ($notifications as $notif) {
    echo "<div class='notification'>";
    echo "{$notif->message} ({Date::timeAgo($notif->created_at)})";
    echo "</div>";
}

Real-World Examples

1. Membership System

use Kotchasan\Date;

class MemberSystem
{
    public function getMemberInfo($memberId)
    {
        global $db;
        $member = $db->first("SELECT * FROM members WHERE id=?", [$memberId]);

        $age = Date::compare($member->birth_date, date('Y-m-d'));
        $memberSince = Date::compare($member->join_date, date('Y-m-d'));

        return [
            'name' => $member->name,
            'age' => $age['year'] . ' years',
            'age_text' => Date::age($member->birth_date),
            'member_since' => Date::format($member->join_date, 'd F Y'),
            'membership_years' => $memberSince['year'],
            'is_adult' => $age['year'] >= 18,
            'last_login' => Date::timeAgo($member->last_login)
        ];
    }
}

2. Sales Report

class SalesReport
{
    public function getDailySales($date)
    {
        global $db;
        $sales = $db->select('sales', '*', ['DATE(created_at)' => $date]);

        $dayNum = date('w', strtotime($date));

        return [
            'date' => Date::format($date, 'd F Y'),
            'day_name' => Date::dateName($dayNum, false),
            'total_sales' => count($sales),
            'sales' => array_map(function($sale) {
                return [
                    'amount' => number_format($sale->amount, 2),
                    'time' => Date::format($sale->created_at, 'H:i'),
                    'time_ago' => Date::timeAgo($sale->created_at)
                ];
            }, $sales)
        ];
    }
}

3. Booking System

class BookingSystem
{
    public function checkAvailability($date)
    {
        $dayOfWeek = date('w', strtotime($date));

        // Check weekend
        if ($dayOfWeek == 0 || $dayOfWeek == 6) {
            return [
                'available' => false,
                'reason' => Date::dateName($dayOfWeek, false) . ' - Closed'
            ];
        }

        return [
            'available' => true,
            'date' => Date::format($date, 'l, d F Y'),
            'day_name' => Date::dateName($dayOfWeek, false)
        ];
    }

    public function canCancelBooking($bookingDate)
    {
        $diff = Date::compare($bookingDate, date('Y-m-d'));
        return [
            'can_cancel' => $diff['days'] < 7,
            'days_until' => $diff['days'],
            'message' => "Booked " . Date::timeAgo($bookingDate)
        ];
    }
}

4. Employee System

class EmployeeSystem
{
    public function calculateRetirement($birthDate)
    {
        $retirementAge = 60;
        $currentAge = Date::compare($birthDate, date('Y-m-d'));
        $yearsToRetirement = $retirementAge - $currentAge['year'];

        if ($yearsToRetirement > 0) {
            return "Retirement in {$yearsToRetirement} years";
        }

        return "Retired";
    }

    public function getWorkDuration($hireDate)
    {
        $duration = Date::compare($hireDate, date('Y-m-d'));

        return [
            'years' => $duration['year'],
            'months' => $duration['month'],
            'days' => $duration['day'],
            'total_days' => $duration['days'],
            'text' => Date::age($hireDate),
            'is_senior' => $duration['year'] >= 5
        ];
    }
}

Best Practices

1. Use compare() for Calculations

// ✅ Good - comprehensive data
$diff = Date::compare($start, $end);
echo "{$diff['year']} years {$diff['month']} months";

// ❌ Bad - manual calculation, inaccurate
$y1 = date('Y', strtotime($start));
$y2 = date('Y', strtotime($end));
echo ($y2 - $y1) . " years"; // Inaccurate

2. Use format() for Display

// ✅ Good - multi-language support
echo Date::format($date, 'd F Y'); // "01 December 2567"

// ❌ Bad - hardcoded language
echo date('d', $timestamp) . " December " . (date('Y', $timestamp) + 543);

3. Use timeAgo() for Social Features

// ✅ Good - user-friendly
echo Date::timeAgo($post->created_at); // "5 minutes ago"

// ❌ Bad - raw timestamp
echo $post->created_at; // "2024-12-01 10:00:00" (hard to read)

4. Validate with parse()

// ✅ Good - validate before use
$parsed = Date::parse($_POST['date']);
if ($parsed && checkdate($parsed['m'], $parsed['d'], $parsed['y'])) {
    // Safe
}

// ❌ Bad - direct use
$date = strtotime($_POST['date']); // Dangerous!

Important Considerations

[!WARNING]
Language Dependency: Methods dateName(), monthName(), format() require Language class to be configured

[!NOTE]
YEAR_OFFSET: Buddhist Era uses YEAR_OFFSET = 543 from Language config

[!IMPORTANT]
parse() supports only: YYYY-MM-DD and YYYY-MM-DD HH:II:SS formats

[!TIP]
timeDiff() vs compare(): Use timeDiff() for seconds, compare() for years/months/days

Summary

Date class has 8 main methods:

  1. compare() - Calculate date difference (returns days, year, month, day)
  2. age() - Convert to age text (X years Y months Z days)
  3. timeDiff() - Calculate in seconds
  4. dateName() - Day names (Sunday-Saturday)
  5. format() - Format dates (supports BE/Thai names)
  6. monthName() - Month names (January-December)
  7. parse() - Parse date components
  8. timeAgo() - Convert to "time ago" (5 minutes ago)

Perfect for:

  • Membership systems (age calculation)
  • Reports (date formatting)
  • Social media (time ago)
  • Calendars (day/month names)