Browse Source

feat: 일출일몰 시간계산 유틸추가

pull/17/head
lkd9125(이경도) 8 months ago
parent
commit
d767b3a6b5
  1. 130
      pav-server/src/main/java/com/palnet/comn/utils/SunRiseUtils.java

130
pav-server/src/main/java/com/palnet/comn/utils/SunRiseUtils.java

@ -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…
Cancel
Save