In a year, has 24 terms of Solar term system. It should be noted that weather conditions are based on the relative position of the Earth compared to the Sun, using the Sun's Ecliptic Longitude algorithm to calculate, not related to the Moon.
The lunar-calendar provide a SolarTerm class to work with the Solar term. Before going into details, see the table below to grasp the 24 solar terms with their basic properties. From version 3.x, the Solar term is formatted in English, to improve standardization.
Term's name | Term's key | Position | Category | Solar longitude |
---|---|---|---|---|
Beginning of Spring | begin_spring | 0 | J | 315 |
Rain Water | rain_water | 1 | Z | 330 |
Awakening of Insects | awaken_insects | 2 | J | 345 |
Spring Equinox | spring_equinox | 3 | Z | 0 |
Pure Brightness | pure_brightness | 4 | J | 15 |
Grain Rain | grain_rain | 5 | Z | 30 |
Beginning of Summer | begin_summer | 6 | J | 45 |
Grain Buds | grain_buds | 7 | Z | 60 |
Grain in Ear | grain_in_ear | 8 | J | 75 |
Summer Solstice | summer_solstice | 9 | Z | 90 |
Minor Heat | minor_heat | 10 | J | 105 |
Major heat | major_heat | 11 | Z | 120 |
Beginning of Autumn | begin_autumn | 12 | J | 135 |
End of Heat | end_of_heat | 13 | Z | 150 |
White Dew | white_dew | 14 | J | 165 |
Autumn Equinox | autumn_equinox | 15 | Z | 180 |
Cold Dew | cold_dew | 16 | J | 195 |
Frost's Descent | frost_descent | 17 | Z | 210 |
Beginning of Winter | begin_winter | 18 | J | 225 |
Minor Snow | minor_snow | 19 | Z | 240 |
Major Snow | major_snow | 20 | J | 255 |
Winter Solstice | winter_solstice | 21 | Z | 270 |
Minor Cold | minor_cold | 22 | J | 285 |
Major Cold | major_cold | 23 | Z | 300 |
The __constructor
of the SolarTerm class requires a Unix timestamp as the calculation point. By default, the milestone of initialization will be used. Inside app.php
try the code below, then run the command php ./app.php
with terminal:
app.php
<?php
use LucNham\LunarCalendar\SolarTerm;
require_once('./vendor/autoload.php');
$solarTerm = new SolarTerm();
print_r($solarTerm->getTerm());
Results:
LucNham\LunarCalendar\Terms\SolarTermIdentifier Object
(
[key] => frost_descent
[name] => Frost's Descent
[position] => 17
[type] => Z
[ls] => 210
)
SolarTerm also supports 2 static methods to initialize term:
SolarTerm::now()
: Returns the current term, tương tự nhưnew SolarTerm()
SolarTerm::fromDate()
: Returns the term corresponding to a Lunar or Gregorian milestone.
You can try the following code:
app.php
<?php
use LucNham\LunarCalendar\LunarDateTime;
use LucNham\LunarCalendar\SolarTerm;
require_once('./vendor/autoload.php');
$date = new DateTime('1970-01-01');
$lunar = new LunarDateTime('2000-10-30');
print_r(
[
"From Date________" => SolarTerm::fromDate($date)->name,
"From Lunar Date__" => SolarTerm::fromDate($lunar)->name,
"Now______________" => SolarTerm::now()->name
]
);
Results:
Array
(
[From Date________] => Winter Solstice
[From Lunar Date__] => Minor Snow
[Now______________] => Frost's Descent
)
The SolarTerm class allows direct access to the identifier properties of the current term via the magic __get
:
app.php
<?php
use LucNham\LunarCalendar\SolarTerm;
require_once('./vendor/autoload.php');
$s = new SolarTerm();
print_r(
[
"Term's name____________________________________" => $s->name,
"Term's unique key in group_____________________" => $s->key,
"Term's unique position (order) in group________" => $s->position,
"Term's Solar longitude angle of beginning point" => $s->ls,
"term's type betwen (J) and (Z)_________________" => $s->type,
"Term's Solar longitute angle of current point__" => $s->angle,
"Term's Unix timestamp of the beginning point___" => $s->begin,
]
);
Results:
Array
(
[Term's name____________________________________] => Frost's Descent
[Term's unique key in group_____________________] => frost_descent
[Term's unique position (order) in group________] => 17
[Term's Solar longitude angle of beginning point] => 210
[term's type betwen (J) and (Z)_________________] => Z
[Term's Solar longitute angle of current point__] => 214.593
[Term's Unix timestamp of the beginning point___] => 1729635007
)
To get the starting position of the current term, you can use the begin
property or the getBeginTimestamp()
method.
Both methods above return the same Unix timestamp of the starting point of the term, which you can then use for different purposes. The following example prints information related to the starting point of the term at the '2024-10-20' Lunar date:
app.php
<?php
use LucNham\LunarCalendar\Converters\DateTimeIntervalToDateTimeString;
use LucNham\LunarCalendar\Converters\JdToGregorian;
use LucNham\LunarCalendar\Converters\UnixToJd;
use LucNham\LunarCalendar\LunarDateTime;
use LucNham\LunarCalendar\SolarTerm;
require_once('./vendor/autoload.php');
$lunar = new LunarDateTime('2024-10-20 +0700');
$solarTerm = SolarTerm::fromDate($lunar);
// A bit of fun interacting with the date time converters to get the Gregorian string corresponding
// to the start of the term, although you can always use other methods.
$date = (new UnixToJd($solarTerm->begin))
->setOffset($lunar->getOffset())
->then(JdToGregorian::class)
->then(DateTimeIntervalToDateTimeString::class)
->getOutput();
print_r(
[
'Lunar date input____________________________________________' => $lunar->format('Y-m-d H:i:s P k'),
'The Gregorian corresponds to the Lunar______________________' => $lunar->toDateTimeString(),
'The Term corresponds to the Lunar___________________________' => $solarTerm->name,
'Unix timestamp of beginning point___________________________' => $solarTerm->getBeginTimestamp(),
'The Gregorian corresponds to the beginning point of the term' => $date
]
);
Results:
Array
(
[Lunar date input____________________________________________] => 2024-10-20 00:00:00 +07:00
[The Gregorian corresponds to the Lunar______________________] => 2024-11-20 00:00:00 +07:00
[The Term corresponds to the Lunar___________________________] => Beginning of Winter
[Unix timestamp of beginning point___________________________] => 1730931582
[The Gregorian corresponds to the beginning point of the term] => 2024-11-07 05:19:42 +07:00
)
From the current term, you can move to the previous term via the previous()
method, or the next term via the next()
method. These two methods return a new instance of the SolarTerm class, so you can use all the features mentioned in this section.
app.php
<?php
use LucNham\LunarCalendar\LunarDateTime;
use LucNham\LunarCalendar\SolarTerm;
require_once('./vendor/autoload.php');
$current = SolarTerm::fromDate(new LunarDateTime('2024-01-01 +0700'));
$next = $current->next();
$prev = $current->previous();
print_r(
[
'Current term_____' => "{$current->position}. {$current->name}",
'Previous term____' => "{$prev->position}. {$prev->name}",
'Next term________' => "{$next->position}. {$next->name}",
]
);
Results:
Array
(
[Current term_____] => 0. Beginning of Spring
[Previous term____] => 23. Major Cold
[Next term________] => 1. Rain Water
)
By default, the identifier key and name of all terms are rendered in English, to improve library standardization. If you use Vietnamese, great, lunar-calendar is already configured and ready to use:
app.php
<?php
use LucNham\LunarCalendar\SolarTerm;
use LucNham\LunarCalendar\Terms\VnSolarTermIdentifier;
require_once('./vendor/autoload.php');
$date = new DateTime('2024-12-30');
$default = SolarTerm::fromDate($date);
$local = SolarTerm::fromDate(
date: $date,
target: VnSolarTermIdentifier::class
);
print_r(
[
"Term's name in English version___" => $default->name,
"Term's key in English version____" => $default->key,
"Term's name in Vietnamese version" => $local->name,
"Term's key in Vietnamese version_" => $local->key,
]
);
Results:
Array
(
[Term's name in English version___] => Winter Solstice
[Term's key in English version____] => winter_solstice
[Term's name in Vietnamese version] => Đông Chí
[Term's key in Vietnamese version_] => dong_chi
)
There are many ways to achieve the goal of localizing the Solar term system, here are a few ideas:
- Extend SolarTermIdentifier class and implement custom properties as the example above does via the VnSolarTermIdentifier class. Please be careful to avoid changing the
position
andls
properties, as they are used to calculate the current term. - Create output value filters from the SolarTerm class.
- Extend the SolarTerm class and override the logic according to your needs.
- Create your own Lunar system processing class based on lunar-calendar's built-in converters.
- If your project is based on mature frameworks such as Laravel, you can take advantage of their great localization features.
System Requirements and Installation