js根据经纬度和时间计算出月初月落时间

<html>
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
	<style type="text/css">
	</style>
	<title>浏览器定位</title>
	
</head>

<body>


<p>月出月落时间分别为:</p>
<p> (  <span id="demo"></span>   )</p>
<script type="text/javascript">
/***
 * 建立对象,该对象有月出月落时间两个属性
 */
var pTime = {
		dbMoonRise:"1",
		dbMoonSet:"2",
	}; 
/***
 * moon(Jingdu,Weidu,Year,Month,Day,TimeZone) 为输入接口函数,输入5个参数(经纬度,年月日,时区),返回值分别为月出月落时间
 */
	
function moon(Jingdu,Weidu,Year,Month,Day,TimeZone){
 main(Jingdu,Weidu,Year,Month,Day,TimeZone)
 return parseInt(pTime.dbMoonRise)+":"+parseInt((pTime.dbMoonRise-parseInt(pTime.dbMoonRise))*60)+"  ,  "+parseInt(pTime.dbMoonSet)+":"+parseInt((pTime.dbMoonSet-parseInt(pTime.dbMoonSet))*60);
}
function main(Jingdu,Weidu,Year,Month,Day,TimeZone) {
	         GetSunMoonTime(Jingdu,Weidu,Year,Month,Day,TimeZone,pTime);
	    }
function  GetSunMoonTime(dbLon,dbLat,year,month,day,TimeZone,pTime){

	var mjdd = mjd(day,month,year,0);
		find_moonrise_set(mjdd, TimeZone, dbLon,dbLat,0,0,pTime);
	}
function frac(x){
       x -= parseInt(x);
		return( (x<0) ? x+1.0 : x );
}
function lmst( mjd,  glong){
//  Takes the mjd and the longitude (west negative) and then returns
	//  the local sidereal time in hours. Im using Meeus formula 11.4
	//  instead of messing about with UTo and so on
	var lst, t, d;
	d = mjd - 51544.5;
	t = d / 36525.0;
	lst = range(280.46061837 + 360.98564736629 * d + 0.000387933 *t*t - t*t*t / 38710000);
	lst = lst/15.0 + glong/15.0;
	if (lst >= 24.0) lst -=24.0;
	return (lst);
	}
function ipart(x) {
		// TODO Auto-generated method stub
		var a;
		if (x> 0) a = Math.floor(x);
		else a = Math.ceil(x);
		return a;
	}
function range( x) {
		// TODO Auto-generated method stub
		var a, b;
		b = x / 360;
		a = 360 * (b - ipart(b));
		if (a  < 0 )	a = a + 360;
		return a;
	}
