Skip to content

Latest commit

 

History

History
325 lines (214 loc) · 13.8 KB

3.LunarDateTime.md

File metadata and controls

325 lines (214 loc) · 13.8 KB

Xử lý ngày tháng Âm - Dương lịch

Nếu bạn là người hâm mộ PHP, có thể bạn đã quen thuộc với lớp DateTime, hỗ trợ xử lý ngày tháng Dương lịch. Lấy cảm hứng từ đây, lunar-calendar cung cấp một lớp LunarDateTime với mục tiêu giúp việc xử lý ngày tháng Âm lịch thân thiện nhất có thể. Mặc dù số lượng bộ tính năng không toàn diện như lớp cốt lõi của PHP, nhưng cũng đủ đáp ứng những nhu cầu cần thiết nhất để xử lý Âm lịch.

Lớp LunarDateTime được thiết kế để giải quyết các vấn đề sau:

  • Tạo một cột mốc ngày tháng Âm lịch đã biết
  • Sửa chữa một mốc ngày tháng Âm lịch không đúng thành cột mốc chính xác
  • Định dạng thời gian Âm lịch thân thiện với người đọc
  • Chuyển đổi Âm lịch thành Dương lịch tương ứng

Ký tự định dạng thời gian Âm lịch

Việc định dạng ngày tháng giúp giải quyết vấn đề tạo chuỗi thời gian thân thiện với người đọc, hoặc lưu trữ các giá trị thời gian Âm lịch vào Cơ sở dữ liệu...

