Xem giúp em đoạn code này sai ở đâu

  • Thread starter Thread starter boyxin
  • Ngày gửi Ngày gửi
Liên hệ QC

boyxin

Members actively
Tham gia
10/3/08
Bài viết
1,664
Được thích
2,335
Chào các bác
  • Em đang quan tâm đến vấn đề dùng excel tạo 1 trang lịch có đủ ngày âm, ngày dương ...
  • Em vào http://www.informatik.uni-leipzig.de/~duc/amlich/calrules.html thấy nhiều công thức hay cho vấn đề chuyển đổi ngày âm - dương
  • Nhưng khi em chuyển thành code trong VBA thì không được. Rất mong các bác xem xét, nghiên cứu giúp em cái vụ này với
Thuật toán chuyển đổi giữa ngày dương và âm

Trong tính toán thiên văn người ta lấy ngày 1/1/4713 trước công nguyên của lịch Julius (tức ngày 24/11/4714 trước CN theo lịch Gregorius) làm điểm gốc. Số ngày tính từ điểm gốc này gọi là số ngày Julius (Julian day number) của một thời điểm. Ví dụ, số ngày Julius của 1/1/2000 là 24515455.
Dùng các công thức sau ta có thể chuyển đổi giữa ngày/tháng/năm và số ngày Julius. Phép chia ở 2 công thức sau được hiểu là chia số nguyên, bỏ phần dư: 23/4=5.

1- Đổi ngày dương lịch ra số Jd (Julian day number)
PHP:
Function jdFromDate(dd, mm, yy)
a = Int((14 - mm) / 12)
y = yy + 4800 - a
M = mm + 12 * a - 3
jd = dd + Int((153 * M + 2) / 5) + 365 * y + Int(y / 4) - Int(y / 100) + Int(y / 400) - 32045
If (jd < 2299161) Then
    jd = dd + Int((153 * M + 2) / 5) + 365 * y + Int(y / 4) - 32083
End If
jdFromDate = jd
End Function
2- Đổi số Jd (Julian day number) ra ngày dương lịch
PHP:
Function jdToDate(jd)
If (jd > 2299160) Then ' { // After 5/10/1582, Gregorian calendar
    a = jd + 32044
    b = Int((4 * a + 3) / 146097)
    c = a - Int((b * 146097) / 4)
Else
    b = 0
    c = jd + 32082
    d = Int((4 * c + 3) / 1461)
    E = c - Int((1461 * d) / 4)
    M = Int((5 * E + 2) / 153)
    Day = E - Int((153 * M + 2) / 5) + 1
    Month = M + 3 - 12 * Int(M / 10)
    Year = b * 100 + d - 4800 + Int(M / 10)
End If
jdToDate = Array(Day, Month, Year)
End Function
3- Tìm ngày Sóc
PHP:
Function getNewMoonDay(k, timeZone)
T = k / 1236.85 '; // Time in Julian centuries from 1900 January 0.5
T2 = T * T
T3 = T2 * T
dr = Pi / 180
Jd1 = 2415020.75933 + 29.53058868 * k + 0.0001178 * T2 - 0.000000155 * T3
Jd1 = Jd1 + 0.00033 * Math.Sin((166.56 + 132.87 * T - 0.009173 * T2) * dr) '; // Mean new moon
M = 359.2242 + 29.10535608 * k - 0.0000333 * T2 - 0.00000347 * T3 '; // Sun's mean anomaly
Mpr = 306.0253 + 385.81691806 * k + 0.0107306 * T2 + 0.00001236 * T3 '; // Moon's mean anomaly
F = 21.2964 + 390.67050646 * k - 0.0016528 * T2 - 0.00000239 * T3 '; // Moon's argument of latitude
C1 = (0.1734 - 0.000393 * T) * Math.Sin(M * dr) + 0.0021 * Math.Sin(2 * dr * M)
C1 = C1 - 0.4068 * Math.Sin(Mpr * dr) + 0.0161 * Math.Sin(dr * 2 * Mpr)
C1 = C1 - 0.0004 * Math.Sin(dr * 3 * Mpr)
C1 = C1 + 0.0104 * Math.Sin(dr * 2 * F) - 0.0051 * Math.Sin(dr * (M + Mpr))
C1 = C1 - 0.0074 * Math.Sin(dr * (M - Mpr)) + 0.0004 * Math.Sin(dr * (2 * F + M))
C1 = C1 - 0.0004 * Math.Sin(dr * (2 * F - M)) - 0.0006 * Math.Sin(dr * (2 * F + Mpr))
C1 = C1 + 0.001 * Math.Sin(dr * (2 * F - Mpr)) + 0.0005 * Math.Sin(dr * (2 * Mpr + M))
If (T < -11) Then
    deltat = 0.001 + 0.000839 * T + 0.0002261 * T2 - 0.00000845 * T3 - 0.000000081 * T * T3