function minimoon( t) {	


		// TODO Auto-generated method stub
		var p2 = 6.283185307, arc = 206264.8062, coseps = 0.91748, sineps = 0.39778;
		var L0, L, LS, F, D, H, S, N, DL, CB, L_moon, B_moon, V, W, X, Y, Z, RHO,dec,ra;
		var mooneq=new Array(2);

		L0 = frac(0.606433 + 1336.855225 * t);	// mean longitude of moon
		L = p2 * frac(0.374897 + 1325.552410 * t); //mean anomaly of Moon
		LS = p2 * frac(0.993133 + 99.997361 * t); //mean anomaly of Sun
		D = p2 * frac(0.827361 + 1236.853086 * t); //difference in longitude of moon and sun
		F = p2 * frac(0.259086 + 1342.227825 * t); //mean argument of latitude

		// corrections to mean longitude in arcsec
		DL =  22640 * Math.sin(L);
		DL += -4586 * Math.sin(L - 2*D);
		DL += +2370 * Math.sin(2*D);
		DL +=  +769 * Math.sin(2*L);
		DL +=  -668 * Math.sin(LS);
		DL +=  -412 * Math.sin(2*F);
		DL +=  -212 * Math.sin(2*L - 2*D);
		DL +=  -206 * Math.sin(L + LS - 2*D);
		DL +=  +192 * Math.sin(L + 2*D);
		DL +=  -165 * Math.sin(LS - 2*D);
		DL +=  -125 * Math.sin(D);
		DL +=  -110 * Math.sin(L + LS);
		DL +=  +148 * Math.sin(L - LS);
		DL +=   -55 * Math.sin(2*F - 2*D);

		// simplified form of the latitude terms
		S = F + (DL + 412 * Math.sin(2*F) + 541* Math.sin(LS)) / arc;
		H = F - 2*D;
		N =   -526 * Math.sin(H);
		N +=   +44 * Math.sin(L + H);
		N +=   -31 * Math.sin(-L + H);
		N +=   -23 * Math.sin(LS + H);
		N +=   +11 * Math.sin(-LS + H);
		N +=   -25 * Math.sin(-2*L + F);
		N +=   +21 * Math.sin(-L + F);

		// ecliptic long and lat of Moon in rads
		L_moon = p2 * frac(L0 + DL / 1296000);
		B_moon = (18520.0 * Math.sin(S) + N) /arc;

		// equatorial coord conversion - note fixed obliquity
		CB = Math.cos(B_moon);
		X = CB * Math.cos(L_moon);
		V = CB * Math.sin(L_moon);
		W = Math.sin(B_moon);
		Y = coseps * V - sineps * W;
		Z = sineps * V + coseps * W;
		RHO = Math.sqrt(1.0 - Z*Z);
		dec = (360.0 / p2) * Math.atan(Z / RHO);
		ra = (48.0 / p2) * Math.atan(Y / (X + RHO));
		if (ra <0 ) ra += 24;
		mooneq[1] = dec;
		mooneq[0] = ra;
		return mooneq;
	
}
function sin_alt(iobj,  mjd0,  hour, glong,  cglat,  sglat)	{
//  this rather mickey mouse function takes a lot of
	//  arguments and then returns the sine of the altitude of
	//  the object labelled by iobj. iobj = 1 is moon, iobj = 2 is sun
        var mjd, t, ra, dec, tau, salt, rads = 0.0174532925;
		var objpos=new Array(2);
		mjd = mjd0 + hour/24.0;
		t = (mjd - 51544.5) / 36525.0;
		if (iobj == 1)	objpos = minimoon(t);
	//	else 	objpos = minisun(t);
		ra = objpos[0];
		dec = objpos[1];
		// hour angle of object
		tau = 15.0 * (lmst(mjd, glong) - ra);
		// sin(alt) of object using the conversion formulas
		salt = sglat * Math.sin(rads*dec) + cglat * Math.cos(rads*dec) *Math.cos(rads*tau);
		return salt;

}
function   find_moonrise_set(mjd,  tz,glong,  glat, dls, ST, pTime){
//  Im using a separate function for moonrise/set to allow for different tabulations
	//  of moonrise and sun events ie weekly for sun and daily for moon. The logic of
	//  the function is identical to find_sun_and_twi_events_for_date()
        var  sglat, date, ym, yz,  utrise = 0, utset = 0,sinho,cglat,xe,ye;
		var yp, nz,  hour, z1, z2,  rads = 0.0174532925;
		var rise, sett,above;
		var quadout=new Array(5);

		sinho = Math.sin(rads * 8/60);		//moonrise taken as centre of moon at +8 arcmin
		sglat = Math.sin(rads * glat);
		cglat = Math.cos(rads * glat);
		date = mjd - tz/24;
		rise = "false";
		sett = "false";
		above = "false";
		hour = 1.0;
		ym = sin_alt(1, date, hour - 1.0, glong, cglat, sglat) - sinho;
		if (ym > 0.0) above = "true";
		while(hour < 25 && (sett == "false"|| rise == "false"))
		{
			yz = sin_alt(1, date, hour, glong, cglat, sglat) - sinho;
			yp = sin_alt(1, date, hour + 1.0, glong, cglat, sglat) - sinho;
			quadout = quad(ym, yz, yp);
			nz = quadout[0];
			z1 = quadout[1];
			z2 = quadout[2];
			xe = quadout[3];
			ye = quadout[4];
			// case when one event is found in the interval
			if (nz == 1) {
				if (ym < 0.0) {
					utrise = hour + z1;
					rise = "true";
				}
				else {
					utset = hour + z1;
					sett = "true";
				}
			} // end of nz = 1 case

			// case where two events are found in this interval
			// (rare but whole reason we are not using simple iteration)
			if (nz == 2) {
				if (ye < 0.0) {
					utrise = hour + z2;
					utset = hour + z1;
				}
				else {
					utrise = hour + z1;
					utset = hour + z2;
				}
			}

			// set up the next search interval
			ym = yp;
			hour += 2.0;
		} // end of while loop

		if (rise == "true" || sett == "true" )
		{
			if (rise == "true")
			{
				if (ST == 0)pTime.dbMoonRise = utrise+dls;
				else pTime.dbMoonRise = lmst(mjd+(utrise-tz)/24, glong);
			}
			else    pTime.dbMoonRise = -1;
			if (sett == "true")
			{
				if (ST == 0)pTime.dbMoonSet = utset+dls;
				else pTime.dbMoonSet = lmst(mjd+(utset-tz)/24, glong);
			}
			else	pTime.dbMoonSet = -1;
		}
		else	pTime.dbMoonSet = -2;
}
function mjd( day,  month, year, hour) {
//	Takes the day, month, year and hours in the day and returns the
	//  modified julian day number defined as mjd = jd - 2400000.5
	//  checked OK for Greg era dates - 26th Dec 02
   var a, b;
		if (month <= 2) {
			month = month + 12;
			year = year - 1;
		}
		a = 10000.0 * year + 100.0 * month + day;
		if (a <= 15821004.1)
			b = -2 * Math.floor((year + 4716)/4) - 1179;
		else
			b = Math.floor(year/400) - Math.floor(year/100) + Math.floor(year/4);
		a = 365.0 * year - 679004.0;
		return (a + b + Math.floor(30.6001 * (month + 1)) + day + hour/24.0);
	}



