1 function compute () { 2 3 if (CheckInputs ()) { 4 5 var f = document.theForm; 6 7 //常量 8 9 var degreesToRadians = 3.1416 / 180.0000; 10 var radiansToDegrees = 180.0000 / 3.1416; 11 var feetToMeters = 1.0000 / 3.2800; 12 var degreeMinutesToDecimal = 1.0000 / 60.0000; 13 var degreeSecondsToDecimal = 1.0000 / 3600.0000; 14 15 // 检索输入的值 16 /*经度 17 120 18 选择时间制式 19 16:56 20 21 纬度 22 36 23 选择时区 24 选择日期 月 日 选择基准时间 25 年 夏令时 26 海拔 27 44 28 零方位角 29 计算 30 世界时间时区查询换算 31 输出结果: 32 太阳高度角 33 - 1.59 34 偏差 35 -23.30 36 太阳方位角 37 62.03 38 时差 39 - 0.02 40 时钟时间 41 1656 42 日出时间 43 2308 44 太阳时 45 1656 46 日落时间 47 3254 48 时角 49 74.00 50 */ 51 20160926修改 52 var inputLongitude = f.inputLongitude.value; 53 var inputEastWest = f.inputEastWest.options[f.inputEastWest.selectedIndex].text; 54 var inputLatitude = f.inputLatitude.value; 55 var inputNorthSouth = f.inputNorthSouth.options[f.inputNorthSouth.selectedIndex].text; 56 var inputElevation = f.inputElevation.value; 57 var inputFeetMeters = f.inputFeetMeters.options[f.inputFeetMeters.selectedIndex].text; 58 var inputMonth = f.inputMonth.options[f.inputMonth.selectedIndex].text; 59 var inputDate = f.inputDate.options[f.inputDate.selectedIndex].text - 0; 60 var inputYear = f.inputYear.options[f.inputYear.selectedIndex].text - 0; 61 var inputTime = f.inputTime.value; 62 var inputAMPM = f.inputAMPM.options[f.inputAMPM.selectedIndex].text; 63 var inputTimeFormat = f.inputTimeFormat.options[f.inputTimeFormat.selectedIndex].text; 64 var inputTimeZone = f.inputTimeZone.options[f.inputTimeZone.selectedIndex].value - 0; 65 var inputDaylight = f.inputDaylight.options[f.inputDaylight.selectedIndex].text; 66 var inputZeroAzimuth = f.inputZeroAzimuth.options[f.inputZeroAzimuth.selectedIndex].value - 0; 67 68 69 if (inputLongitude.indexOf("d") != -1) { 70 71 degMarker = inputLongitude.indexOf("d"); 72 minMarker = inputLongitude.indexOf("m"); 73 secMarker = inputLongitude.indexOf("s"); 74 75 longitudeDeg = inputLongitude.substr(0,degMarker) - 0; 76 longitudeMin = inputLongitude.substr(degMarker+1,minMarker-degMarker-1) - 0; 77 longitudeSec = inputLongitude.substr(minMarker+1,secMarker-minMarker-1) - 0; 78 79 inputLongitude = longitudeDeg + (longitudeMin * degreeMinutesToDecimal) + (longitudeSec * degreeSecondsToDecimal); 80 } 81 else { inputLongitude -= 0; } 82 83 if (inputLatitude.indexOf("d") != -1) { 84 85 degMarker = inputLatitude.indexOf("d"); 86 minMarker = inputLatitude.indexOf("m"); 87 secMarker = inputLatitude.indexOf("s"); 88 89 LatitudeDeg = inputLatitude.substr(0,degMarker) - 0; 90 LatitudeMin = inputLatitude.substr(degMarker+1,minMarker-degMarker-1) - 0; 91 LatitudeSec = inputLatitude.substr(minMarker+1,secMarker-minMarker-1) - 0; 92 93 inputLatitude = LatitudeDeg + (LatitudeMin * degreeMinutesToDecimal) + (LatitudeSec * degreeSecondsToDecimal); 94 } 95 else { inputLatitude -= 0; } 96 97 //检查输入值的有效性 98 99 var validInputTime = true; 100 101 // 避免由于纬度或经度数学错误 = 0 102 103 if ((inputLatitude == 0) && (f.inputLatitude.value.length > 0)) { inputLatitude = 0.000000001; } 104 if ((inputLongitude == 0) && (f.inputLongitude.value.length > 0)) { inputLongitude = 0.000000001; } 105 106 //检查输入的字段都由用户填写 107 108 var timeEntered = (inputTime != ""); 109 var latitudeEntered = (inputLatitude != ""); 110 var longitudeEntered = (inputLongitude != ""); 111 112 // 将输入的字符串转换为数字 113 114 inputLatitude = inputLatitude - 0; 115 inputLongitude = inputLongitude - 0; 116 inputElevation = inputElevation - 0; 117 118 // 确定时间格式 119 120 var clockTimeInputMode = (inputTimeFormat == "Clock time"); 121 var lsotInputMode = (inputTimeFormat == "Solar time"); 122 123 // 124 125 var doableDeclination = true; 126 var doableEOT = true; 127 var doableClockTime = ((longitudeEntered || clockTimeInputMode) && timeEntered); 128 var doableLSOT = ((longitudeEntered || lsotInputMode) && timeEntered); 129 var doableHourAngle = (longitudeEntered && timeEntered); 130 var doableSunRiseSet = (longitudeEntered && latitudeEntered); 131 var doableAltitude = (longitudeEntered && timeEntered && latitudeEntered); 132 var doableAzimuth = (longitudeEntered && timeEntered && latitudeEntered); 133 134 135 // //////////// // 136 //计算// 137 // //////////// // 138 139 // 转换单位 140 141 // 经度东-西调整 142 143 if (longitudeEntered) { 144 var signedLongitude = inputLongitude; 145 if (inputEastWest == "East") signedLongitude *= -1; // [0] = 东, [1] = 西 146 } 147 148 // 纬度南北调整 149 150 if (latitudeEntered) { 151 var signedLatitude = inputLatitude; 152 if (inputNorthSouth == "South") signedLatitude *= -1; // [0] = 北, [1] = 南 153 } 154 155 // 修复经度 > 180 deg 156 157 if (signedLongitude > 180) { 158 159 signedLongitude = signedLongitude - 360; 160 } 161 162 // 修复经度< -180 deg 163 164 if (signedLongitude < -180) { 165 166 signedLongitude = signedLongitude + 360; 167 } 168 169 // 日光节约时间的调整,计算 170 171 var daylightAdjustment = 0; 172 173 if (inputDaylight == "Yes") daylightAdjustment = 1; 174 175 // 如果有必要,转换高度单位 176 177 if (inputFeetMeters == "feet") { inputElevation *= feetToMeters; } 178 179 //设置为零的方位 180 181 zeroAzimuth = inputZeroAzimuth; 182 183 // 当地标准时间子午线 184 185 var meridian = inputTimeZone * -15; 186 187 // 如果太多与时区经度不同的警报 188 189 var longitudeMeridianDifference = signedLongitude - meridian; 190 191 if ((! showedLongitudeMeridianWarning) && ((longitudeMeridianDifference > 30) || (longitudeMeridianDifference < -30))) { 192 193 alert ("警告: 经度从选定的时区中心相差超过30度. 这可能是正确的, 或者它可能表明,其中一个输入是不正确的.\n\n请点击 '时区' 输入的详细信息.\n\n(不会再次显示这个警告.)"); 194 195 showedLongitudeMeridianWarning = true; 196 } 197 198 // 计算时间 199 200 // 转换时间输入午后小时 201 202 if (validInputTime) { 203 204 // ...如果有必要从时间字符串删除分号 205 206 inputTime = RemoveSemicolon (inputTime); 207 208 // ...解析时间输入的字符串并得到小时和分钟 209 210 if (inputTime.length == 4) { // 如 "1234" 211 timeHours = inputTime.substring(0,2) - 0; 212 timeMinutes = inputTime.substring(2,4) - 0; 213 } 214 else { // 如 "123" 215 timeHours = inputTime.substring(0,1) - 0; 216 timeMinutes = inputTime.substring(1,3) - 0; 217 } 218 219 // ...调整为 AM/PM 名称 220 221 if ((inputAMPM == "AM") && (timeHours == 12)) timeHours = 0; 222 if (inputAMPM == "PM") { if (timeHours != 12) timeHours += 12; } 223 224 // ...计算后午夜的时钟分钟 225 226 var inputHoursAfterMidnight = timeHours + timeMinutes / 60.0; 227 var inputMinutesAfterMidnight = timeHours * 60.0 + timeMinutes; 228 } 229 230 // 计算通用时间 231 232 var UT = 0.0; 233 234 if (validInputTime) { UT = inputHoursAfterMidnight - inputTimeZone - daylightAdjustment; } 235 236 var monthNum = (MonthStringToMonthNum (inputMonth)) - 0; 237 238 if (monthNum > 2) { 239 correctedYear = inputYear; 240 correctedMonth = monthNum - 3; 241 } 242 else { 243 correctedYear = inputYear - 1; 244 correctedMonth = monthNum + 9; 245 } 246 247 var t = ((UT / 24.0) + inputDate + Math.floor (30.6 * correctedMonth + 0.5) + Math.floor (365.25 * (correctedYear - 1976)) - 8707.5) / 36525.0; 248 249 var G = 357.528 + 35999.05 * t; 250 G = NormalizeTo360 (G); 251 252 var C = (1.915 * Math.sin (G * degreesToRadians)) + (0.020 * Math.sin (2.0 * G * degreesToRadians)); 253 254 var L = 280.460 + (36000.770 * t) + C; 255 L = NormalizeTo360 (L); 256 257 var alpha = L - 2.466 * Math.sin (2.0 * L * degreesToRadians) + 0.053 * Math.sin (4.0 * L * degreesToRadians); 258 259 var GHA = UT * 15 - 180 - C + L - alpha; 260 GHA = NormalizeTo360 (GHA); 261 262 var obliquity = 23.4393 - 0.013 * t; 263 264 var declination = Math.atan (Math.tan (obliquity * degreesToRadians) * Math.sin (alpha * degreesToRadians)) * radiansToDegrees; 265 266 f.outputDeclination.value = FormatFloatString (declination); 267 268 var eotAdjustment = (L - C - alpha) / 15.0; 269 270 f.outputEOT.value = FormatFloatString (eotAdjustment); 271 272 if (doableLSOT || doableClockTime) { 273 274 var clockTimeToLSOTAdjustment = ((signedLongitude - meridian) / 15.0) - eotAdjustment + daylightAdjustment; // 以小时为单位 275 } 276 277 var solarHourAngle = 0; 278 279 if (clockTimeInputMode) { solarHourAngle = GHA - signedLongitude; } 280 281 else { solarHourAngle = 15 * (inputHoursAfterMidnight - 12); } 282 283 solarHourAngle = NormalizeTo180 (solarHourAngle); 284 285 var apparentSolarTime = 0; 286 287 if (clockTimeInputMode) { apparentSolarTime = NormalizeTo24 (12 + solarHourAngle / 15.0); } 288 289 else { apparentSolarTime = inputHoursAfterMidnight; } 290 291 if (doableLSOT) { 292 293 if (clockTimeInputMode) { 294 295 solarMinutesAfterMidnight = inputMinutesAfterMidnight - (clockTimeToLSOTAdjustment * 60.0); 296 297 var whichDay = 0; 298 299 if (solarMinutesAfterMidnight < 0) { 300 solarMinutesAfterMidnight += 24 * 60; 301 whichDay = -1; 302 } 303 304 if (solarMinutesAfterMidnight >= 24 * 60) { 305 solarMinutesAfterMidnight -= 24 * 60; 306 whichDay = 1; 307 } 308 } 309 310 else { 311 312 solarMinutesAfterMidnight = inputMinutesAfterMidnight; 313 314 whichDay = 0; 315 } 316 317 solarTime = MinutesToClockTime (solarMinutesAfterMidnight, inputAMPM); 318 319 if (whichDay == "-1") f.outputLSOT.value = solarTime + "-"; 320 if (whichDay == "0") f.outputLSOT.value = solarTime ; 321 if (whichDay == "1") f.outputLSOT.value = solarTime + "+"; 322 } 323 324 else { f.outputLSOT.value = ""; } 325 326 if (doableClockTime) { 327 328 var clockMinutesAfterMidnight = inputMinutesAfterMidnight; 329 330 if (lsotInputMode) { clockMinutesAfterMidnight = inputMinutesAfterMidnight + (clockTimeToLSOTAdjustment * 60.0); } 331 332 var whichDay = 0; 333 334 if (clockMinutesAfterMidnight < 0) { 335 clockMinutesAfterMidnight += 24 * 60; 336 whichDay = -1; 337 } 338 339 if (clockMinutesAfterMidnight >= 24 * 60) { 340 clockMinutesAfterMidnight -= 24 * 60; 341 whichDay = 1; 342 } 343 344 clockTime = MinutesToClockTime (clockMinutesAfterMidnight, inputAMPM); 345 346 if (whichDay == "-1") f.outputClockTime.value = clockTime + "-"; 347 if (whichDay == "0") f.outputClockTime.value = clockTime ; 348 if (whichDay == "1") f.outputClockTime.value = clockTime + "+"; 349 } 350 351 else { f.outputClockTime.value = ""; } 352 353 // 小时角 354 355 // 不同之间 180 和 + 180 度 356 357 if (doableHourAngle) { 358 359 var hourAngle = (solarMinutesAfterMidnight - (12 * 60)) / 4; 360 361 f.outputHourAngle.value = FormatFloatString (hourAngle); 362 } 363 364 else { f.outputHourAngle.value = ""; } 365 366 //地平高度角 367 368 if (doableAltitude) { 369 370 var altitudeAngle = radiansToDegrees * ArcSin ( 371 (Math.sin (signedLatitude * degreesToRadians) * 372 Math.sin (declination * degreesToRadians)) - 373 (Math.cos (signedLatitude * degreesToRadians) * 374 Math.cos (declination * degreesToRadians) * 375 Math.cos ((solarHourAngle + 180) * degreesToRadians))); 376 377 f.outputAltitude.value = FormatFloatString (altitudeAngle); 378 } 379 380 else { f.outputAltitude.value = ""; } 381 382 // 方位角 383 384 if (doableAzimuth) { 385 386 var preAzimuthAngle = radiansToDegrees * ArcCos ( 387 (Math.cos (declination * degreesToRadians) * 388 ((Math.cos (signedLatitude * degreesToRadians) * 389 Math.tan (declination * degreesToRadians)) + 390 (Math.sin (signedLatitude * degreesToRadians) * 391 Math.cos ((solarHourAngle + 180) * degreesToRadians)))) / 392 Math.cos (altitudeAngle * degreesToRadians)); 393 394 azimuthAngle = preAzimuthAngle + (zeroAzimuth - 180.0); 395 396 // 方位角的正确标志 397 398 399 if (zeroAzimuth == 0) { 400 401 azimuthAngle = ChangeSign (azimuthAngle, "same", hourAngle); 402 } 403 404 //北零方位 405 406 else { 407 408 azimuthAngle = ChangeSign (azimuthAngle, "opposite", hourAngle); 409 } 410 411 f.outputAzimuth.value = FormatFloatString (azimuthAngle); 412 } 413 414 else { f.outputAzimuth.value = ""; } 415 416 // 时钟时间的日出与日落 417 418 if (doableSunRiseSet) { 419 var sunRiseSetLSoTMinutes = radiansToDegrees * ArcCos ( -1.0 * 420 (Math.sin (signedLatitude * degreesToRadians) * 421 Math.sin (declination * degreesToRadians) - 422 Math.sin ((-0.8333 - 0.0347 * Math.sqrt (inputElevation)) * degreesToRadians)) / 423 Math.cos (signedLatitude * degreesToRadians) / 424 Math.cos (declination * degreesToRadians)) * 4; 425 426 f.outputSunrise.value = MinutesToClockTime ((12 * 60 - sunRiseSetLSoTMinutes + (clockTimeToLSOTAdjustment * 60)), inputAMPM); 427 428 f.outputSunset.value = MinutesToClockTime ((12 * 60 + sunRiseSetLSoTMinutes + (clockTimeToLSOTAdjustment * 60)), inputAMPM); 429 } 430 else { 431 f.outputSunrise.value = ""; 432 f.outputSunset.value = ""; 433 } 434 } 435 436 // 零出形式输出,是否输入了无效 437 438 else { 439 440 var f = document.theForm; 441 442 f.outputAltitude.value = ''; 443 f.outputAzimuth.value = ''; 444 f.outputDeclination.value = ''; 445 f.outputEOT.value = ''; 446 f.outputClockTime.value = ''; 447 f.outputSunrise.value = ''; 448 f.outputSunset.value = ''; 449 f.outputLSOT.value = ''; 450 f.outputHourAngle.value = ''; 451 } 452 453 }