Else
    deltat = -0.000278 + 0.000265 * T + 0.000262 * T2
    JdNew = Jd1 + C1 - deltat
End If
getNewMoonDay = Int(JdNew + 0.5 + timeZone / 24)
End Function
4- Tính tọa độ mặt trời
PHP:
Function getSunLongitude(jdn, timeZone)
T = (jdn - 2451545.5 - timeZone / 24) / 36525 '; // Time in Julian centuries from 2000-01-01 12:00:00 GMT
T2 = T * T
dr = Pi / 180 '; // degree to radian
M = 357.5291 + 35999.0503 * T - 0.0001559 * T2 - 0.00000048 * T * T2 '; // mean anomaly, degree
L0 = 280.46645 + 36000.76983 * T + 0.0003032 * T2 '; // mean longitude, degree
DL = (1.9146 - 0.004817 * T - 0.000014 * T2) * Math.Sin(dr * M)
DL = DL + (0.019993 - 0.000101 * T) * Math.Sin(dr * 2 * M) + 0.00029 * Math.Sin(dr * 3 * M)
L = L0 + DL '; // true longitude, degree
L = L * dr
L = L - Pi * 2 * (Int(L / (Pi * 2))) '; // Normalize to (0, 2*PI)
getSunLongitude = Int(L / Pi * 6)
End Function
5- Tìm ngày 1-11 âm lịch
PHP:
Function getLunarMonth11(yy, timeZone)
off = jdFromDate(31, 12, yy) - 2415021
k = Int(off / 29.530588853)
nm = getNewMoonDay(k, timeZone)
sunLong = getSunLongitude(nm, timeZone) '; // sun longitude at local midnight
If (sunLong >= 9) Then
    nm = getNewMoonDay(k - 1, timeZone)
End If
getLunarMonth11 = nm
End Function
6- Xác định tháng âm lịch nhuận
PHP:
Function getLeapMonthOffset(a11, timeZone)
k = Int((a11 - 2415021.07699869) / 29.530588853 + 0.5)
last = 0
I = 1 '; // We start with the month following lunar month 11
Arc = getSunLongitude(getNewMoonDay(k + I, timeZone), timeZone)
Do
    last = Arc
    I = I + 1
    Arc = getSunLongitude(getNewMoonDay(k + I, timeZone), timeZone)
While (Arc = last & I < 14)
getLeapMonthOffset = I - 1
End Function
7- Đổi ngày đương lịch ra ngày âm lịch
PHP:
Function convertSolar2Lunar(dd, mm, yy, timeZone)
dayNumber = jdFromDate(dd, mm, yy)
k = Int((dayNumber - 2415021.07699869) / 29.530588853)
monthStart = getNewMoonDay(k + 1, timeZone)
If (monthStart > dayNumber) Then
    monthStart = getNewMoonDay(k, timeZone)
    a11 = getLunarMonth11(yy, timeZone)
    b11 = a11
    If (a11 >= monthStart) Then
        lunarYear = yy
        a11 = getLunarMonth11(yy - 1, timeZone)
    Else
        lunarYear = yy + 1
        b11 = getLunarMonth11(yy + 1, timeZone)
        lunarDay = dayNumber - monthStart + 1
        diff = Int((monthStart - a11) / 29)
        lunarLeap = 0
        lunarMonth = diff + 11
        If (b11 - a11 > 365) Then
            leapMonthDiff = getLeapMonthOffset(a11, timeZone)
            If (diff >= leapMonthDiff) Then
                lunarMonth = diff + 10
                If (diff = leapMonthDiff) Then
                    lunarLeap = 1
                    If (lunarMonth > 12) Then
                        lunarMonth = lunarMonth - 12
                        If (lunarMonth >= 11 & diff < 4) Then
                            lunarYear = lunarYear - 1
                        End If
                    End If
                End If
            End If
        End If
    End If
