qq_35660280 2017-05-13 03:36 采纳率: 100%
浏览 3073
已采纳

java如何根据经纬度和日期获取当地日出日落时间?

要求:
(1)用java编写
(2)输入是 经纬度 和 日期
(3)输出是日出时间和日落时间
急求代码 感谢

  • 写回答

2条回答 默认 最新

  • qq_35660280 2017-06-18 11:29
    关注

    java写的我找不到 但是我找到了c语言的 要改成java 应该不难 我c语言版本的也能用 有需要的自己改一下吧

    下面我分享一下c语言版本的 我测试 误差在几分钟之内 很好用

    #include
    #include
    #include
    #include "math.h"
    #include "time.h"

    define M_PI 3.14159265358979323846

    static double RAD = 180.0 * 3600 / M_PI;
    static double richu;
    static double midDayTime;
    static double dawnTime;
    static double jd;
    static double wd;
    static double jd_degrees;
    static double jd_minutes;
    static double jd_seconds;
    static double wd_degrees;
    static double wd_minutes;
    static double wd_seconds;
    /*************************

    • 儒略日的计算 *
    • @param y 年 *
    • @param M 月 *
    • @param d 日 *
    • @param h 小时 *
    • @param m 分 *
    • @param s秒 *
    • @return int
      ***************************/
      static double timeToDouble(int y, int M, double d)
      {
      // double A=0;
      double B = 0;
      double jd = 0;

      //设Y为给定年份,M为月份,D为该月日期(可以带小数)。
      //若M > 2,Y和M不变,若 M =1或2,以Y–1代Y,以M+12代M,换句话说,如果日期在1月或2月,则被看作是在前一年的13月或14月。
      //对格里高利历有 :A = INT(Y/100) B = 2 - A + INT(A/4)
      //对儒略历,取 B = 0
      //JD = INT(365.25(Y+4716))+INT(30.6001(M+1))+D+B-1524.5 (7.1)
      B = -13;
      jd = floor(365.25 * (y + 4716)) + floor(30.60001 * (M + 1)) + B + d - 1524.5;
      return jd;
      }

    static void doubleToStr(double time, char *str)
    {
    double t;
    int h, m, s;

    t = time + 0.5;
    t = (t - (int)t) * 24;
    h = (int)t;
    t = (t - h) * 60;
    m = (int)t;
    t = (t - m) * 60;
    s = (int)t;
    
    sprintf(str, "%02d:%02d:%02d", h, m, s);
    

    }

    /****************************

    • @param t 儒略世纪数 *
    • @return 太阳黄经 *****************************/ static double sunHJ(double t) { double j; t = t + (32.0 * (t + 1.8) * (t + 1.8) - 20) / 86400.0 / 36525.0; // 儒略世纪年数,力学时 j = 48950621.66 + 6283319653.318 * t + 53 * t * t - 994 + 334166 * cos(4.669257 + 628.307585 * t) + 3489 * cos(4.6261 + 1256.61517 * t) + 2060.6 * cos(2.67823 + 628.307585 * t) * t; return (j / 10000000); }

    static double mod(double num1, double num2)
    {
    num2 = fabs(num2);
    // 只是取决于Num1的符号
    return num1 >= 0 ? (num1 - (floor(num1 / num2)) * num2) : ((floor(fabs(num1) / num2)) * num2 - fabs(num1));
    }
    /********************************

    • 保证角度∈(-π,π) *
    • @param ag
    • @return ag ***********************************/ static double degree(double ag) { ag = mod(ag, 2 * M_PI); if (ag <= -M_PI){ ag = ag + 2 * M_PI; } else if (ag>M_PI){ ag = ag - 2 * M_PI; } return ag; }

    /***********************************
    *

    • @param date 儒略日平午 *
    • @param lo 地理经度 *
    • @param la 地理纬度 *
    • @param tz 时区 *
    • @return 太阳升起时间
      *************************************/
      double sunRiseTime(double date, double lo, double la, double tz)
      {
      double t, j, sinJ, cosJ, gst, E, a, D, cosH0, cosH1, H0, H1, H;
      date = date - tz;
      // 太阳黄经以及它的正余弦值
      t = date / 36525;
      j = sunHJ(t);
      // 太阳黄经以及它的正余弦值
      sinJ = sin(j);
      cosJ = cos(j);
      // 其中2*M_PI*(0.7790572732640 + 1.00273781191135448*jd)恒星时(子午圈位置)
      gst = 2 * M_PI * (0.779057273264 + 1.00273781191135 * date) + (0.014506 + 4612.15739966 * t + 1.39667721 * t * t) / RAD;
      E = (84381.406 - 46.836769 * t) / RAD; // 黄赤交角
      a = atan2(sinJ * cos(E), cosJ);// '太阳赤经
      D = asin(sin(E) * sinJ); // 太阳赤纬
      cosH0 = (sin(-50 * 60 / RAD) - sin(la) * sin(D)) / (cos(la) * cos(D)); // 日出的时角计算,地平线下50分
      cosH1 = (sin(-6 * 3600 / RAD) - sin(la) * sin(D)) / (cos(la) * cos(D)); // 天亮的时角计算,地平线下6度,若为航海请改为地平线下12度
      // 严格应当区分极昼极夜,本程序不算
      if (cosH0 >= 1 || cosH0 <= -1){
      return -0.5;// 极昼
      }
      H0 = -acos(cosH0); // 升点时角(日出)若去掉负号 就是降点时角,也可以利用中天和升点计算
      H1 = -acos(cosH1);
      H = gst - lo - a; // 太阳时角
      midDayTime = date - degree(H) / M_PI / 2 + tz; // 中天时间
      dawnTime = date - degree(H - H1) / M_PI / 2 + tz;// 天亮时间
      return date - degree(H - H0) / M_PI / 2 + tz; // 日出时间,函数返回值
      }
      void input_gJD(int c[]){

      int i;

      printf("Enter the degree of longitude(form: 40 40 (means 40°40′40″)):");
      for (i = 0; i<3; i++){

      scanf("%d", &c[i]);
      

      }
      for (i = 0; i < 3; i++){
      printf("< %d>", c[i]);
      };
      printf("\n");
      }

    //输入经度

    void input_gWD(int c[]){

    int i;
    
    printf("Enter the degree of latitude(form: 40 40 40 (means 40°40′40″)):");
    for (i = 0; i<3; i++){
    
        scanf("%d",&c[i]);
    
    }
    for (i = 0; i < 3; i++){
        printf( "< %d>",c[i]);
    };
    printf("\n");
    

    }

    //输入经度
    void input_date(int c[]){

    int i;
    
    printf("Enter the date (form: 2009 03 10):"); 
    
    for (i = 0; i<3; i++){
    
        scanf("%d",&c[i]);
    
    }
    

    }

    //输入日期

    int main()
    {

    time_t curtime;
    struct tm * timeinfo;
    //int i, j, k;
    char timestr[20];
    int year;
    int month;
    int day;
    //int hour;
    //int min;
    //int sec;
    int tz;
    int c[3];
    //FILE *fp;
    
    
    //上海东经121度29分,北纬31度14分
    //jd_degrees = 121;
    //jd_seconds = 28;
    //wd_degrees = 31;
    //wd_seconds = 14;
    //乌鲁木齐东经87度35分,北纬43度48分
    //jd_degrees=87;
    //jd_seconds=35;
    //wd_degrees=43;
    //wd_seconds=48;
    //广州 E113°16' N23°06'
    
    input_gJD(c);
    jd_degrees = c[0];
    jd_minutes = c[1];
    jd_seconds = c[2];
    
    input_gWD(c);
    wd_degrees = c[0];
    wd_minutes = c[1];
    wd_seconds = c[2];
    
    tz = 8;
    
    //得到当前时间
    time(&curtime);
    timeinfo = localtime(&curtime);
    //printf("The current date/time is: %s", asctime(timeinfo));
    
    //step 1
    jd = -(jd_degrees + jd_minutes / 60+jd_seconds/3600) / 180 * M_PI;
    wd = (wd_degrees +wd_minutes/60+ wd_seconds / 3600) / 180 * M_PI;
    //printf("将输出经纬度的语句注释掉\n");
    //printf("jd=%f\r\n", jd);
    //printf("wd=%f\r\n", wd);;
    
    //step 2
    input_date(c);
    
    year = c[0];
    
    month = c[1];
    
    day = c[2];
    //year = timeinfo->tm_year + 1900;
    //month = timeinfo->tm_mon + 1;
    //day = timeinfo->tm_mday;
    //hour = timeinfo->tm_hour;
    //min = timeinfo->tm_min;
    

    // sec = timeinfo->tm_sec;
    richu = timeToDouble(year, month, day) - 2451544.5;
    //printf("mjd:%f\r\n", richu);
    printf("%d年%d月%d日\r\n", year, month, day);
    for (int i = 0; i < 10; i++){
    //时区在此处运用,可以根据经纬度算出 ,也是整型
    richu = sunRiseTime(richu, jd, wd, tz / 24.0);// 逐步逼近法算10次
    }

    doubleToStr(richu, timestr);
    printf("日出时间 %s\r\n", timestr);
    
    doubleToStr(midDayTime + midDayTime - richu, timestr);
    printf("日落时间 %s\r\n", timestr);
    //printf("richu:%f,midDayTime:%f\r\n", richu, midDayTime);
    
    /*doubleToStr(midDayTime, timestr);
    printf("中天时间 %s\r\n", timestr);
    
    doubleToStr(dawnTime, timestr);
    printf("天亮时间 %s\r\n", timestr);
    
    doubleToStr(midDayTime + midDayTime - dawnTime, timestr);
    printf("天黑时间 %s\r\n", timestr);
    
    
    fp = fopen("richu.txt", "w");
    if (fp == NULL){
    printf("file open error\r\n");
    }
    /*
    //char fst[]={"日出                                           日落\n"};
    char str[50];
    char m2012[12]={31,29,31,30,31,30,31,31,30,31,30,31};   //2012
    //fputs(fst,fp);
    
    for(i=0;i<12;i++){
    for(j=1;j<=m2012[i];j++){
    year=2012;
    month=i+1;
    day=j;
    richu = timeToDouble(year,month,day*1.0) - 2451544.5;
    for (k = 0; k < 10; k++){
    richu = sunRiseTime(richu, jd, wd, tz/24.0);// 逐步逼近法算10次
    }
    
    sprintf(str,"%d-%02d-%02d    ",year,month,(int)day);
    doubleToStr(richu,timestr);
    strcat(str,timestr);
    strcat(str,"       ");
    
    doubleToStr(midDayTime + midDayTime - richu,   timestr);
    strcat(str,timestr);
    strcat(str,"\n");
    
    fputs(str,fp);
    }
    }
    */
    //fclose(fp);
    //printf("Hello world!\n");
    return 0;
    

    }

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 关于#Mybatis#的问题:怎么办重复数据如下"KSDM":37,"KSMC":"呼吸内科门诊","ksdm":37,"ksmc":"呼吸内科门诊"xml文件填写
  • ¥40 servlet的web程序部署出错
  • ¥50 activiti 新建流程系列问题
  • ¥50 为什么我版本升级之后运行速度变慢5倍??
  • ¥15 如何在gazebo中加载机械臂和机械手
  • ¥15 纯运放实现隔离采样方案设计
  • ¥20 easyconnect无法连接后缀带.com的网站,一直显示找不到服务器ip地址,但是带有数字的网站又是可以连接上的,如何解决
  • ¥15 电脑开机过商标后就直接这样,求解各位
  • ¥15 mysql , 用自己创建的本地主机和用户名 登录不上
  • ¥15 关于#web项目#的问题,请各位专家解答!