Skip to main content
🕊️ កម្ពុជាត្រូវការសន្តិភាព CAMBODIA NEEDS PEACE 🇰🇭

យើងគាំទ្រដល់ទាហានខ្មែរទាំងអស់ដែលការពារទឹកដីជាតិ · We stand with our brave soldiers defending our homeland

Reference & usage guide

Documentation

Everything you need to integrate Khmer Lunar calendar conversions into your PHP or Laravel application.

Installation

Install the package via Composer:

composer require asorasoft/chhankitek

The only runtime dependency is nesbot/carbon, so the package works in any PHP project — Laravel is optional. Inside a Laravel application it automatically registers its service provider, so no additional configuration is needed.

Basic Usage

Using the Trait

In your Laravel controller, use the HasChhankitek trait:

use Asorasoft\Chhankitek\Traits\HasChhankitek;
use Carbon\CarbonImmutable;

class YourController extends Controller
{
    use HasChhankitek;

    public function index()
    {
        $lunarDate = $this->chhankitek(
            CarbonImmutable::now()->setTimezone('Asia/Phnom_Penh')
        );

        echo $lunarDate->toString();
        // ថ្ងៃច័ន្ទ ៤ រោច ខែបឋមាសាឍ ឆ្នាំឆ្លូវ ត្រីស័ក ពុទ្ធសករាជ ២៥៦៥
    }
}

Using the Helper Function

Alternatively, use the global toLunarDate helper:

use Carbon\CarbonImmutable;

$lunarDate = toLunarDate(
    CarbonImmutable::now()->setTimezone('Asia/Phnom_Penh')
);

echo $lunarDate->toString();

Important

Always use CarbonImmutable (not Carbon) and set the timezone to 'Asia/Phnom_Penh'.

Pure PHP Usage (without Laravel)

Laravel is not required. Instantiate Chhankitek directly and read the lunar date from the formatKhmerDate property:

require 'vendor/autoload.php';

use Asorasoft\Chhankitek\Chhankitek;
use Carbon\CarbonImmutable;

$target = CarbonImmutable::now()->setTimezone('Asia/Phnom_Penh');

$lunarDate = (new Chhankitek($target))->formatKhmerDate;

echo $lunarDate->toString();
// ថ្ងៃច័ន្ទ ៤ រោច ខែបឋមាសាឍ ឆ្នាំឆ្លូវ ត្រីស័ក ពុទ្ធសករាជ ២៥៦៥

The toLunarDate() helper is also available outside Laravel:

$lunarDate = toLunarDate(
    CarbonImmutable::now()->setTimezone('Asia/Phnom_Penh')
);

Without a Laravel application, conversions automatically use a framework-free in-memory cache. See Caching to plug in your own cache store.

Available Methods

The KhmerLunarDate object provides the following methods:

getDayOfWeek()

Returns the Khmer day of the week.

$lunarDate->getDayOfWeek(); // អាទិត្យ, ច័ន្ទ, អង្គារ, ពុធ, ព្រហស្បតិ៍, សុក្រ, សៅរ៍

getLunarDay()

Returns the lunar day with moon status (កើត waxing, រោច waning).

$lunarDate->getLunarDay(); // ១កើត, ២កើត, ១៤រោច, etc.

getLunarMonth()

Returns the Khmer lunar month name.

$lunarDate->getLunarMonth(); // ចេត្រ, ពិសាខ, ជេស្ឋ, អាសាឍ, etc.

getLunarZodiac()

Returns the animal year (Khmer zodiac).

$lunarDate->getLunarZodiac(); // ជូត, ឆ្លូវ, ខាល, ថោះ, រោង, ម្សាញ់, ...

getLunarEra()

Returns the era year (10-year cycle).

$lunarDate->getLunarEra(); // ត្រីស័ក, ចត្វាស័ក, បញ្ចស័ក, etc.

getLunarYear()

Returns the Buddhist Era year in Khmer numerals.

$lunarDate->getLunarYear(); // ២៥៦៥, ២៥៦៦, etc.

toString()

Returns the complete lunar date as a formatted string.

$lunarDate->toString();
// ថ្ងៃច័ន្ទ ៤ រោច ខែបឋមាសាឍ ឆ្នាំឆ្លូវ ត្រីស័ក ពុទ្ធសករាជ ២៥៦៥

Caching

Converted dates are cached for 365 days to minimize computational overhead. The cache is swappable via the CacheRepository interface, so it works the same with or without Laravel:

  • Inside Laravel — automatically uses Laravel's cache system (LaravelCache), respecting your configured driver (Redis, Memcached, file, etc.). No setup required.
  • Pure PHP — falls back to an in-memory cache (ArrayCache) that de-duplicates lookups within a single request or script run.

Providing your own cache

Pass any implementation of Asorasoft\Chhankitek\Cache\CacheRepository as the second constructor argument:

use Asorasoft\Chhankitek\Cache\ArrayCache;
use Asorasoft\Chhankitek\Cache\CacheRepository;
use Asorasoft\Chhankitek\Chhankitek;

// Use the bundled in-memory cache explicitly
$lunarDate = (new Chhankitek($target, new ArrayCache))->formatKhmerDate;

