1. 程式人生 > >計算日落日出時間演算法與程式碼

計算日落日出時間演算法與程式碼

演算法:

怎樣用經緯度計算日出日落的時間

下面是一種隨經緯度變化的日出日落時間計算方法,我成功運用在一智慧路燈控制器中,希望對需要的朋友有幫助。 

已知:日出日落時太陽的位置h-0.833°,要計算地的地理位置,經度Long,緯度G1at,時區zone,UTo為上次計算的日出日落時間,第一次計算時UTo180°。 

(1)先計算出從格林威治時間公元200011日到計算日天數days; 
(2)
計算從格林威治時間公元200011日到計算日的世紀數t, t(days+UTo360)36525; 
(3)
計算太陽的平黃徑 : L=280.460+36000.770×t; 
(4)
計算太陽的平近點角 :

G357.528+35999.050×t 
(5)
計算太陽的黃道經度 :λL+1.915×sinG+0.020xsin(2G); 
(6)
計算地球的傾角     ε23.4393-0.0130×t; 
(7)
計算太陽的偏差     δarcsin(sinε×sinλ); 
(8)
計算格林威治時間的太陽時間角GHA: GHA=UTo-180-1.915×sinG-0.020×sin(2G)   +2.466×sin(2λ)-0.053×sin(4λ) 
(9)
計算修正值e: e=arcos{[   sinh-sin(Glat)sin(δ)]/cos(Glat)cos(δ)} 
(10)
計算新的日出日落時間 :UTUTo-(GHA+Long±e); 
其中“+”表示計算日出時間,“-”表示計算日落時間
(11)
比較UToUT之差的絕對值,如果大於0.1°0.007小時,UT作為新的日出日落時間值,重新從第(2)步開始進行迭代計算,如果UToUT之差的絕對值小於0.007小時,UT即為所求的格林威治日出日落時間
(12)
上面的計算以度為單位,180°=12小時,因此需要轉化為以小時表示的時間,再加上所在的時區數Zone,即要計算地的日出日落時間為 :T=UT/15+Zone 
上面的計算日出日落時間方法適用於小於北緯60°和南緯60°之間的區域,如果計算位置為西半球時,經度Long為負數。

Java程式碼:

public class SunRiseSet {

private static int[] days_of_month_1={31,28,31,30,31,30,31,31,30,31,30,31};

private static int[] days_of_month_2={31,29,31,30,31,30,31,31,30,31,30,31};

privatefinalstaticdoubleh= -0.833;//日出日落時太陽的位置

privatefinalstaticdoubleUTo=180.0;//上次計算的日落日出時間,初始迭代值180.0

//輸入日期

//輸入經緯度

//判斷是否為閏年:若為閏年,返回1;若不是閏年,返回0

public static boolean leap_year(int year){ 

    if(((year%400==0) || (year%100!=0) && (year%4==0))) return true

elsereturnfalse

//求從格林威治時間公元2000年1月1日到計算日天數days 

public static int days(int year, int month, int date){  

    int i,a=0;  

    for(i=2000;i<year;i++){  

        if(leap_year(i)) a=a+366;  

        else a=a+365;  

    }  

    if(leap_year(year)){  

        for(i=0;i<month-1;i++){ 

            a=a+days_of_month_2[i];  

        } 

    }else {  

        for(i=0;i<month-1;i++){ 

            a=a+days_of_month_1[i]; 

        }  

    }  

    a=a+date;  

    return a;  

}

//求格林威治時間公元2000年1月1日到計算日的世紀數t 

public static double t_century(int days,  double UTo){  

    return ((double)days+UTo/360)/36525;  

//求太陽的平黃徑

public static double L_sun(double t_century){  

    return (280.460+36000.770*t_century);  

}

//求太陽的平近點角

public static double G_sun(double t_century){  

    return (357.528+35999.050*t_century);  

}

//求黃道經度

public static double ecliptic_longitude(double L_sun,double G_sun){  

    return (L_sun+1.915*Math.sin(G_sun*Math.PI/180)+0.02*Math.sin(2*G_sun*Math.PI/180)); 

}

//求地球傾角

public static double earth_tilt(double t_century){  

    return (23.4393-0.0130*t_century);  

//求太陽偏差

public static double sun_deviation(double earth_tilt,double ecliptic_longitude){  

    return (180/Math.PI*Math.asin(Math.sin(Math.PI/180*earth_tilt)*Math.sin(Math.PI/180*ecliptic_longitude)));  

}

//求格林威治時間的太陽時間角GHA

public static double GHA(double UTo,double G_sun,double ecliptic_longitude){  

    return (UTo-180-1.915*Math.sin(G_sun*Math.PI/180)-0.02*Math.sin(2*G_sun*Math.PI/180)+2.466*Math.sin(2*ecliptic_longitude*Math.PI/180)-0.053*Math.sin(4*ecliptic_longitude*Math.PI/180)); 

//求修正值e

publicstaticdouble e(double h,double glat,double sun_deviation){  

    return 180/Math.PI*Math.acos((Math.sin(h*Math.PI/180)-Math.sin(glat*Math.PI/180)*Math.sin(sun_deviation*Math.PI/180))/(Math.cos(glat*Math.PI/180)*Math.cos(sun_deviation*Math.PI/180)));  

//求日出時間

publicstaticdouble UT_rise(double UTo,double GHA,double glong,double e){  

    return (UTo-(GHA+glong+e));  

//求日落時間

publicstaticdouble UT_set(double UTo,double GHA,double glong,double e){  

    return (UTo-(GHA+glong-e)); 

}

//判斷並返回結果(日出)

public static double result_rise(double UT,double UTo,double glong, double glat, int year, int month, int date){  

    double d;  

    if(UT>=UTo) d=UT-UTo;  

    else d=UTo-UT;  

    if(d>=0.1) {  

        UTo=UT;  

        UT=UT_rise(UTo,

            GHA(UTo,G_sun(t_century(days(year,month,date),UTo)),

                   ecliptic_longitude(L_sun(t_century(days(year,month,date),UTo)),

                   G_sun(t_century(days(year,month,date),UTo)))),

        glong,

        e(h,glat,sun_deviation(earth_tilt(t_century(days(year,month,date),UTo)),

           ecliptic_longitude(L_sun(t_century(days(year,month,date),UTo)),

           G_sun(t_century(days(year,month,date),UTo))))));  

        result_rise(UT,UTo,glong,glat,year,month,date); 

    }  

    return UT;  

//判斷並返回結果(日落)

public static double result_set(double UT,double UTo,double glong,double glat, int year, int month, int date){  

    double d;  

    if(UT>=UTo) d=UT-UTo;  

    else d=UTo-UT;  

    if(d>=0.1){  

        UTo=UT;  

        UT=UT_set(UTo,

         GHA(UTo,G_sun(t_century(days(year,month,date),UTo)),

         ecliptic_longitude(L_sun(t_century(days(year,month,date),UTo)),

         G_sun(t_century(days(year,month,date),UTo)))),

         glong,

         e(h,glat,sun_deviation(earth_tilt(t_century(days(year,month,date),UTo)),

         ecliptic_longitude(L_sun(t_century(days(year,month,date),UTo)),

         G_sun(t_century(days(year,month,date),UTo))))));  

        result_set(UT,UTo,glong,glat,year,month,date);  

    }  

    return UT;  

}

//求時區

public static int Zone(double glong){  

    if(glong>=0) return (int)((int)(glong/15.0)+1);  

    else return (int)((int)(glong/15.0)-1); 

//列印結果 

//public static void output(double rise, double set, double glong){  

//    if((int)(60*(rise/15+Zone(glong)-(int)(rise/15+Zone(glong))))<10)  

//        System.out.println("The time at which the sunrise is: "+(int)(rise/15+Zone(glong))+":"+(int)(60*(rise/15+Zone(glong)-(int)(rise/15+Zone(glong))))+" .\n");  

//    else System.out.println("The time at which the sunrise is: "+(int)(rise/15+Zone(glong))+":"+(int)(60*(rise/15+Zone(glong)-(int)(rise/15+Zone(glong))))+" .\n");

//     

//    if((int)(60*(set/15+Zone(glong)-(int)(set/15+Zone(glong))))<10) 

//        System.out.println("The time at which the sunset is: "+(int)(set/15+Zone(glong))+": "+(int)(60*(set/15+Zone(glong)-(int)(set/15+Zone(glong))))+" .\n"); 

//    else System.out.println("The time at which the sunset is: "+(int)(set/15+Zone(glong))+":"+(int)(60*(set/15+Zone(glong)-(int)(set/15+Zone(glong))))+" .\n"); 

//} 

public static String getSunrise(GeoPoint geoPoint,Time sunTime){

double sunrise,glong,glat;

int year,month,date;

year=sunTime.year;

month=sunTime.month;

date=sunTime.monthDay;

glong=geoPoint.getLongitude();

glat=geoPoint.getLatitude();

sunrise=result_rise(UT_rise(UTo,

                 GHA(UTo,G_sun(t_century(days(year,month,date),UTo)),

                        ecliptic_longitude(L_sun(t_century(days(year,month,date),UTo)),

                        G_sun(t_century(days(year,month,date),UTo)))),

            glong,

            e(h,glat,sun_deviation(earth_tilt(t_century(days(year,month,date),UTo)),

            ecliptic_longitude(L_sun(t_century(days(year,month,date),UTo)),

        G_sun(t_century(days(year,month,date),UTo)))))),UTo,glong,glat,year,month,date);

//System.out.println("Sunrise is: "+(int)(sunrise/15+Zone(glong))+":"+(int)(60*(sunrise/15+Zone(glong)-(int)(sunrise/15+Zone(glong))))+" .\n");

Log.d("Sunrise""Sunrise is: "+(int)(sunrise/15+8)+":"+(int)(60*(sunrise/15+8-(int)(sunrise/15+8)))+" .\n");

//return "Sunrise is: "+(int)(sunrise/15+Zone(glong))+":"+(int)(60*(sunrise/15+Zone(glong)-(int)(sunrise/15+Zone(glong))))+" .\n";

        return "Sunrise is: "+(int)(sunrise/15+8)+":"+(int)(60*(sunrise/15+8-(int)(sunrise/15+8)))+" .\n";

}

public static String getSunset(GeoPoint geoPoint,Time sunTime){

double sunset,glong,glat;

int year,month,date;

year=sunTime.year;

month=sunTime.month;

date=sunTime.monthDay;

glong=geoPoint.getLongitude();

glat=geoPoint.getLatitude();

sunset=result_set(UT_set(UTo,

                GHA(UTo,G_sun(t_century(days(year,month,date),UTo)),

                  ecliptic_longitude(L_sun(t_century(days(year,month,date),UTo)),

              G_sun(t_century(days(year,month,date),UTo)))),

                glong,

                e(h,glat,sun_deviation(earth_tilt(t_century(days(year,month,date),UTo)),

                  ecliptic_longitude(L_sun(t_century(days(year,month,date),UTo)),

              G_sun(t_century(days(year,month,date),UTo)))))),UTo,glong,glat,year,month,date);

//System.out.println("The time at which the sunset is: "+(int)(sunset/15+Zone(glong))+":"+(int)(60*(sunset/15+Zone(glong)-(int)(sunset/15+Zone(glong))))+" .\n");

Log.d("Sunset""Sunset is: "+(int)(sunset/15+8)+":"+(int)(60*(sunset/15+8-(int)(sunset/15+8)))+" .\n");

//return "Sunset is: "+(int)(sunset/15+Zone(glong))+":"+(int)(60*(sunset/15+Zone(glong)-(int)(sunset/15+Zone(glong))))+" .\n";

       return "Sunset is: "+(int)(sunset/15+8)+":"+(int)(60*(sunset/15+8-(int)(sunset/15+8)))+" .\n";

}

} //SunRiseSet.getSunRise(GeoPoint geoPoint,Time sunTime),SunRiseSet.getSunSet(GeoPoint geoPoint,Time sunTime)算出的是北京時間下各地區日出日落時間表,計算當地時間的話,把時區8改為Zone(glong)即可。GeoPoint類是地理位置座標點類,構造器輸入是經緯度。

相關推薦

計算日落日出時間演算法程式碼

演算法: 怎樣用經緯度計算日出日落的時間 下面是一種隨經緯度變化的日出日落時間計算方法,我成功運用在一智慧路燈控制器中,希望對需要的朋友有幫助。  已知:日出日落時太陽的位置h=-0.833°,要計算地的地理位置,經度Long,緯度G1at,時區zone,UTo為上

Java常用的八種排序演算法程式碼實現(三):桶排序、計數排序、基數排序

三種線性排序演算法:桶排序、計數排序、基數排序 線性排序演算法(Linear Sort):這些排序演算法的時間複雜度是線性的O(n),是非比較的排序演算法 桶排序(Bucket Sort)   將要排序的資料分到幾個有序的桶裡,每個桶裡的資料再單獨進行排序,桶內排完序之後,再把桶裡的

Java常用的八種排序演算法程式碼實現(二):歸併排序法、快速排序法

注:這裡給出的程式碼方案都是通過遞迴完成的 --- 歸併排序(Merge Sort):   分而治之,遞迴實現   如果需要排序一個數組,我們先把陣列從中間分成前後兩部分,然後對前後兩部分進行分別排序,再將排好序的數組合並在一起,這樣整個陣列就有序了   歸併排序是穩定的排序演算法,時間

機器學習之logistic迴歸演算法程式碼實現

                                       Logistic迴歸演算法與程式

Java常用的八種排序演算法程式碼實現(一):氣泡排序法、插入排序法、選擇排序法

這三種排序演算法適合小規模資料排序 ---   共同點:基於比較,時間複雜度均為O(n2),空間複雜度均為O(1)(原地排序演算法)   不同點:插入排序和氣泡排序是穩定的排序演算法,選擇排序不是 ---   穩定排序演算法:可以保持數值相等的兩個物件,在排序之

機器學習之樸素貝葉斯演算法程式碼實現

                                    樸素貝葉斯演算法與程式碼實現 演算法原理 樸素貝葉斯是經典的機器學習演算法之一,也是為數不多的基於概率論的分類演算法。樸素貝葉斯原理簡單,也很容易實現,多用於文字分類,比如垃圾郵件過濾。 該演算法的優點在於簡單易懂、學習效率高、在某些領

Java常用的八種排序演算法程式碼實現(一)

本文需要5分鐘左右閱讀完成,建議收藏以後閱讀,裡面都是乾貨,可以親自試驗一下,如果覺得好用可以幫忙點贊轉發一下,謝謝!交流學習java大資料可以加群460570824。 1.直接插入排序 經常碰到這樣一類排序問題:把新的資料插入到已經排好的資料列中。 將第一個數和第二個數

一遍記住Java常用的八種排序演算法程式碼實現

1.直接插入排序 經常碰到這樣一類排序問題:把新的資料插入到已經排好的資料列中。 將第一個數和第二個數排序,然後構成一個有序序列將第三個數插入進去,構成一個新的有序序列。對第四個數、第五個數……直到最後一個數,重複第二步。 如何寫寫成程式碼: 首先設定插入次數,即迴圈

Java 常用的八種排序演算法程式碼實現

寫排序演算法是一個大工程,估計得好多天才可以寫完。。。就慢慢寫吧。未完待續。。。。 內部排序和外部排序 內部排序是資料記錄在記憶體中進行排序,而外部排序是因排序的資料很大,一次不能容納全部的排序記錄,在排序過程中需要訪問外存。 我們這裡說說八大排序就是

Java常用的八種排序演算法程式碼實現--轉載

1.直接插入排序      我們經常會到這樣一類排序問題:把新的資料插入到已經排好的資料列中。將第一個數和第二個數排序,然後構成一個有序序列將第三個數插入進去,構成一個新的有序序列。對第四個數、第五個數……直到最後一個數,重複第二步。如題所示:直接插入排序(Straight

秦九韶演算法的思想解多項式演算法時間比較附程式碼

多項式計算之秦九韶演算法 多項式求值與秦九韶演算法 一、引言   多項式函式常常用於描述現實世界的各種規律,而在用計算機計算多項式

Error Based Pruning剪枝演算法程式碼實現舉例

EBP(Error Based Pruning): 下列演算法轉載自連結: https://login.sina.com.cn/crossdomain2.php?action=login&entry=blog&r=http%3A%2F%2Fblog.sina.com.cn%2

演算法平行計算常規

利用平行計算機實現軟體和硬體上的並行演算法的主要步驟和層次 第5層是指應用層,在這一層裡描述的是需要平行計算平臺實現的應用和問題。對應所需的輸入和輸出的格式也在這層進行定義。某些輸入和輸出(I/O)介面的描述還需要考慮資料儲存的位置和時間的相關性。這一層的結果會被更

程式設計師程式碼面試指南:IT名企演算法資料結構題目最優解

網站 更多書籍點選進入>> CiCi島 下載 電子版僅供預覽及學習交流使用,下載後請24小時內刪除,支援正版,喜歡的請購買正版書籍 電子書下載(皮皮雲盤-點選“普通下載”) 購買正版 封頁 編輯推薦 如何在IT名企的面試中脫穎

機器學習系列文章:Apriori關聯規則分析演算法原理分析程式碼實現

1.關聯規則淺談     關聯規則(Association Rules)是反映一個事物與其他事物之間的相互依存性和關聯性,如果兩個或多個事物之間存在一定的關聯關係,那麼,其中一個事物就能通過其他事物預測到。關聯規則是資料探勘的一個重要技術,用於從大量資料中挖掘出有價值的資料

演算法資料結構專場】BitMap演算法基本操作程式碼實現

上篇我們講了BitMap是如何對資料進行儲存的,沒看過的可以看一下【演算法與資料結構專場】BitMap演算法介紹 這篇我們來講一下BitMap這個資料結構的程式碼實現。 回顧下資料的儲存原理 一個二進位制位對應一個非負數n,如果n存在,則對應的二進位制位的值為1,否則為0。這個時候,我們的第一個問題:我們在

python 計算時間差,時間加減運算程式碼

如何方便的計算兩個時間的差,如兩個時間相差幾天,幾小時等 使用datetime模組可以很方便的解決這個問題,舉例如下: import datetime d1 = datetime.datetime(20

Linux學習筆記(演算法資料結構)之 佇列程式碼(C語言)

1、程式碼在VS2010的C++編譯器中編譯通過,可能有極少部分語法不符合C89標準;bool型別無法使用,用int代替 2、由於VS配置問題,沒有分.c和.h檔案書寫;如果要分,最好將Create_Node和Destory_Node加上static關鍵字修飾,他們只會在所

Linux學習筆記(演算法資料結構)之 二叉搜尋樹程式碼(C語言)

1、程式碼在VS2010的C++編譯器中編譯通過,可能有極少部分語法不符合C99標準;bool型別無法使用,用int代替 2、由於VS配置問題,沒有分.c和.h檔案書寫;如果要分,最好將Create_Node和Destory_Node加上static關鍵字修飾,他們只會在所

Dijkstra演算法Floyed程式碼詳解

一:Dijkstra演算法 詳解程式碼 #define INF 0x3f3f3f struct node { int L,W; }Map[MAX][MAX];//用鄰接矩陣表示圖,圖中每個元素含兩個值L,W;L為路徑長度,W為收費情況 int visit[MAX];