End If
convertSolar2Lunar = Array(lunarDay, lunarMonth, lunarYear)
End Function
8- Đổi ngày âm lịch ra ngày dương lịch
PHP:
Function convertLunar2Solar(lunarDay, lunarMonth, lunarYear, lunarLeap, timeZone)
If (lunarMonth < 11) Then
    a11 = getLunarMonth11(lunarYear - 1, timeZone)
    b11 = getLunarMonth11(lunarYear, timeZone)
Else
    a11 = getLunarMonth11(lunarYear, timeZone)
    b11 = getLunarMonth11(lunarYear + 1, timeZone)
    off = lunarMonth - 11
    If (off < 0) Then
        off = off + 12
        If (b11 - a11 > 365) Then
            leapOff = getLeapMonthOffset(a11, timeZone)
            leapMonth = leapOff - 2
            If (leapMonth < 0) Then
                leapMonth = leapMonth + 12
                If (lunarLeap = 0 & lunarMonth = leapMonth) Then
return new Array(0, 0, 0);
                Else
                    If (lunarLeap = 0) Or (off >= leapOff) Then
                        off = off + 1
                        k = Int(0.5 + (a11 - 2415021.07699869) / 29.530588853)
                        monthStart = getNewMoonDay(k + off, timeZone)
                    End If
                End If
            End If
        End If
    End If
End If
return jdToDate(monthStart+lunarDay-1);
End Function

File đính kèm trong bài #15
 
Lần chỉnh sửa cuối:
Chào các bác
  • Em đang quan tâm đến vấn đề dùng excel tạo 1 trang lịch có đủ ngày âm, ngày dương ...
  • Em vào http://www.informatik.uni-leipzig.de.../calrules.html thấy nhiều công thức hay cho vấn đề chuyển đổi ngày âm - dương
  • Nhưng khi em chuyển thành code trong VBA thì không được. Rất mong các bác xem xét, nghiên cứu giúp em cái vụ này với

NHƯNG boyxin phải nói ra lỗi ở đâu nhỉ? khi nào?
thế mới thì TV # giúp được
.
 
Upvote 0
NHƯNG boyxin phải nói ra lỗi ở đâu nhỉ? khi nào?
thế mới thì TV # giúp được
.

Em mới tập voc về VBA
Em vào http://www.informatik.uni-leipzig.de.../calrules.html
thấy nhiều công thức hay cho vấn đề chuyển đổi ngày âm - dương​

Chép y nguyên code trong này, và chủ yếu là thêm End If để thành Function
1- Trong đoạn 1
Ví dụ, số ngày Julius của 1/1/2000 là 24515455
nhưng em chép y nguyên code về tính thì lại ra kết quả khác
cụ thể: số ngày Julius của 1/1/2000 chỉ là 24515455
2- Trong đoạn 2: Đổi số Jd (Julian day number) ra ngày dương lịch
em lấy số Jd = 24515455 để đổi thì lại ra kết quả khác với ngày 1/1/1990

và còn nhiều chỗ nữa, em gửi file đính kèm trong bài #15
 
