nrel-spa-dart/.github/wiki/guides/advanced.md
Aric Camarata 86db6c6bae
feat: gap-fill API surface parity with nrel-spa JS (v1.0.1) (#1)
* feat: gap-fill API surface parity with nrel-spa JS (v1.0.1)

Add formatTime, calcSpa, SpaFormattedResult, SpaFormattedAnglesResult,
functionCode parameter for getSpa (spaZa/spaZaInc/spaZaRts/spaAll),
incidence field on SpaResult, and export all function code constants.

All 48 tests pass including numerical cross-validation against the NREL
SPA reference date (Golden CO, 2003-10-17) and surface incidence angle.

* docs: add CHANGELOG.md for v1.0.1 release

* chore: polish pubspec, fix unused import, add wiki docs
2026-05-29 06:49:12 -04:00

2.3 KiB

Advanced Usage

Custom Zenith Angles

Calculate rise/set times for any solar depression angle. Useful for computing civil, nautical, and astronomical twilight, or Islamic prayer times.

import 'package:nrel_spa/nrel_spa.dart';

final result = getSpa(
  DateTime.utc(2024, 3, 15, 12, 0, 0),
  40.7128, -74.0060, -5.0,
  customAngles: [96.0, 102.0, 108.0], // civil, nautical, astronomical
);

for (int i = 0; i < result.angles.length; i++) {
  final a = result.angles[i];
  print('Angle ${a.angle}°: rise=${a.sunrise.toStringAsFixed(4)} h, set=${a.sunset.toStringAsFixed(4)} h');
}

Standard zenith angles:

Twilight type Zenith angle
Civil 96.0°
Nautical 102.0°
Astronomical 108.0°
Fajr (18°) 108.0°
Isha (17°) 107.0°

Elevation and Atmospheric Correction

For more accurate results at high elevation or in varying atmospheric conditions:

final result = getSpa(
  DateTime.utc(2024, 3, 15, 12, 0, 0),
  39.7392,    // Denver latitude
  -104.9903,  // Denver longitude
  -7.0,       // UTC offset (MST)
  elevation: 1609.0,    // meters above sea level
  pressure: 835.0,      // mbar (lower at altitude)
  temperature: 10.0,    // Celsius
);

deltaT Parameter

deltaT is the difference between Terrestrial Time (TT) and Universal Time (UT1), in seconds. The default is 67 seconds, which is accurate for recent dates. For historical calculations or projections, supply the correct value from IERS tables.

// Historical calculation (1990)
final result = getSpa(
  DateTime.utc(1990, 6, 21, 12, 0, 0),
  40.7128, -74.0060, -5.0,
  deltaT: 57.2,
);

Batch Calculations

For high-volume calculations (annual ephemeris, solar energy modeling), call getSpa in a loop. The function is synchronous and pure — safe to call from any isolate.

final times = List.generate(365, (i) {
  final date = DateTime.utc(2024, 1, 1).add(Duration(days: i));
  return getSpa(date, lat, lng, utcOffset);
});

For parallel batch work in Flutter, dispatch to an isolate:

import 'dart:isolate';

final results = await Isolate.run(() {
  return List.generate(365, (i) {
    final date = DateTime.utc(2024, 1, 1).add(Duration(days: i));
    return getSpa(date, lat, lng, utcOffset);
  });
});