Solar Time Daemon
TimeNow provides standalone system daemons that compute solar time offsets without requiring the JVM backend. These are designed for Linux kernel integration, embedded systems, and scientific infrastructure.
Available Implementations
| Daemon | Language | Kernel Compatible | Dependencies |
timenow-daemon | C99 | Via userspace | libm only |
timenow-daemon-rs | Rust | no_std crate | libm (Rust) |
Both implementations use the same NOAA solar position algorithms (reference) and produce equivalent results.
Architecture
┌──────────────────┐
│ GPS / Config │
│ --lat --lng │
└────────┬─────────┘
│
┌────────▼─────────┐
│ timenow-daemon │
│ (C99 or Rust) │
│ │
│ NOAA solar math │
│ signal handling │
│ atomic writes │
└──┬─────┬─────┬──┘
│ │ │
┌────────────▼┐ ┌──▼───┐ ┌▼────────────┐
│/run/timenow/│ │/run/ │ │/dev/shm/ │
│solar_offset │ │solar │ │timenow │
│(plain text) │ │.json │ │(SHM struct) │
└─────────────┘ └──────┘ └──────┬──────┘
│
┌────────▼────────┐
│ chrony / NTP │
│ refclock SHM │
└─────────────────┘
Quick Start
C Daemon
cd daemon && make
./timenow-daemon --lat=48.2 --lng=16.37 --foreground
Rust Daemon
cd daemon-rust && cargo build --release
./target/release/timenow-daemon-rs --lat=48.2 --lng=16.37
CLI Flags
C Daemon
| Flag | Required | Default | Description |
--lat=DEG | Yes | — | Latitude (-90 to 90) |
--lng=DEG | Yes | — | Longitude (-180 to 180) |
--interval=SEC | No | 1 | Update interval in seconds |
--foreground | No | off | Run in foreground (skip daemonization) |
--help | No | — | Show usage |
Rust Daemon
| Flag | Required | Default | Description |
--lat=DEG | Yes | — | Latitude (-90 to 90) |
--lng=DEG | Yes | — | Longitude (-180 to 180) |
--interval=SEC | No | 60 | Update interval in seconds |
--help / -h | No | — | Show usage |
Output Files
C Daemon
| Path | Format | Content |
/run/timenow/solar_offset | Plain text | Offset in seconds (e.g. -1054.234567) |
/run/timenow/solar.json | JSON (pretty) | Full solar data |
/dev/shm/timenow | Key-value | offset, clock_sec, clock_nsec, precision, leap |
/run/timenow/timenow.pid | Plain text | Process ID |
Rust Daemon
| Path | Format | Content |
/run/timenow/solar_offset_rs | Plain text | Offset in seconds |
/run/timenow/solar_rs.json | JSON (compact) | Full solar data + declination |
/dev/shm/timenow_rs | Plain text | Offset value |
Sample JSON (C Daemon)
{
"timestamp": "2025-01-15T12:30:00Z",
"latitude": 48.208200,
"longitude": 16.373800,
"solar_noon_utc": 11.823456,
"sunrise_utc": 6.712345,
"sunset_utc": 16.934567,
"elevation_deg": 18.4523,
"azimuth_deg": 192.3401,
"equation_of_time_min": -9.2345,
"day_length_hours": 8.4567,
"solar_offset_sec": -1054.234567
}
Sample JSON (Rust Daemon)
{
"lat": 48.208200,
"lng": 16.373800,
"solar_noon_utc": 11.823456,
"sunrise_utc": "06:42:44",
"sunset_utc": "16:56:05",
"elevation_deg": 18.4523,
"azimuth_deg": 192.3401,
"equation_of_time_min": -9.2345,
"day_length_hours": 8.4567,
"solar_offset_sec": -1054.234567,
"declination_deg": -18.1234
}
Implementation Differences
| Aspect | C Daemon | Rust Daemon |
| Default interval | 1 second | 60 seconds |
| Daemonization | Double-fork | Foreground only |
| Atomic writes | Yes (temp + rename) | Direct creation |
| JSON format | Pretty-printed | Compact single-line |
| Sunrise/sunset in JSON | Numeric (hours) | Formatted HH:MM:SS |
| Polar handling | Horizon angle check | NaN for sunrise/sunset |
| Logging | Silent unless --foreground | Always logs to stderr |
Polar Day/Night
Both daemons handle extreme latitudes where the sun may not rise or set:
- C daemon: Returns computed horizon angle; sunrise/sunset may be absent.
- Rust daemon: Returns
NaN for sunrise/sunset, sets day length to 24.0 (midnight sun) or 0.0 (polar night). JSON displays "--:--:--" for missing values.