You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

日落/日出时间计算异常:祈祷时间程序公式疑存问题

祈祷时间计算程序的错误排查

我正在开发一款祈祷时间计算程序,代码逻辑看似正确,但计算结果始终存在错误。目前怀疑问题出在三角函数(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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 05:27:03