日落/日出时间计算异常:祈祷时间程序公式疑存问题
祈祷时间计算程序的错误排查
我正在开发一款祈祷时间计算程序,代码逻辑看似正确,但计算结果始终存在错误。目前怀疑问题出在三角函数(sin相关)调用、日出/日落时间公式以及正午太阳峰值时间的计算上。以下是对应的Java代码:
public void onLocationChanged(Location loc) { GPSEnlem = loc.getLatitude(); GPSBoylam = loc.getLongitude(); String Text = "Bulunduğunuz konum bilgileri : \n" + "Latitud = " + loc.getLatitude() + "\nLongitud = " + loc.getLongitude(); konumText.setText(Text); String pattern = "dd_MM_yyyy"; SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern); String date = simpleDateFormat.format(new Date()); String day = date.substring(0, 1); String month = date.substring(3, 4); String year = date.substring(6, 9); double dayy = Double.valueOf(day); double monthh = Double.valueOf(month); double yearr = Double.valueOf(year); double I = yearr; double J = monthh; double K = dayy; double jd = 665176 + (1461 * (I + 4800 + (J - 14) / 12)) / 4 + (367 * (J - 2 - 12 * ((J - 14) / 12))) / 12 - (3 * ((I + 4900 + (J - 14) / 12) / 100)) / 4 + K - 32075; double d = jd - 2451545; // jd verilen Jülyen tarihidir double g = 357.529 + 0.98560028 * d; double q = 280.459 + 0.98564736 * d; double L = q + 1.915 * sin(Math.toRadians(g)) + 0.020 * sin(Math.toRadians(2 * g)); double R = 1.00014 - 0.01671 * cos(Math.toRadians(g)) - 0.00014 * cos(Math.toRadians(2 * g)); double e = 23.439 - 0.00000036 * d; double RA = atan2(cos(Math.toRadians(e)) * sin(Math.toRadians(L)), cos(Math.toRadians(L))) / 15; double D = asin(sin(Math.toRadians(e)) * sin(Math.toRadians(L))); // Güneş'in sapması double EqT = q / 15 - RA; // zaman denklemi double Lng = 30.0; double Ltd = 39.0; double SaatDilimi = 3; double oglevakti = 12.0 + SaatDilimi - (Lng / 15.0) - EqT; double a = 0; double n = d; double Jk = n - (Lng / 360.0); double M = (357.5291 + 0.98560028 * Jk) % 360.0; double C = 1.9148 * sin(M) + 0.0200 * sin(2.0 * M) + 0.0003 * sin(3.0 * M); double lambda = (M + C + 180 + 102.9372) % 360.0; double si = asin(sin(lambda) * sin(23.4397)); double Ta = (acos(-sin(a) - sin(Ltd) * sin(si))) / 15.0; double T0833 = acos(-sin(0.833) - sin(GPSEnlem) * sin(si)) / 15.0; double T17 = acos(Math.toRadians(-sin(17) - sin(GPSEnlem) * sin(si))) / 15.0; double T18 = acos(Math.toRadians(-sin(18) - sin(GPSEnlem) * sin(si))) / 15.0; double gunesvakti = oglevakti - T0833; double aksamvakti = oglevakti + T0833; double imsakvakti = oglevakti - T18; double yatsivakti = oglevakti + T17; double AL = 2 + abs(tan(GPSEnlem) - si); double A2 = 1 / AL; double ikindivakti = oglevakti + A2; }
核心错误点与修正建议
日期解析逻辑错误
代码中通过substring截取日期时范围错误:day = date.substring(0, 1)只能获取单日数字(如10号会被截成1),应改为substring(0, 2)month = date.substring(3, 4)同理,应改为substring(3, 5)year = date.substring(6, 9)只能获取3位年份(如2024会被截成202),应改为substring(6, 10)
修正后才能正确解析多位数的日、月和完整年份。
三角函数参数未转弧度
Java的Math.sin()、Math.cos()等方法要求参数为弧度值,但代码中多处直接传入角度值:- 计算
C时:sin(M)、sin(2.0 * M),需改为sin(Math.toRadians(M))、sin(Math.toRadians(2.0 * M)) - 计算
si时:sin(lambda)、sin(23.4397),需改为sin(Math.toRadians(lambda))、sin(Math.toRadians(23.4397)) - 计算
T0833时:sin(0.833),需改为sin(Math.toRadians(0.833))(0.833是太阳高度角的度数)
- 计算
硬编码经纬度,未使用GPS数据
代码中硬写了Lng = 30.0、Ltd = 39.0,但实际应该使用获取到的GPSBoylam(经度)和GPSEnlem(纬度),否则计算结果不会随定位变化。Fajr/Isha时间的公式错误
目前T17、T18的写法完全错误:- 错误地将整个
acos参数用Math.toRadians()包裹,实际上应该是先将角度值转为弧度计算正弦值 - 正确的公式应为:
cos(T) = (sin(h0) - sin(lat)*sin(decl)) / (cos(lat)*cos(decl)),其中h0是太阳高度角(Fajr取-18°,Isha取-17°)
修正示例(以Fajr为例):
double h0 = -18; // Fajr的太阳高度角 double sinH0 = Math.sin(Math.toRadians(h0)); double sinLat = Math.sin(Math.toRadians(GPSEnlem)); double cosLat = Math.cos(Math.toRadians(GPSEnlem)); double sinDecl = Math.sin(si); // si是赤纬,需确保之前已转弧度计算 double cosDecl = Math.cos(si); double cosT = (sinH0 - sinLat * sinDecl) / (cosLat * cosDecl); double T18 = Math.acos(cosT) / 15.0;- 错误地将整个
正午时间(oglevakti)计算错误
公式中使用了硬编码的Lng,应替换为实际的GPSBoylam;同时需确保EqT(时差)的计算正确,RA(赤经)需要调整到0-24小时范围内,避免负数或超过24的情况。Asr时间(ikindivakti)公式错误
当前代码中的AL = 2 + abs(tan(GPSEnlem) - si)完全不符合Asr的计算逻辑。Asr的标准公式基于影子长度,比如:// 标准Asr(1倍影子) double tanTheta = Math.tan(Math.toRadians(90 - Math.abs(GPSEnlem - si))); double cosT = -Math.tan(Math.toRadians(GPSEnlem)) * Math.sin(si) - tanTheta; double asrT = Math.acos(cosT) / 15.0; double ikindivakti = oglevakti + asrT;
内容的提问来源于stack exchange,提问作者oseyfo4664
相关产品推荐
相关产品推荐