Lớp LunarDateTime hỗ trợ nhiều ký tự định dạng thời gian tương ứng với lớp DateTime (xem thêm https://www.php.net/manual/en/datetime.format.php). Trước khi đi xa hơn, bạn nên nắm bắt giá trị biểu đạt của các ký tự này. Bảng sau liệt kê các ký tự định dạng tương ứng với các giá trị đầu ra của Âm lịch:

Ký tự Mô tả Ví dụ
d Ngày trong tháng, có số 0 đứng trước. Từ 01 đến 30
j Ngày trong tháng, không có số 0 đứng trước. Từ 1 đến 30
L Biểu thị số tháng, có số 0 đứng trước, tháng nhuận có hậu tố '+'. 02, 05+, 12
l Biểu thị số tháng, không có số 0 đứng trước, tháng nhuận có hậu tố '+'. 2, 5+, 12
n Biểu thị số của tháng, không có số 0 đứng trước, không có hậu tố tháng nhuận. 2, 5, 12
m Biểu thị số của tháng, có số 0 đứng trước, không có hậu tố tháng nhuận. 02, 05, 12
Y Biểu thị số năm gồm 4 chữ số. 1000, 2000, 2024
t Biểu thị tổng số ngày trong tháng. 29 hoặc 30
G Định dạng 24 giờ không có số 0 đứng đầu. Từ 0 đến 23
g Định dạng 12 giờ không có số 0 đứng đầu. Từ 0 đến 11
H Định dạng 24 giờ có số 0 đứng đầu. Từ 00 đến 23
h Định dạng 12 giờ có số 0 đứng đầu. Từ 00 đến 11
i Định dạng phút có số 0 đứng đầu. Từ 00 đến 59
s Định dạng giây có số 0 đứng đầu. Từ 00 đến 59
a Chữ in thường trong tiếng Anh phân biệt buổi sáng và buổi chiều. am - pm
A Chữ in HOA trong tiếng Anh phân biệt buổi sáng và buổi chiều. AM - PM
P Độ lệch múi giờ với dấu hai chấm giữa giờ và phút. +00:00
O Độ lệch múi giờ được định dạng liền nhau giữa giờ và phút. +0000
U Số giây kể từ Unix Epoch (1970-01-01 00:00:00 GMT).
Z Độ lệch múi giờ, tính bằng giây. Từ -43200 đến 50400
e Timezone identifier. UTC, Asia/Ho_Chi_Minh
k Chuỗi (+) xác định tháng nhuận. 1903-05-02 00:00 (+)
K Chuỗi [+] xác định tháng nhuận. 1903-05-02 00:00 [+]
c Phiên bản ISO 8601 Âm lịch, nếu tháng nhuận sẽ có thêm hậu tố (+) 1903-05-02T00:00:00+0700 (+)

Lưu ý danh sách các ký tự trên được hỗ trợ bởi lớp định dạng mặc định LunarDateTimeDefaultFormatter, trong quá trình sử dụng, bạn hoàn toàn có thể tùy chỉnh bộ định dạng theo nhu cầu cá nhân.

Tạo mốc thời gian Âm lịch

Bây giờ, hãy tạo một tệp app.php và tạo một mốc thời gian Âm lịch tương ứng với thời điểm hiện tại, sau đó chạy lệnh php ./app.php để xem kết quả.

app.php

<?php

use LucNham\LunarCalendar\LunarDateTime;

require_once('./vendor/autoload.php');

$lunar = new LunarDateTime();
$datetime = 'Current Lunar date time is ' . $lunar->format('d-m-Y H:i:s P');

print_r($datetime);

Kết quả:

Current Lunar date time is 24-09-2024 03:39:54 +00:00

Theo mặc định, khi không có tham số khởi tạo, lớp LunarDateTime sẽ sử dụng thời điểm "hiện tại", và múi giờ sẽ sử dụng theo cấu hình của hệ thống.

Bây giờ, hãy làm cho rõ ràng hơn một chút. Giả sử chúng ta cần mốc Âm lịch cụ thể ngày 01 tháng 01 năm 2000, lúc 20 giờ 30 phút tại Việt Nam, hãy viết như sau:

app.php

<?php

use LucNham\LunarCalendar\LunarDateTime;

require_once('./vendor/autoload.php');

$lunar = new LunarDateTime('2000-01-01 20:30 Asia/Ho_Chi_Minh');
$datetime = 'Current Lunar date time is ' . $lunar->format('d-m-Y H:i:s P');

print_r($datetime);

Kết quả:

`Current Lunar date time is 01-01-2000 20:30:00 +07:00`

Thông thường, bạn có thể truyền trực tiếp múi giờ địa phương vào chuỗi Âm lịch. Tuy nhiên, trong những trường hợp khác, bạn muốn tách rời thời gian và múi giờ, bạn có thể truyền một đối tượng DateTimeZone vào __constructor, kết quả là giống nhau:

app.php

<?php

use LucNham\LunarCalendar\LunarDateTime;

require_once('./vendor/autoload.php');

$lunar = new LunarDateTime(
    datetime: '2000-01-01 20:30',
    timezone: new DateTimeZone('+0700')
);
$datetime = 'Current Lunar date time is ' . $lunar->format('d-m-Y H:i:s P');

print_r($datetime);

Lưu ý, nếu chuỗi thời gian có chứa thông tin múi giờ và đối tượng DateTimeZone đồng thời được truyền vào hàm tạo, thì múi giờ trong chuỗi thời gian sẽ được ưu tiên sử dụng.

app.php

<?php

use LucNham\LunarCalendar\LunarDateTime;

require_once('./vendor/autoload.php');

$lunar = new LunarDateTime(
    datetime: '2000-01-01 20:30 UTC',
    timezone: new DateTimeZone('GMT+12')
);

$timezone = $lunar->format('e');

print_r($timezone);

Kết quả:

UTC

Xử lý tháng nhuận

Không giống như Dương lịch năm nhuận luôn rơi vào tháng 02, tháng Nhuận trong Âm lịch khá phức tạp và không cố định. Để xử lý thời gian Âm lịch trong tháng nhuận, bạn có thể chỉ định tháng nhuận đầu vào bằng một trong các định dạng sau:

Thời gian ví dụ Chuỗi ký tự dịnh dạng tương ứng
2020-04-20 00:00 +0700 (+) Y-m-d H:i O k
2020-04-20 00:00 +0700 [+] Y-m-d H:i O K
20/04+/2020 00:00 +0700 d/L/Y H:i O
2020-04+-20 00:00 +0700 Y-L-d H:i O

Khi các dấu hiệu +, (+), [+] được thêm vào chuỗi thời gian Âm lịch, trình phân tích sẽ đánh dấu tháng bạn chọn là tháng nhuận.

app.php

<?php

use LucNham\LunarCalendar\LunarDateTime;

require_once('./vendor/autoload.php');

$lunar1 = new LunarDateTime('2020-04-20 20:30 +0700 (+)');
$lunar2 = new LunarDateTime('20/04+/2020 20:30 +0700');

print_r([
    "Lunar 1" => $lunar1->format('d-m-Y k'),
    "Lunar 2" => $lunar2->format('d-m-Y K'),
]);

Kết quả:

Array
(
    [Lunar 1] => 20-04-2020 (+)
    [Lunar 2] => 20-04-2020 [+]
)

Trường hợp tháng nhuận bạn chỉ định không đúng với dữ kiện lịch, lớp LunarDateTime sẽ cố gắng sửa chữa mốc đầu vào thành giá trị đúng. Ở ví dụ bên dưới, năm 2020 Âm lịch Việt Nam nhuận vào tháng 04, nhưng đầu vào lại được đặt thành tháng 05 nhuận:

app.php

<?php

use LucNham\LunarCalendar\LunarDateTime;

require_once('./vendor/autoload.php');

$lunar = new LunarDateTime('2020-05-20 20:30 +0700 (+)');
$guaranteed = $lunar->getGuaranteedLunarDateTime();

print_r([
    'Âm lịch đầu vào' => $lunar->format('d-m-Y k'),
    'Tháng nhuận thực tế' => $guaranteed->l
]);

Kết quả:

Array
(
    [Âm lịch đầu vào] => 20-05-2020
    [Tháng nhuận thực tế] => 4
)

Khớp ngày tháng bị sai

Một tháng Âm lịch có 29 hoặc 30 ngày, nhưng số ngày mỗi tháng không cố định như Dương lịch mà phụ thuộc vào vị trí Pha trăng mới (điểm Sóc) và vị trí lập lịch trên Trái Đất. Điều này tạo ra vấn đề không thể biết được tháng cần tìm có bao nhiêu ngày. Ví dụ, tháng 09 năm 2024 Âm lịch Việt Nam chỉ có 29 ngày, nếu bạn chỉ định chuỗi đầu vào là 30, lớp LunarDateTime sẽ sửa nó thành ngày 01 tháng 10 như sau:

app.php

<?php

use LucNham\LunarCalendar\LunarDateTime;

require_once('./vendor/autoload.php');

$lunar = new LunarDateTime('2024-09-30 +0700');

print_r([
    'Đâu vào không chính xác' => '2024-09-30 +0700',
    'Đầu ra được sửa chữa' => $lunar->format('Y-m-d P')
]);

Kết quả:

Array
(
    [Đâu vào không chính xác] => 2024-09-30 +0700
    [Đầu ra được sửa chữa] => 2024-10-01 +07:00
)

Tạo Âm lịch từ dương lịch

Khi cần phải tính toán Âm lịch từ một mốc Dương lịch, bạn có thể sử dụng phương thức tĩnh LunarDateTime::fromGregorian, phương thức này chấp nhận tham số là một chuỗi thời gian Dương lịch.

app.php

<?php

use LucNham\LunarCalendar\LunarDateTime;

require_once('./vendor/autoload.php');

$lunar = LunarDateTime::fromGregorian('2024-02-10 +0700');
$ouput  = $lunar->format('c');

print_r($ouput);

Kết quả:

2024-01-01T00:00:00+07:00

Chuyển đổi Âm lịch sang Dương lịch

Giả sử bạn có một mốc ngày Âm lịch cần phải chuyển đổi sang Dương lịch, hãy sử dụng phương thức LunarDateTime::toDateTimeString. Phương thức này trả về chuỗi thời gian Dương lịch tiêu chuẩn và thân thiện với định dạng Y-m-d H:i:s P mà bạn có thể sử dụng cho nhiều mục đích khác nhau. Thông tin về múi giờ địa phương cũng sẽ được chuyển tiếp đồng bộ.

app.php

<?php

use LucNham\LunarCalendar\LunarDateTime;

require_once('./vendor/autoload.php');

$lunar = new LunarDateTime('2024-01-01 20:00 +0700');
$ouput  = $lunar->toDateTimeString();

print_r($ouput);

Kết quả:

2024-02-10 20:00:00 +07:00

Các tính năng khác

Bảng sau liệt kê các phương thức sẵn có của lớp LunarDateTime mà bạn có thể sử dụng:

Tên phương thức Mô tả
now() Trả về mốc Âm lịch tại thời điểm gọi, tham số timzone có thể được bổ sung nếu cần
getGuaranteedLunarDateTime() Trả về một đối tượng LunarDateTimeGuaranteed
getTimestamp() Trả về dấu thời gian Unix tương ứng với mốc Âm lịch, tính bằng giây
getTimezone Trả về một đối tượng DateTimeZone
getOffset Trả về bù chênh lệch giữa giờ địa phương và giờ Greenwich, tính bằng giây

Trình đơn điều hướng

Giới thiệu

Cài đặt thư viện

Hệ thống Tiết khí

Hệ thống Can Chi