Chuyển ngày dương sang âm lịch

Chào mọi người. E có tham khảo được đoạn code chuyển ngày dương sang âm lịch mà xem mãi không hiểu. Mong được mọi người thông não giúp e với.

void da(int m,int d)
{   
   ngayduong=(m-1)*31+d;//so ngay duong so voi 1.1
   if ((m==3)|(m==4)) ngayduong=ngayduong-3;//do thang 2 co 28 ngay
   else 
       if ((m==5)|(m==6)) ngayduong=ngayduong-4;// thang 4 co 30 ngay
       else
      if ((m==7)|(m==8)|(m==9)) ngayduong=ngayduong-5;//thang 6 co 30 ngay
      else
          if ((m==10)|(m==11)) ngayduong=ngayduong-6;//thang 9 co 30 ngay
          else 
         if (m==12) ngayduong=ngayduong-7;// thang 11 co 30 ngay
   ngayam=ngayduong+26;//mung 1.1 la ngay 27.11
   thangam=11;
   if (ngayam>=30) 
   {
       ngayam=ngayam-29;
       thangam=12;
   }
   while (ngayam>=30)
   {
       if ((thangam==2)|(thangam==5)|(thangam==8)|(thangam==7)|(thangam==10))
       {
      if (ngayam==29) break;
      ngayam=ngayam-29;      
      thangam++;
      if (thangam==13) thangam=1;
       }
       else 
      if (ngayam==30) break;
      else
      {
      ngayam=ngayam-30;
      thangam++;
      if (thangam==13) thangam=1;
      }
   }
//

Công thức trên code này sai rồi bạn. Bạn đọc công thức đúng ở đây:

https://www.informatik.uni-leipzig.de/~duc/amlich/calrules.html

5 Likes

Hầu hết các lịch âm hiện hành đều dùng thuật toán của Hồ Ngọc Đức. Bạn có thể lên trang của chú ấy để xem chi tiết, có hướng dẫn/giải thích đầy đủ https://www.informatik.uni-leipzig.de/~duc/amlich

4 Likes

Cách tích trên là cách tính dựa vào ngày mốc.
Ngày mốc được chọn là ngày 1/1 dương tương ứng với ngày 27 tháng 11. (năm 2011)
Ban đầu tính số ngày từ ngày mốc tới ngày hiện tại.
Sau đó trừ dần cho tới khi số ngày nhỏ hơn 30.
Cách tích này chỉ áp dụng cho 1 năm duy nhất, để mở rộng cần dùng bảng tra cứu.

#define THANG_1 0;
#define THANG_2 1;
#define THANG_3 2;
#define THANG_4 3;
#define THANG_5 4;
#define THANG_6 5;
#define THANG_7 6;
#define THANG_8 7;
#define THANG_9 8;
#define THANG_10 9;
#define THANG_11 10;
#define THANG_12 11;


int ngayTetDuongLich = 1;
int thangTetDuongLich = 1;
int ngayAmTetDuongLich = 27;
int thangAmTetDuongLich = 11;
int soNgayTuTetDuongLich(int m, int d) {
    int ngayduong = (m-1) * 31+d; // Giả sử mỗi tháng 31 ngày
    int soNgayTrongThang[12] = {
        31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
    };
    int so_ngay_bu_31[12];
    for (int i = 0; i < 12; i++) {
        so_ngay_bu_31[i] = 31 - soNgayTrongThang[i];
        //[0,3,0,1,0,1,0,0,1,0,1,0]
    }
    int ngayBu = 0;
    if ((m==3)|| (m==4)) {
        ngayBu = so_ngay_bu_31[THANG_1] + so_ngay_bu_31[THANG_2]; // = 3
    }
    else if ((m==5)|(m==6)) {
        ngayBu = so_ngay_bu_31[THANG_1] + so_ngay_bu_31[THANG_2] +
                 so_ngay_bu_31[THANG_3] + so_ngay_bu_31[THANG_4]; // = 4

    }
    else if ((m==7)|(m==8)|(m==9)) {
        ngayBu = so_ngay_bu_31[THANG_1] + so_ngay_bu_31[THANG_2] +
                 so_ngay_bu_31[THANG_3] + so_ngay_bu_31[THANG_4] +
                 so_ngay_bu_31[THANG_5] + so_ngay_bu_31[THANG_6] +
                 so_ngay_bu_31[THANG_7] + so_ngay_bu_31[THANG_8]; // =5; so_ngay_bu_31[THANG_7] = 0 so_ngay_bu_31[THANG_8] = 0
        
    }
    else if ((m==10)|(m==11)) {
        ngayBu = so_ngay_bu_31[THANG_1] + so_ngay_bu_31[THANG_2] +
                 so_ngay_bu_31[THANG_3] + so_ngay_bu_31[THANG_4] +
                 so_ngay_bu_31[THANG_5] + so_ngay_bu_31[THANG_6] +
                 so_ngay_bu_31[THANG_7] + so_ngay_bu_31[THANG_8] +
                 so_ngay_bu_31[THANG_9] + so_ngay_bu_31[THANG_10]; // = 6
    }
    else if (m==12) {
        ngayBu = so_ngay_bu_31[THANG_1] + so_ngay_bu_31[THANG_2] +
                 so_ngay_bu_31[THANG_3] + so_ngay_bu_31[THANG_4] +
                 so_ngay_bu_31[THANG_5] + so_ngay_bu_31[THANG_6] +
                 so_ngay_bu_31[THANG_7] + so_ngay_bu_31[THANG_8] +
                 so_ngay_bu_31[THANG_9] + so_ngay_bu_31[THANG_10] +
                 so_ngay_bu_31[THANG_11]; // = 7
    }
    ngayduong = ngayduong - ngayBu;
    return ngayduong;
}
void da(int m,int d)
{   
    int ngayduong = soNgayTuTetDuongLich(m,d); // Số ngày tính từ tết dương lịch
    ngayam=ngayduong + ngayAmTetDuongLich - ngayTetDuongLich;//(+26) cộng thêm chênh lệch ngày âm dương
    thangam = thangAmTetDuongLich;
    if (ngayam>=30) 
    {
        ngayam=ngayam-29;
        thangam=12;
    }
    // Trừ dần cho tới khi ngày nhỏ hơn 30.
    while (ngayam>=30)
    {
        if ((thangam==2)|(thangam==5)|(thangam==8)|(thangam==7)|(thangam==10))
        {
            if (ngayam==29) break;
            ngayam=ngayam-29;      
            thangam++;
            if (thangam==13) thangam=1;
        }
        else {
            if (ngayam==30) break;
            else
            {
                ngayam=ngayam-30;
                thangam++;
                if (thangam==13) thangam=1;
            }
        }
    }
}
2 Likes
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?