• Vui lòng đọc nội qui diễn đàn để tránh bị xóa bài viết
  • Tìm kiếm trước khi đặt câu hỏi

Giải thuật (và code VB6) tên Can và Chi của ngày, tháng và năm âm lịch

Các thủ thuật liên quan đến xử lý chuỗi và thời gian
User avatar
truongphu
VIP
VIP
Posts: 4778
Joined: Sun 04/11/2007 10:57 am
Location: Cam Đức, Khánh hòa
Has thanked: 14 times
Been thanked: 522 times

Giải thuật (và code VB6) tên Can và Chi của ngày, tháng và năm âm lịch

Postby truongphu » Sat 29/08/2020 2:53 pm

1- Giới thiệu tên Can và Chi.
Tên của ngày, tháng và năm âm lịch là tên kép, được ghép từ mỗi đơn vị trong 2 bộ là Can (Thiên Can) và Chi (Địa Chi).
Can gồm 10 phần tử, hay đọc quen là: Giáp, Ất, Bính, Đinh, Mậu, Kỷ, Canh, Tân, Nhâm, Quý. Sở dĩ đọc quen vì với âm lịch, Giáp là khởi đầu và lần lượt đến các Can khác theo thứ tự như thế.
Chi, tương tự, gồm bộ 12 phần tử, hay đọc quen là: Tý, Sửu, Dần, Mão, Thìn, Tỵ, Ngọ, Mùi, Thân, Dậu, Tuất, Hợi. Tý cũng là chi khởi đầu.
Ví dụ tên năm khởi đầu được ghép từ Can và Chi là Giáp Tý. Tên năm tiếp là Ất Sửu, Bính Dần...
Vì bộ 10 ghép với bộ 12 lần lượt, mà cả 2 bộ đều là chẵn nên chỉ dùng nửa tổ hợp từ Can và Chi: (10 x 12)/2 = 60. Ví dụ ta không bao giờ nghe từ kép Can Chi như Giáp Sửu, Ất Dần...
Và như thế, cứ mỗi 60 đơn vị ghép Can Chi là một chu kỳ.
Kết thúc 1 bộ Can hay Chi, Âm lịch gọi là một Giáp. Giáp Can là 10, giáp Chi là 12. Vì tên năm, khẩu ngữ chỉ gọi tắt tên Chi như năm Tý, tuổi Mẹo... nên một giáp trong dân gian mặc định là giáp Chi, hay 12 năm.
Và tên năm thuộc bộ phối Can Chi, thế nên kết thúc 1 chu kỳ nầy cũng gọi tròn 1 giáp 60, có tên văn vẻ là Lục thập hoa giáp.

2- Giải thuật tên Âm lịch.
Lịch được làm từ đếm, hôm qua ngày 31 thì hôm nay đương nhiên là ngày 32, cứ thế ta có thể tính tới hoặc tính lùi nếu đã có mốc. Giải thuật tên Âm lịch liên quan phép đếm.
Đương nhiên bên cạnh phép đếm, lịch còn có những quy định khác để phù hợp tuần trăng, mùa màng, thời tiết... Chuyện nầy không tính ở đây.

2a- Giải thuật tên năm âm lịch rất đơn giản.
Để dễ tính toán, năm âm lịch được gán theo con số của năm dương lịch. (Nếu không biết ngày tháng năm âm lịch cụ thể, chỉ dùng năm dương lịch để tính thì điều nầy đúng trong hơn 10 tháng).

Về nguyên tắc, ta cứ ghép tên giữa Can và Chi theo thứ tự lần lượt như định nghĩa.

Can: Về giải thuật, các số hay dùng thuộc hệ 10, nên số đơn vị của năm rất tương ứng với Can. Lấy số đơn vị theo VB là Mod 10.
Đơn vị của năm là 0 tương ứng với Can Canh, trong mảng Giáp, Ất... thì Canh đứng thứ 6 tính từ 0, vậy nên sau khi Mod, ta phải +6.

Để code "đẹp", khỏi phép cộng rườm rà, ta có thể dùng mảng Can khác theo đúng thứ tự với Canh đứng đầu
Canh, Tân, Nhâm, Quý, Giáp, Ất, Bính, Đinh, Mậu, Kỷ.

Chi: ta lấy phần dư sau chia 12, đó là Mod 12. Tương tự phần Can, Mod 12 = 0 thường tương ứng Chi của năm là Thân, với mảng Tý, Sửu... ta phải cộng 8.
Để code "đẹp", khỏi phép cộng rườm rà, ta có thể dùng mảng Chi khác theo đúng thứ tự với Thân đứng đầu.

Một ví dụ vài hàng code VB6 đẹp gọi tên năm âm lịch:

  1. Public Function NamAmLich$(ByVal aDate&) ' aDate là nãm âm lich
  2.    Dim Can$(), Chi$()
  3. Can = Split("Canh,Tân,Nhâm,Qúy,Giáp," & ChrW$(7844) & "t,Bính,Ðinh,M" & ChrW$(7853) & "u,K" & ChrW$(7927), ",")
  4. Chi = Split("Thân,D" & ChrW$(7853) & "u,Tu" & ChrW$(7845) & "t,H" & ChrW$(7907) & "i,Tý,S" & ChrW$(7917) & "u,D" & ChrW$(7847) & "n,Mão,Thìn,T" & ChrW$(7925) & ",Ng" & ChrW$(7885) & ",Mùi", ",")
  5. NamAmLich = Can(aDate Mod 10) & " " & Chi(aDate Mod 12)
  6. End Function


Đối số aDate ở câu trên đương nhiên là năm âm lịch nhưng viết theo năm dương lịch.

2b- Giải thuật tên ngày âm lịch đơn giản theo Microsoft.
Đơn giản vì ngày âm lịch cứ tuần tự theo chu kỳ 60 Can Chi. Viết: ...Theo MS bởi vì MS đã làm mốc 1/1/1900 là mốc ngày để tiện tính toán.
Giải thuật: Để tìm tên ngày âm lịch, ta hoàn toàn dựa vào một mốc ngày dương lịch, lấy Mod 10 và Mod 12 rồi tìm quy luật như đã trình bày ở năm âm lịch.
Một ví dụ vài hàng code VB6 gọi tên ngày âm lịch: Đổi trực tiếp từ ngày dương sang ngày âm nhờ MS.
Đối số DDate ở dưới là ngày dương lịch, vd 31/7/2020 hay 7/31/2020 tùy Format.

[vb]Public Function NgayALich$(ByVal DDate As Date) ' DDate là ngày duong lich
Dim Can$(), Chi$()
Can = Split("Nhâm,Qúy,Giáp," & ChrW$(7844) & "t,Bính,Ðinh,M" & ChrW$(7853) & "u,K" & ChrW$(7927) & ",Canh,Tân", ",")
Chi = Split("Thân,D" & ChrW$(7853) & "u,Tu" & ChrW$(7845) & "t,H" & ChrW$(7907) & "i,Tý,S" & ChrW$(7917) & "u,D" & ChrW$(7847) & "n,Mão,Thìn,T" & ChrW$(7925) & ",Ng" & ChrW$(7885) & ",Mùi", ",")
NgayALich$ = Can(DDate Mod 10) & " " & Chi(DDate Mod 12)
End Function[/vb]

Code như trên gọi là quá đẹp, tương ứng giải thuật đơn giản.

2c- Giải thuật tên tháng âm lịch.