function quad( ym,  yz,  yp) {
//  finds the parabola throuh the three points (-1,ym), (0,yz), (1, yp)
	//  and returns the coordinates of the max/min (if any) xe, ye
	//  the values of x where the parabola crosses zero (roots of the quadratic)
	//  and the number of roots (0, 1 or 2) within the interval [-1, 1]
	//  well, this routine is producing sensible answers
	//  results passed as array [nz, z1, z2, xe, ye]
		// TODO Auto-generated method stub
		var a, b, c, dis, dx, xe, ye, z1 = 0, z2 = 0, nz;
		var quadout=new Array(5);

		nz = 0;
		a = 0.5 * (ym + yp) - yz;
		b = 0.5 * (yp - ym);
		c = yz;
		xe = -b / (2 * a);
		ye = (a * xe + b) * xe + c;
		dis = b * b - 4.0 * a * c;
		if (dis > 0)
		{
			dx = 0.5 * Math.sqrt(dis) / Math.abs(a);
			z1 = xe - dx;
			z2 = xe + dx;
			if (Math.abs(z1) <= 1.0) nz += 1;
			if (Math.abs(z2) <= 1.0) nz += 1;
			if (z1 < -1.0) z1 = z2;
		}
		quadout[0] = nz;
		quadout[1] = z1;
		quadout[2] = z2;
		quadout[3] = xe;
		quadout[4] = ye;
		return quadout;
	}
      

 

 document.getElementById("demo").innerHTML=moon(116.47,39.57,2002,12,30,8);   //调用例子,将结果写入页面
</script>
	
	
</body>
</html>


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值