lkd9125(이경도)
8 months ago
1 changed files with 130 additions and 0 deletions
@ -0,0 +1,130 @@ |
|||||||
|
package com.palnet.comn.utils; |
||||||
|
|
||||||
|
public class SunRiseUtils { |
||||||
|
|
||||||
|
public static String calculateSunriseSunset(int year, int month, int day, double longitude, double lati) { |
||||||
|
int sunriseH, sunrisem, sunsetH, sunsetm; |
||||||
|
|
||||||
|
double latitude = deg2rad(lati); |
||||||
|
double zenith = deg2rad(90.8333); // 일출일몰 계산, 시민박명:96.0, 항해박명:102.0, 천문박명:108.0
|
||||||
|
double timezone = 9.0; // KST +9H
|
||||||
|
|
||||||
|
// 1. first calculate the day of the year
|
||||||
|
int N = (int) (floor(275 * month / 9) - (floor((month + 9) / 12) * (1 + floor((year - 4 * floor(year / 4) + 2) / 3))) + day - 30); |
||||||
|
|
||||||
|
// 2. convert the longitude to hour value and calculate an approximate time
|
||||||
|
double lhour = longitude / 15; |
||||||
|
double tr = N + ((6 - lhour) / 24.0); // sunrise
|
||||||
|
double ts = N + ((18 - lhour) / 24.0); // sunrise
|
||||||
|
|
||||||
|
// 3. calculate the Sun's mean anomaly
|
||||||
|
double Mr = (0.9856 * tr) - 3.289; |
||||||
|
double Ms = (0.9856 * ts) - 3.289; |
||||||
|
|
||||||
|
// 4. calculate the Sun's true longitude
|
||||||
|
double Lr = Mr + (1.916 * sin(deg2rad(Mr))) + (0.020 * sin(deg2rad(2 * Mr))) + 282.634; |
||||||
|
double Ls = Ms + (1.916 * sin(deg2rad(Ms))) + (0.020 * sin(deg2rad(2 * Ms))) + 282.634; |
||||||
|
Lr = (Lr >= 0) ? fmod(Lr, 360) : fmod(Lr, 360) + 360.0; |
||||||
|
Ls = (Ls >= 0) ? fmod(Ls, 360) : fmod(Ls, 360) + 360.0; |
||||||
|
double lr = deg2rad(Lr); |
||||||
|
double ls = deg2rad(Ls); |
||||||
|
|
||||||
|
// 5a. calculate the Sun's right ascension
|
||||||
|
double RAr = rad2deg(atan(0.91764 * tan(lr))); |
||||||
|
double RAs = rad2deg(atan(0.91764 * tan(ls))); |
||||||
|
RAr = (RAr >= 0) ? fmod(RAr, 360) : fmod(RAr, 360) + 360.0; |
||||||
|
RAs = (RAs >= 0) ? fmod(RAs, 360) : fmod(RAs, 360) + 360.0; |
||||||
|
|
||||||
|
// 5b. right ascension value needs to be in the same quadrant as L
|
||||||
|
RAr += (floor(Lr / 90.0) * 90.0) - (floor(RAr / 90.0) * 90.0); |
||||||
|
RAs += (floor(Ls / 90.0) * 90.0) - (floor(RAs / 90.0) * 90.0); |
||||||
|
|
||||||
|
// 5c. right ascension value needs to be converted into hours
|
||||||
|
RAr /= 15; |
||||||
|
RAs /= 15; |
||||||
|
|
||||||
|
// 6. calculate the Sun's declination
|
||||||
|
double sindecr = 0.39782 * sin(lr); |
||||||
|
double sindecs = 0.39782 * sin(ls); |
||||||
|
double cosdecr = cos(Math.asin(sindecr)); |
||||||
|
double cosdecs = cos(Math.asin(sindecs)); |
||||||
|
|
||||||
|
// 7a. calculate the Sun's local hour angle
|
||||||
|
double cosHr = (cos(zenith) - (sindecr * sin(latitude))) / (cosdecr * cos(latitude)); |
||||||
|
double cosHs = (cos(zenith) - (sindecs * sin(latitude))) / (cosdecs * cos(latitude)); |
||||||
|
|
||||||
|
// 7b. finish calculating H and convert into hours
|
||||||
|
double Hr = 360.0 - rad2deg(acos(cosHr)); |
||||||
|
double Hs = rad2deg(acos(cosHs)); |
||||||
|
Hr /= 15; |
||||||
|
Hs /= 15; |
||||||
|
|
||||||
|
// 8. calculate local mean time of rising/setting
|
||||||
|
double Tr = Hr + RAr - (0.06571 * tr) - 6.622; |
||||||
|
double Ts = Hs + RAs - (0.06571 * ts) - 6.622; |
||||||
|
|
||||||
|
// 9. adjust back to UTC
|
||||||
|
double UTr = Tr - lhour; |
||||||
|
double UTs = Ts - lhour; |
||||||
|
UTr = (UTr >= 0) ? fmod(UTr, 24.0) : fmod(UTr, 24.0) + 24.0; |
||||||
|
UTs = (UTs >= 0) ? fmod(UTs, 24.0) : fmod(UTs, 24.0) + 24.0; |
||||||
|
|
||||||
|
// 10. convert UT value to local time zone of latitude/longitude
|
||||||
|
double localTr = fmod(UTr + timezone, 24.0); |
||||||
|
double localTs = fmod(UTs + timezone, 24.0); |
||||||
|
|
||||||
|
// last convert localT to human time
|
||||||
|
sunriseH = (int) floor(localTr); |
||||||
|
sunrisem = (int) ((localTr - sunriseH) * 60); |
||||||
|
sunsetH = (int) floor(localTs); |
||||||
|
sunsetm = (int) ((localTs - sunsetH) * 60); |
||||||
|
|
||||||
|
StringBuilder sb = new StringBuilder(); |
||||||
|
sb.append((sunriseH < 10 ? ("0"+sunriseH) : sunriseH)); |
||||||
|
sb.append((sunrisem < 10 ? ("0"+sunrisem) : sunrisem)); |
||||||
|
sb.append("00"); |
||||||
|
sb.append(" / "); |
||||||
|
sb.append((sunsetH < 10 ? ("0"+sunsetH) : sunsetH)); |
||||||
|
sb.append((sunsetm < 10 ? ("0"+sunsetm) : sunsetm)); |
||||||
|
sb.append("00"); |
||||||
|
|
||||||
|
return sb.toString(); |
||||||
|
} |
||||||
|
|
||||||
|
private static double deg2rad(double degree) { |
||||||
|
return degree * Math.PI / 180; |
||||||
|
} |
||||||
|
|
||||||
|
private static double rad2deg(double radian) { |
||||||
|
return radian * 180 / Math.PI; |
||||||
|
} |
||||||
|
|
||||||
|
private static double sin(double value) { |
||||||
|
return Math.sin(value); |
||||||
|
} |
||||||
|
|
||||||
|
private static double cos(double value) { |
||||||
|
return Math.cos(value); |
||||||
|
} |
||||||
|
|
||||||
|
private static double tan(double value) { |
||||||
|
return Math.tan(value); |
||||||
|
} |
||||||
|
|
||||||
|
private static double acos(double value) { |
||||||
|
return Math.acos(value); |
||||||
|
} |
||||||
|
|
||||||
|
private static double atan(double value) { |
||||||
|
return Math.atan(value); |
||||||
|
} |
||||||
|
|
||||||
|
private static double floor(double value) { |
||||||
|
return Math.floor(value); |
||||||
|
} |
||||||
|
|
||||||
|
private static double fmod(double x, double y) { |
||||||
|
return x % y; |
||||||
|
} |
||||||
|
|
||||||
|
} |
Loading…
Reference in new issue