// Or wire up your own (e.g. a PSR-16 adapter)
final class Psr16Cache implements CacheRepository
{
    public function __construct(private \Psr\SimpleCache\CacheInterface $cache) {}

    public function remember(string $key, int $ttl, callable $callback): mixed
    {
        if ($this->cache->has($key)) {
            return $this->cache->get($key);
        }

        $value = $callback();
        $this->cache->set($key, $value, $ttl);

        return $value;
    }
}

Requirements

PHP ^8.2
Carbon nesbot/carbon ^2.0 | ^3.0 — the only required dependency
Laravel ^10.0 | ^11.0 | ^12.0 | ^13.0 (optional) — enables the facade, service provider, and persistent cache

Examples

Example 1 — Convert current date

$today = toLunarDate(
    CarbonImmutable::now()->setTimezone('Asia/Phnom_Penh')
);

echo "Day: " . $today->getDayOfWeek();
echo "Lunar Day: " . $today->getLunarDay();
echo "Month: " . $today->getLunarMonth();
echo "Year: " . $today->getLunarYear();

Example 2 — Convert specific date

$date = CarbonImmutable::createFromFormat(
    'Y-m-d',
    '2024-04-14'
)->setTimezone('Asia/Phnom_Penh');

$lunarDate = toLunarDate($date);
echo $lunarDate->toString();

Example 3 — Display in a Blade template

// In Controller
public function index()
{
    $lunarDate = toLunarDate(
        CarbonImmutable::now()->setTimezone('Asia/Phnom_Penh')
    );

    return view('welcome', compact('lunarDate'));
}

// In Blade (welcome.blade.php)
<div>
    <h1>{{ $lunarDate->toString() }}</h1>
    <p>Animal Year: {{ $lunarDate->getLunarZodiac() }}</p>
</div>

Example 4 — Using in an API

Route::get('/api/lunar-date', function (Request $request) {
    $date = $request->input('date')
        ? CarbonImmutable::parse($request->input('date'))
        : CarbonImmutable::now();

    $date = $date->setTimezone('Asia/Phnom_Penh');
    $lunarDate = toLunarDate($date);

    return response()->json([
        'gregorian' => $date->format('Y-m-d'),
        'lunar' => [
            'full' => $lunarDate->toString(),
            'day_of_week' => $lunarDate->getDayOfWeek(),
            'lunar_day' => $lunarDate->getLunarDay(),
            'month' => $lunarDate->getLunarMonth(),
            'zodiac' => $lunarDate->getLunarZodiac(),
            'era' => $lunarDate->getLunarEra(),
            'year' => $lunarDate->getLunarYear(),
        ],
    ]);
});

Understanding the Khmer Calendar

Lunar Months

The Khmer lunar calendar has 12 standard months. In leap years, an additional month (បឋមាសាឍ) is added:

មិគសិរ Mikasar
បុស្ស Boss
មាឃ Meak
ផល្គុន Phalguna
ចេត្រ Chaet
ពិសាខ Pisak
ជេស្ឋ Chet
អាសាឍ Asath
ស្រាពណ៍ Srapon
ភទ្របទ Phutrobot
អស្សុជ Assoch
កត្តិក Kadek

Lunar Days

Each lunar month is divided into two phases:

  • កើត (Kaet): Waxing moon (days 1–15)
  • រោច (Roch): Waning moon (days 1–15)

Zodiac Animals (12-year cycle)

ជូត Rat
ឆ្លូវ Ox
ខាល Tiger
ថោះ Rabbit
រោង Dragon
ម្សាញ់ Snake
មមី Horse
មមែ Goat
វក Monkey
រកា Rooster
Dog
កុរ Pig

Leap Years

The Khmer calendar has two types of leap years:

  • Leap Month Year (Adhikameas): An extra 13th month (បឋមាសាឍ) is added, making the year 384 days long.
  • Leap Day Year: An extra day is added to the month of ជេស្ឋ, making the year 355 days long.
  • Regular Year: 354 days with 12 months.

Learn more: Visit Khmer Calendar for detailed information about the system.

API Reference

Chhankitek Class

new Chhankitek(CarbonImmutable $target, ?CacheRepository $cache = null)

Framework-free entry point. The resulting lunar date is on the formatKhmerDate property. The optional CacheRepository defaults to Laravel's cache when an application is bound, otherwise an in-memory cache.

HasChhankitek Trait

chhankitek(CarbonImmutable $target, ?CacheRepository $cache = null): KhmerLunarDate

Converts a Gregorian date to Khmer lunar date format.

Helper Function

toLunarDate(CarbonImmutable $target, ?CacheRepository $cache = null): KhmerLunarDate

Global helper function for date conversion.

KhmerLunarDate Methods

Method Returns Description
getDayOfWeek()stringKhmer day of week
getLunarDay()stringLunar day with moon status
getLunarMonth()stringKhmer lunar month name
getLunarZodiac()stringAnimal year (zodiac)
getLunarEra()stringEra year (10-year cycle)
getLunarYear()stringBuddhist Era year (Khmer numerals)
toString()stringComplete formatted date string

Contributing

Contributions are welcome. Please see the CONTRIBUTING.md file for details.

Found a security issue? Please email mabhelitc@gmail.com instead of using the issue tracker.