Lịch là đếm tuần tự. Ngày hay năm đã đếm tuần tự thì tháng âm lịch cũng thế.
Chi của tháng vừa đủ cho 12 tháng, tuần tự cố định từ tháng giêng (1) gọi là Dần, tháng Hai tiếp tục là Mão...
Can của tháng giêng (1) mỗi năm: năm sau tăng hơn năm trước 2 can. Các tháng sau, Can tính theo tuần tự tháng.
Về giải thuật ta cứ lấy số dư của năm chia cho 10 và cộng thêm số tháng, cộng hay trừ thêm một ít để phù hợp chuỗi Can dùng.
Tháng Giêng: Năm có Mod 10=0 bao giờ Can cũng là Mậu, Mod 10=1 luôn là Canh và tuần tự là Nhâm, Giáp, Bính.

Năm phối Tháng ((Năm âm lịch Mod 10) -1) x 2 + Tháng âm lịch + số K điều chỉnh phù hợp mảng Can.

Một ví dụ vài hàng code VB6 gọi tên tháng âm lịch: Đương nhiên cần có tháng âm lịch và năm âm lịch viết theo kiểu dương lịch.
[vb]
Public Function ThangALich$(ByVal Amonth%, ByVal Ayear&) ' a=âm Amonth = tháng âl, Ayear =nãm âL
Dim Can$(), Chi$()
Can = Split("Ðinh,M" & ChrW$(7853) & "u,K" & ChrW$(7927) & ",Canh,Tân,Nhâm,Qúy,Giáp," & ChrW$(7844) & "t,Bính", ",")
Chi = Split("S" & ChrW$(7917) & "u,D" & ChrW$(7847) & "n,Mão,Thìn,T" & ChrW$(7925) & ",Ng" & ChrW$(7885) & ",Mùi,Thân,D" & ChrW$(7853) & "u,Tu" & ChrW$(7845) & "t,H" & ChrW$(7907) & "i,Tý", ",")
ThangALich = Can((Ayear * 2 + Amonth) Mod 10) & " " & Chi(Amonth Mod 12)
End Function[/vb]

Code đẹp không? Đẹp là gọn, giảm tối đa cộng trừ lôi thôi... Tôi bảo đảm với các bạn chưa ai viết gọn như thế! (trừ tên hàm, biến) cả 3 hàm NgàyAL, ThángAl và NămAL.
Bạn có thể đưa các function nầy vào Excel (chèn Module) và gọi hàm từ Cell thoải mái. B-)


o0o--truongphu--o0o

.........
Ghé thăm:
Chuyện Linh Tinh

User avatar
NoBi
Quản trị
Quản trị
Posts: 970
Joined: Tue 18/03/2008 1:22 pm
Location: Sài Gòn
Has thanked: 57 times
Been thanked: 67 times
Contact:

Re: Giải thuật (và code VB6) tên Can và Chi của ngày, tháng và năm âm lịch

Postby NoBi » Wed 09/09/2020 9:52 am

Bác truongphu có thử viết code trên Google Sheets chưa?
:>

User avatar
truongphu
VIP
VIP
Posts: 4778
Joined: Sun 04/11/2007 10:57 am
Location: Cam Đức, Khánh hòa
Has thanked: 14 times
Been thanked: 522 times

Re: Giải thuật (và code VB6) tên Can và Chi của ngày, tháng và năm âm lịch

Postby truongphu » Fri 11/09/2020 8:59 pm

Chào anh NoBi lâu ngày nha.
Mong CLBVB sứ sống mãi.

Tôi quen lập trình như thú vui, chơi cái VB6 xem như công cụ thích hợp.
Còn Google Sheets có thấy nhưng không vào chi tiết. Có chiếc Honda cà tàng, chạy cũng êm thì nhìn Ya hay Su cũng thế... :)

Chúc anh NoBi và gia quyến khỏe mạnh và nhiều niềm vui trong cuộc sống.
o0o--truongphu--o0o

.........
Ghé thăm:
Chuyện Linh Tinh


Return to “[VB] Chuỗi và Thời gian”

Who is online

Users browsing this forum: No registered users and 0 guests