Lần chỉnh sửa cuối:
Upvote 0
Mình cùng bắt đầu từ Function jdToDate(jd) nhé. Theo tôi code của nó phải là:
PHP:
'Doi so Jd (Julian day number) ra ngay'
Function jdToDate(jd)
Dim a, b, c, d, e, m, dd, mm, yy
If (jd >= 2299161) Then '' { // After 5/10/1582, Gregorian calendar
    a = jd + 32044
    b = Int((4 * a + 3) / 146097)
    c = a - Int((b * 146097) / 4)
Else
    b = 0
    c = jd + 32082
End If
d = Int((4 * c + 3) / 1461)
e = c - Int((1461 * d) / 4)
m = Int((5 * e + 2) / 153)
dd = e - Int((153 * m + 2) / 5) + 1
mm = m + 3 - 12 * Int(m / 10)
yy = b * 100 + d - 4800 + Int(m / 10)
jdToDate = DateSerial(yy, mm, dd)
End Function
Tuy nhiên có vấn đề sau:
- Ngày 01/01/1900 đổi sang số Jd (= 'jdFromDate(dd, mm, yy)') = 2415021 (giống kết quả của tác giả Hồ Ngọc Đức tại trang web mà boyxin đã cung cấp).
- Dùng hàm 'jdToDate(jd)' của số 2415021 thì lại ra là ngày 02/01/1900.
Nhờ các bác trên diễn đàn kiểm tra lại xem là có gì sai nữa không???
 
Upvote 0
Mình cùng bắt đầu từ Function jdToDate(jd) nhé. Theo tôi code của nó phải là:
PHP:
'Doi so Jd (Julian day number) ra ngay'
Function jdToDate(jd)
Dim a, b, c, d, e, m, dd, mm, yy
If (jd >= 2299161) Then '' { // After 5/10/1582, Gregorian calendar
    a = jd + 32044
    b = Int((4 * a + 3) / 146097)
    c = a - Int((b * 146097) / 4)
Else
    b = 0
    c = jd + 32082
End If
d = Int((4 * c + 3) / 1461)
e = c - Int((1461 * d) / 4)
m = Int((5 * e + 2) / 153)
dd = e - Int((153 * m + 2) / 5) + 1
mm = m + 3 - 12 * Int(m / 10)
yy = b * 100 + d - 4800 + Int(m / 10)
jdToDate = DateSerial(yy, mm, dd)
End Function
Tuy nhiên có vấn đề sau:
- Ngày 01/01/1900 đổi sang số Jd (= 'jdFromDate(dd, mm, yy)') = 2415021 (giống kết quả của tác giả Hồ Ngọc Đức tại trang web mà boyxin đã cung cấp).
- Dùng hàm 'jdToDate(jd)' của số 2415021 thì lại ra là ngày 02/01/1900.
Nhờ các bác trên diễn đàn kiểm tra lại xem là có gì sai nữa không???

Cảm ơn pác minhlev nhiều lắm

các bác tiếp tục xem giúp em với File đính kèm trong bài #15
 
Lần chỉnh sửa cuối:
Upvote 0
Tiếp tục với hàm getSunLongitude(jdn, timeZone) nhé. Theo tôi, code của nó phải là:
PHP:
Function getSunLongitude(jdn, timeZone)
Dim T, T2, dr, m, L0, DL, L
T = (jdn - 2451545.5 - timeZone / 24) / 36525 '; // Time in Julian centuries from 2000-01-01 12:00:00 GMT'
T2 = T * T
dr = WorksheetFunction.Pi / 180  '; // degree to radian'
m = 357.5291 + 35999.0503 * T - 0.0001559 * T2 - 0.00000048 * T * T2 '; // mean anomaly, degree
L0 = 280.46645 + 36000.76983 * T + 0.0003032 * T2 '; // mean longitude, degree
DL = (1.9146 - 0.004817 * T - 0.000014 * T2) * Sin(dr * m)
DL = DL + (0.019993 - 0.000101 * T) * Sin(dr * 2 * m) + 0.00029 * Sin(dr * 3 * m)
L = L0 + DL '; // true longitude, degree
L = L * dr
L = L - WorksheetFunction.Pi * 2 * (Int(L / (WorksheetFunction.Pi * 2)))
getSunLongitude = Int(L / WorksheetFunction.Pi * 6)
End Function
 
Upvote 0
Tiếp theo là hàm Function convertSolar2Lunar(dd, mm, yy, timeZone). Theo tôi code phải là:
PHP:
'Doi ngay DL ra ngay AL'
Function convertSolar2Lunar(dd, mm, yy, timeZone)
Dim k, dayNumber, monthStart, a11, b11
Dim lunarDay, lunarMonth, lunarYear, lunarLeap
dayNumber = jdFromDate(dd, mm, yy)
k = Int((dayNumber - 2415021.07699869) / 29.530588853)
monthStart = getNewMoonDay(k + 1, timeZone)
If monthStart > dayNumber Then _
    monthStart = getNewMoonDay(k, timeZone)
    a11 = getLunarMonth11(yy, timeZone)
    b11 = a11
If a11 >= monthStart Then
    lunarYear = yy
    a11 = getLunarMonth11(yy - 1, timeZone)
Else
    lunarYear = yy + 1
    b11 = getLunarMonth11(yy + 1, timeZone)
End If
lunarDay = dayNumber - monthStart + 1
diff = Int((monthStart - a11) / 29)
lunarLeap = 0
lunarMonth = diff + 11
If b11 - a11 > 365 Then
    leapMonthDiff = getLeapMonthOffset(a11, timeZone)
    If diff >= leapMonthDiff Then
        lunarMonth = diff + 10
        If diff = leapMonthDiff Then lunarLeap = 1
    End If
End If
If lunarMonth > 12 Then lunarMonth = lunarMonth - 12
If lunarMonth >= 11 And diff < 4 Then lunarYear = lunarYear - 1
convertSolar2Lunar = DateSerial(lunarYear, lunarMonth, lunarDay)
End Function
Theo tôi, nhìn chung là bạn bị nhầm trong việc ngắt các dòng điều kiện If...Then-->End If. Nếu bạn ngắt đúng thì kết quả sẽ đúng. Bạn làm tương tự với hàm cuối cùng nhé.
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Em mới tập voc về VBA
Em vào http://www.informatik.uni-leipzig.de.../calrules.html
thấy nhiều công thức hay cho vấn đề chuyển đổi ngày âm - dương​

Chép y nguyên code trong này, và chủ yếu là thêm End If để thành Function
1- Trong đoạn 1 nhưng em chép y nguyên code về tính thì lại ra kết quả khác
cụ thể: số ngày Julius của 1/1/2000 chỉ là 24515455
2- Trong đoạn 2: Đổi số Jd (Julian day number) ra ngày dương lịch
em lấy số Jd = 24515455 để đổi thì lại ra kết quả khác với ngày 1/1/1990

và còn nhiều chỗ nữa, em gửi file đính kèm đây. Các bác xem giúp em nha

oh, sao đều 24515455 vậy thế là đâu có sai nhỉ, boyxin
 
Upvote 0
Không biết boyxin đã thử cái hàm convertSolar2Lunar ở trên chưa? Nhưng hàm đó có 1 lỗi rất cơ bản mà tôi mới phát hiện ra. Đó là ở dòng code cuối cùng không thể viết
Mã:
[COLOR=black]convertSolar2Lunar [/COLOR][COLOR=black][COLOR=#007700]= [/COLOR][COLOR=#0000bb]DateSerial[/COLOR][COLOR=#007700]([/COLOR][COLOR=#0000bb]lunarYear[/COLOR][COLOR=#007700], [/COLOR][COLOR=#0000bb]lunarMonth[/COLOR][COLOR=#007700], [/COLOR][COLOR=#0000bb]lunarDay[/COLOR][/COLOR][COLOR=#007700][COLOR=black])[/COLOR][/COLOR]
Lý do là hàm Dateserial kết hợp ngày tháng theo dương lịch. Mà trong lịch dương thì tháng 2 chỉ có 28 hoặc 29 ngày (năm nhuận) mà thôi. Trong khi đó trong lịch âm thì tháng 2 lại có thể có 29 ngày (tháng thiếu) hoặc 30 ngày (tháng đủ). Do vậy tôi tạm chuyển hàm này về dạng String với code như sau
Mã:
convertSolar2Lunar = [COLOR=#0000bb][COLOR=black]lunarDay & "/" & lunarMonth & "/" & lunarYear [/COLOR][/COLOR]
Xin nhờ các bác trong diễn đàn xem có cách nào khác không?

--------
File tôi gửi trong bài #7 bị sai. Tôi đã gửi lại file mới. Nhờ các bác xem hộ.
 
Lần chỉnh sửa cuối:
Upvote 0
Không biết boyxin đã thử cái hàm convertSolar2Lunar ở trên chưa? Nhưng hàm đó có 1 lỗi rất cơ bản mà tôi mới phát hiện ra. Đó là ở dòng code cuối cùng không thể viết
Mã:
[COLOR=black]convertSolar2Lunar [/COLOR][COLOR=black][COLOR=#007700]= [/COLOR][COLOR=#0000bb]DateSerial[/COLOR][COLOR=#007700]([/COLOR][COLOR=#0000bb]lunarYear[/COLOR][COLOR=#007700], [/COLOR][COLOR=#0000bb]lunarMonth[/COLOR][COLOR=#007700], [/COLOR][COLOR=#0000bb]lunarDay[/COLOR][/COLOR][COLOR=#007700][COLOR=black])[/COLOR][/COLOR]
Lý do là hàm Dateserial kết hợp ngày tháng theo dương lịch. Mà trong lịch dương thì tháng 2 chỉ có 28 hoặc 29 ngày (năm nhuận) mà thôi. Trong khi đó trong lịch âm thì tháng 2 lại có thể có 29 ngày (tháng thiếu) hoặc 30 ngày (tháng đủ). Do vậy tôi tạm chuyển hàm này về dạng String với code như sau
Mã:
convertSolar2Lunar = [COLOR=#0000bb][COLOR=black]lunarDay & "/" & lunarMonth & "/" & lunarYear [/COLOR][/COLOR]
Xin nhờ các bác trong diễn đàn xem có cách nào khác không?

--------
File tôi gửi trong bài #7 bị sai. Tôi đã gửi lại file mới. Nhờ các bác xem hộ.

MÌNH ĐANG TEST HẾT CÁC HÀM ĐỂ POST 1 THỂ, KHÔNG PHẢI CHỈ CÓ NÓ BỊ SAI, CÒN TRUỜNG HỢP HÀM
  1. getSunLongitude(jdn, timeZone) KHÔNG HỀ THAY ĐỔI GIÁ TRỊ KHI THAY ĐỔI NĂM CỦA NGÀY LẤY Jdn
  2. convertSolar2Lunar(dd, mm, yy, timeZone) BỊ SAI RẤT NHIỀU (THÁNG 29 NGÀY THÌ NÓ LẠI LÀ 30 HOẶC 28, .........)
  3. getNewMoonDay(k, timeZone) TÌM NGÀY SÓC CŨNG KHÔNG CHUẨN
  4. getLeapMonthOffset(a11, timeZone) KHÔNG XÁC ĐỊNH ĐƯỢC THÁNG NHUẬN
  5. getLunarMonth11(yy, timeZone) CHO RA KẾT QUẢ LÀ SỐ Jd CỦA NGÀY DƯƠNG LỊCH CỦA NGÀY 1-11 ÂM LỊCH CHỨ KHÔNG PHẢI LÀ NGÀY DƯƠNG LỊCH CỦA NGÀY 1-11 ÂM LỊCH
ĐANG THỬ CÁC TRƯỜNG HỢP KHÁC NỮA
 
Lần chỉnh sửa cuối:
Upvote 0
MÌNH ĐANG TEST HẾT CÁC HÀM ĐỂ POST 1 THỂ, KHÔNG PHẢI CHỈ CÓ NÓ BỊ SAI, CÒN TRUỜNG HỢP HÀM
  1. getSunLongitude(jdn, timeZone) KHÔNG HỀ THAY ĐỔI GIÁ TRỊ KHI THAY ĐỔI NĂM CỦA NGÀY LẤY Jdn
  2. convertSolar2Lunar(dd, mm, yy, timeZone) BỊ SAI RẤT NHIỀU (THÁNG 29 NGÀY THÌ NÓ LẠI LÀ 30 HOẶC 28, .........)
  3. getNewMoonDay(k, timeZone) TÌM NGÀY SÓC CŨNG KHÔNG CHUẨN
  4. getLeapMonthOffset(a11, timeZone) KHÔNG XÁC ĐỊNH ĐƯỢC THÁNG NHUẬN
  5. getLunarMonth11(yy, timeZone) CHO RA KẾT QUẢ LÀ SỐ Jd CỦA NGÀY DƯƠNG LỊCH CỦA NGÀY 1-11 ÂM LỊCH CHỨ KHÔNG PHẢI LÀ NGÀY DƯƠNG LỊCH CỦA NGÀY 1-11 ÂM LỊCH
ĐANG THỬ CÁC TRƯỜNG HỢP KHÁC NỮA

boyxin nên post cập nhập nx cái đã sửa đi, để TV # giúp -> k phải lặp lại cái đã sửa rùi,
.
 
Upvote 0
Lần chỉnh sửa cuối:
Upvote 0
Trong hàm tìm tháng nhuận getLeapMonthOffset(a11, timezone) tôi đã vô tình xóa đi một điều kiện hết sức quan trọng. Sau khi đọc lại bài của Mr Hồ Ngọc Đức mới phát hiện ra.
Code cũ
PHP:
Do While i < 14
    last = arc
    i = i + 1
    arc = getSunLongitude(getNewMoonDay(k + i, timezone), timezone)
Loop
Code đúng
PHP:
Do While last = arc And i < 14
    last = arc
    i = i + 1
    arc = getSunLongitude(getNewMoonDay(k + i, timezone), timezone)
Loop
 
Lần chỉnh sửa cuối:
Upvote 0
boyxin Test convertSolar2Lunar2

Trong hàm tìm tháng nhuận getLeapMonthOffset(a11, timezone) tôi đã vô tình xóa đi một điều kiện hết sức quan trọng. Sau khi đọc lại bài của Mr Hồ Ngọc Đức mới phát hiện ra.
Code đúng
PHP:
Do While last = arc And i < 14
    last = arc
    i = i + 1
    arc = getSunLongitude(getNewMoonDay(k + i, timezone), timezone)
Loop

Hiện tại getLeapMonthOffset(a11, timezone) = 0 cho dù ta thay đổi giá trị a11
PHP:
Function getLeapMonthOffset(a11, timezone)
Dim k, last, arc, i
k = Int((a11 - 2415021.07699869) / 29.530588853 + 0.5)
last = 0
i = 1
arc = getSunLongitude(getNewMoonDay(k + i, timezone), timezone)
Do While last = arc And i < 14
    last = arc
    i = i + 1
    arc = getSunLongitude(getNewMoonDay(k + i, timezone), timezone)
Loop
getLeapMonthOffset = i - 1
End Function
Nếu a11 là số Jd của ngày dương lịch (mà âm lịch là ngày mùng 1 tháng 11)
Chuyển thành thế này dùng hàm getLeapMonthOffset(yy, timezone) tiện hơn
PHP:
Function getLeapMonthOffset(yy, timezone)
Dim k, last, arc, i
a11 = getLunarMonth11(yy, timezone)
k = Int((a11 - 2415021.07699869) / 29.530588853 + 0.5)
last = 0
i = 1
arc = getSunLongitude(getNewMoonDay(k + i, timezone), timezone)
Do While last = arc And i < 14
    last = arc
    i = i + 1
    arc = getSunLongitude(getNewMoonDay(k + i, timezone), timezone)
Loop
getLeapMonthOffset = i - 1
End Function
Thế nhưng lấy ngày 1-11-năm nào cũng vậy

Nếu không phải vậy thì a11 là cái gì? em thay a11 là năm cần xác định tháng nhuận cũng không được,
kết quả vẫn là getLeapMonthOffset(a11, timezone) = 0
--------------------------------------------------------------------------------

Còn 4 Functions chưa xác định được ..... Mong được CÁC BÁC xem giúp
  1. getNewMoonDay(k, timeZone) vẫn có trường hợp sai VD trong file đính kèm
    (NgDL bất kỳ đang là tháng âm lịch nào thì hàm getNewMoonDay(k, timeZone) trả về ngày dương lịch là ngày mùng 1 tháng âm lịch đó)
  2. getSunLongitude(jdn, timeZone)
    (Tính tọa độ mặt trời - Giúp cho việc xác định tháng nào nhuận trong năm nhuận)
  3. getLeapMonthOffset(yy, timeZone)
    (Xác định tháng nhuận)
  4. convertLunar2Solar(lunarDay, lunarMonth, lunarYear, lunarLeap, timeZone)
    (Đổi ngày AL sang ngày DL)
File đính kèm chuyển xuống bài #16
 
Lần chỉnh sửa cuối:
Upvote 0
Web KT

Bài viết mới nhất

Back
Top Bottom