BangleApps/apps/solarclock/solar_date_utils.js

134 lines
7.1 KiB
JavaScript

var Math2 = require("solar_math_utils.js");
const _MIN_MILLIS = 1000 * 60 ;
const _HOUR_MILLIS = _MIN_MILLIS * 60;
const _DAY_MILLIS = _HOUR_MILLIS * 24;
function _start_of_julian_day(now){
var sod_of_day = new Date(now.getTime());
var local_offset_hours = sod_of_day.getTimezoneOffset()/60;
//console.log("local_offset_hours=" + local_offset_hours);
sod_of_day.setHours(12 + local_offset_hours,0,0,0);
return sod_of_day;
}
function _date_to_julian_date(now){
var year = now.getFullYear();
var month = now.getMonth() + 1;
var day = now.getDate();
var julian_date_full = (1461 * (year + 4800 + (month-14)/12))/4 +(367 * (month-2 - 12*((month - 14)/12)))/12-(3 * ((year + 4900 + (month - 14)/12)/100))/4 + day - 32075;
var julian_date = (julian_date_full| 0);
return julian_date;
}
function _to_time(now,day_fraction){
var datetime = new Date(now.getTime());
var hours = (day_fraction * 24) |0;
var remainder = day_fraction - hours/24;
var mins = (remainder * 24 * 60 | 0);
var remainder = remainder - mins/(24*60);
var secs = (remainder * 24 * 60 * 60 | 0);
var remainder = remainder - secs /(24 * 60 * 60);
var millis = remainder * 24 * 60 * 60 * 1000;
datetime.setHours(hours, mins, secs,millis);
return datetime;
}
const DateUtils = {
DAY_MILLIS : _DAY_MILLIS,
HOUR_MILLIS : _HOUR_MILLIS,
MIN_MILLIS: _MIN_MILLIS,
// calculate the sunrise and sunset information using the NOAA
// equations.
sunrise_sunset: (now,longitude,latitude, utc_offset)=>{
var sod_julian = _start_of_julian_day(now);
var julian_date = _date_to_julian_date(sod_julian);
//console.log("julian date=" + julian_date);
//var n = julian_date - 2451545.0 + 0.0008;
var julian_century = (julian_date-2451545)/36525;
//console.log("julian_century=" + julian_century);
var geom_mean_long_sun_degrees = (280.46646+julian_century*(36000.76983 + julian_century*0.0003032)) % 360;
//console.log("geom_mean_long_sun=" + geom_mean_long_sun_degrees);
var geom_mean_anomaly_sun_degrees = 357.52911+julian_century*(35999.05029 - 0.0001537*julian_century);
//console.log("solar_mean_anomaly_sun=" + geom_mean_anomaly_sun_degrees);
var eccent_earth_orbit = 0.016708634-julian_century*(0.000042037+0.0000001267*julian_century);
//console.log("eccent_earth_orbit=" + eccent_earth_orbit);
var sun_eq_of_ctr = Math.sin(Math2.to_radians(geom_mean_anomaly_sun_degrees))*
(1.914602-julian_century*(0.004817+0.000014*julian_century))+
Math.sin(Math2.to_radians(2*geom_mean_anomaly_sun_degrees))*(0.019993-0.000101*julian_century)+
Math.sin(Math2.to_radians(3*geom_mean_anomaly_sun_degrees))*0.000289;
//console.log("sun_eq_of_ctr=" + sun_eq_of_ctr);
var sun_true_long_degrees = geom_mean_long_sun_degrees + sun_eq_of_ctr;
//console.log("sun_true_long_degrees=" + sun_true_long_degrees);
//var sun_true_anom_degrees = geom_mean_anomaly_sun_degrees + sun_eq_of_ctr;
//console.log("sun_true_anom_degrees=" + sun_true_anom_degrees);
//var sun_rad_vector_AUs = (1.000001018*(1-eccent_earth_orbit*eccent_earth_orbit))/(1+eccent_earth_orbit*Math.cos(Math2.to_radians(sun_true_anom_degrees)))
//console.log("sun_rad_vector_AUs=" + sun_rad_vector_AUs);
var sun_app_long_degress = sun_true_long_degrees-0.00569-0.00478*Math.sin(Math2.to_radians(125.04-1934.136*julian_century));
//console.log("sun_app_long_degress=" + sun_app_long_degress);
var mean_obliq_ecliptic_degrees = 23+(26+((21.448-julian_century*(46.815+julian_century*(0.00059-julian_century*0.001813))))/60)/60;
//console.log("mean_obliq_ecliptic_degrees=" + mean_obliq_ecliptic_degrees);
var obliq_corr_degrees = mean_obliq_ecliptic_degrees+0.00256*Math.cos(Math2.to_radians(125.04-1934.136*julian_century))
//console.log("obliq_corr_degrees=" + obliq_corr_degrees);
var sun_declin_degrees = Math2.to_degrees(
Math.asin(Math.sin(Math2.to_radians(obliq_corr_degrees))*Math.sin(Math2.to_radians(sun_app_long_degress)))
);
//console.log("sun_declin_degrees=" + sun_declin_degrees);
var var_y = Math.tan(Math2.to_radians(obliq_corr_degrees/2))*Math.tan(Math2.to_radians(obliq_corr_degrees/2));
//console.log("var_y=" + var_y);
var eq_of_time = 4*Math2.to_degrees(
var_y*Math.sin(2*Math2.to_radians(geom_mean_long_sun_degrees))-
2*eccent_earth_orbit*Math.sin(Math2.to_radians(geom_mean_anomaly_sun_degrees))+
4*eccent_earth_orbit*var_y*Math.sin(Math2.to_radians(geom_mean_anomaly_sun_degrees))*Math.cos(2*Math2.to_radians(geom_mean_long_sun_degrees))-
0.5*var_y*var_y*Math.sin(4*Math2.to_radians(geom_mean_long_sun_degrees))-
1.25*eccent_earth_orbit*eccent_earth_orbit*Math.sin(2*Math2.to_radians(geom_mean_anomaly_sun_degrees))
);
//console.log("eq_of_time=" + eq_of_time);
var HA_sunrise_degrees = Math2.to_degrees(
Math.acos(
Math.cos(Math2.to_radians(90.833))/(Math.cos(Math2.to_radians(latitude))*Math.cos(Math2.to_radians(sun_declin_degrees)))-
Math.tan(Math2.to_radians(latitude))*Math.tan(Math2.to_radians(sun_declin_degrees))
)
);
//console.log("HA_sunrise_degrees=" + HA_sunrise_degrees);
var local_offset_hours = new Date().getTimezoneOffset()/60;
if(utc_offset == null){
utc_offset = -local_offset_hours;
}
var timezone_offset_hours = utc_offset; //(utc_offset - local_offset_hours);
console.log("timezone_offset_hours=" + timezone_offset_hours +
" longitude" + longitude +
" utc_offset=" + utc_offset
);
var solar_noon = (720-4*longitude-eq_of_time+timezone_offset_hours*60)/1440;
var solar_noon_datetime = _to_time(now,solar_noon);
console.log("solar_noon=" + solar_noon + "->" + solar_noon_datetime.toISOString());
var sunrise_time_LST = (solar_noon*1440-HA_sunrise_degrees*4)/1440;
var sunrise_time_LST_datetime = _to_time(now,sunrise_time_LST);
console.log("sunrise_time_LST=" + sunrise_time_LST +
"->" + sunrise_time_LST_datetime.toISOString());
var sunset_time_LST =(solar_noon*1440+HA_sunrise_degrees*4)/1440;
var sunset_time_LST_datetime = _to_time(now,sunset_time_LST);
console.log("sunset_time_LST=" + sunset_time_LST +
"->" + sunset_time_LST_datetime.toISOString());
return {
day_start: new Date(solar_noon_datetime.getTime() - _DAY_MILLIS / 2),
sunrise_date: sunrise_time_LST_datetime,
//sunrise_fraction: sunrise_time_LST,
sunset_date: sunset_time_LST_datetime,
//sunset_fraction: sunset_time_LST,
solar_noon: solar_noon_datetime,
day_end: new Date(solar_noon_datetime.getTime() + _DAY_MILLIS / 2)
};
},
now_fraction_of_day: (now,day_info)=>{
return (now.getTime() - day_info.day_start.getTime())/_DAY_MILLIS;
},
}
module.exports = DateUtils;