From d767b3a6b529cf89723edf6127beec5293c63532 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?lkd9125=28=EC=9D=B4=EA=B2=BD=EB=8F=84=29?= Date: Wed, 17 Jan 2024 17:21:13 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EC=9D=BC=EC=B6=9C=EC=9D=BC=EB=AA=B0=20?= =?UTF-8?q?=EC=8B=9C=EA=B0=84=EA=B3=84=EC=82=B0=20=EC=9C=A0=ED=8B=B8?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/palnet/comn/utils/SunRiseUtils.java | 130 ++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 pav-server/src/main/java/com/palnet/comn/utils/SunRiseUtils.java diff --git a/pav-server/src/main/java/com/palnet/comn/utils/SunRiseUtils.java b/pav-server/src/main/java/com/palnet/comn/utils/SunRiseUtils.java new file mode 100644 index 00000000..319d98ec --- /dev/null +++ b/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; + } + +}