計算日落日出時間演算法與程式碼
演算法:
怎樣用經緯度計算日出日落的時間
下面是一種隨經緯度變化的日出日落時間計算方法,我成功運用在一智慧路燈控制器中,希望對需要的朋友有幫助。
已知:日出日落時太陽的位置h=-0.833°,要計算地的地理位置,經度Long,緯度G1at,時區zone,UTo為上次計算的日出日落時間,第一次計算時UTo=180°。
(1)先計算出從格林威治時間公元2000年1月1日到計算日天數days;
(2)計算從格林威治時間公元2000年1月1日到計算日的世紀數t, 則t=(days+UTo/360)/36525;
(3)計算太陽的平黃徑 : L=280.460+36000.770×t;
(4)計算太陽的平近點角 :
(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)計算新的日出日落時間 :UT=UTo-(GHA+Long±e);
(11)比較UTo和UT之差的絕對值,如果大於0.1°即0.007小時,把UT作為新的日出日落時間值,重新從第(2)步開始進行迭代計算,如果UTo和UT之差的絕對值小於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];