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
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)
2- Đổi số Jd (Julian day number) ra ngày dương lịch
3- Tìm ngày Sóc
4- Tính tọa độ mặt trời
5- Tìm ngày 1-11 âm lịch
6- Xác định tháng âm lịch nhuận
7- Đổi ngày đương lịch ra ngày âm lịch
8- Đổi ngày âm lịch ra ngày dương lịch
File đính kèm trong bài #15
- 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
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
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
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
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
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
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
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
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: