# 接口约定

## 时间和观测点

所有时间为 UTC Unix **毫秒**，内部区分 UT 地球自转和通过分段 ΔT 近似获得的 TT 天体坐标时间。接受范围为 `1900-01-01T00:00:00Z`（含）到 `2151-01-01T00:00:00Z`（不含）。此范围是输入域，不是全时段精度认证。

`instant(Double)` 向零截断到整毫秒，与 JavaScript Date 的数值语义一致。`utc(year,month,day,hour=0,minute=0,second=0,millisecond=0)` 不允许日期滚动；1900 不是闰年，2000 是闰年；不接收闰秒。

`parse_utc` 只接受 `YYYY-MM-DDTHH:MM:SSZ` 或 `YYYY-MM-DDTHH:MM:SS.sssZ`。无隐式本地时区、无偏移格式，非法日期返回 `Err(InvalidDate)`。`to_utc` 拆分日历字段；`to_iso_utc` 始终含三位毫秒。输入端点的太阳事件可能落在相邻年，作为计算输出仍可格式化，不意味着放宽输入域。

`observer(latitude,longitude)` 使用北纬为正、东经为正的度数。没有海拔地理数据库。`SolarConfig` 的高度是相对于可见地平线的高度，不等价于海拔。

## 位置和照明

| 调用 | 输出 |
|---|---|
| `sun_position(time,site)` | `azimuth`、`altitude`（度） |
| `moon_position(time,site)` | 上述角度，`distance`（地心距离 km），`parallactic_angle`（度） |
| `moon_illumination(time)` | `fraction`（照明面积比例 0..1）、`phase`（朔 0、上弦 .25、望 .5、下弦 .75）、`angle`（亮面位置角，度）、`waxing` |

方位角北=0、东=90；高度角为模型大气折射修正后的视高度。月亮位置加了视差，但距离字段仍是地心距离。`angle - parallactic_angle` 是示例所用相对天顶亮面方向，不是照片像素旋转指令。

## 太阳事件

`sun_times(time,site)` 返回 `solar_noon`、`nadir`、`events`、`state`。输入按 **UTC 日期的中午**选取太阳周期，同一 UTC 日期内改变时分秒不改变结果。日期变更线附近的输出可以属于相邻 UTC 日；不是限定于 `[00:00,24:00)` 的事件过滤器。

`SunTimes.event(name)` 返回 `Option[Instant]`；未知名字或该事件不存在都返回 `None`。需要区分时遍历 `events` 并查看 `SolarEvent.state`。不要无条件 unwrap 升落事件。

| 太阳中心几何高度 | 上升 / 下降事件名 |
|---|---|
| -0.833° | sunrise / sunset |
| -0.3° | sunriseEnd / sunsetStart |
| -6° | dawn / dusk |
| -12° | nauticalDawn / nauticalDusk |
| -18° | nightEnd / night |
| +6° | goldenHourEnd / goldenHour |

`solar_angle(angle,rise_name,set_name)` 接受 (-90,90) 度及长度 1..64、互异的名字。`solar_config(height_m,extra)` 接受 0..10000 m、最多 32 组额外事件；拒绝重复或标准保留名，复制输入数组，不修改全局注册表。`sun_times_with` 使用该配置，高度修正为 `-2.076*sqrt(height)/60` 度。事件阈值是几何高度，不应拿含折射的 `sun_position.altitude` 直接断言等于阈值。

## 月亮事件和极区

`moon_times(time,site)` 从该 UTC 日期 00:00 扫描 24 小时；不提供上游 local-time 分支。返回 `rise`、`set`（Option）、`state`。允许只有月出或只有月落的一天。`Crosses` 表示找到至少一个交点，`AlwaysAbove/AlwaysBelow` 表示该模型扫描中没有交点并在地平线上/下；不是天气可见性判断。

太阳每个事件也有自己的状态；顶层太阳状态对应标准日出日落。高纬临界擦边事件对模型和舍入敏感，不应据此做安全承诺。二次曲线退化时使用线性根；Newton 斜率非有限/过小时保留最后有限估计，不宣称这种回退能修正近似模型的全部误差。

## 批量采样

`sample_observations(start,step_ms,count,site)` 返回 `Result[Array[Observation],InputError]`。每项包含 `time,sun,moon,illumination`。步长为正整数毫秒，最大为受支持时间跨度；点数为 1..4096。先检查末点合法性再分配，输入无效返回错误，不产生部分序列。此接口同时算日月，只有太阳需求时也可自行循环 `sun_position`。

## 与 JavaScript 上游的差异

没有默认当前时刻、Date 对象、全局 `addTime`、浏览器打包或本地时区扫描。无效输入使用 Result；无事件使用 Option/状态而非 Invalid Date/缺失对象属性。额外提供严格 UTC 日历适配、有限配置和批量采样。不是可直接替换 JavaScript 函数签名的二进制兼容层。
