Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions src/Positioning/Positioning.jl
Original file line number Diff line number Diff line change
Expand Up @@ -255,9 +255,14 @@ pos_noaa = solar_position(obs, dt, NOAA())
- **Refraction**: Any `RefractionAlgorithm` subtype (default: `NoRefraction()`)

# Time Zone Handling
- `DateTime` inputs are assumed to be in UTC
- `ZonedDateTime` inputs are automatically converted to UTC
- For local solar time calculations, use appropriate time zones
- **`DateTime` inputs are assumed to be in UTC.** If you pass a local time as a plain
`DateTime`, the result will be incorrect — wrap it in a `ZonedDateTime` with the
appropriate time zone instead.
- **`ZonedDateTime` inputs are automatically converted to UTC** before computing the solar
position. For example, `ZonedDateTime(2023, 6, 21, 14, 0, 0, tz"Europe/Brussels")`
(UTC+2) is converted to `DateTime(2023, 6, 21, 12, 0, 0)` (UTC) before calculation.
- Two `ZonedDateTime` values representing the **same UTC instant** in different time zones
will produce **identical** results.

See also: [`solar_position!`](@ref), [`Observer`](@ref), [`PSA`](@ref), [`NOAA`](@ref)
"""
Expand Down
28 changes: 27 additions & 1 deletion test/positioning/test-interface.jl
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,20 @@ using Dates: Hour, @dateformat_str
result1 = solar_position(obs_ref, dt_plain, alg)
@test result1 == result_ref

# ZonedDateTime
# ZonedDateTime (UTC) — same instant as dt_plain
result2 = solar_position(obs_ref, dt_zoned, alg)
@test result2 == result_ref

# ZonedDateTime with non-UTC timezone
# 2020-10-17T14:30:00+02:00 (Europe/Brussels) == 2020-10-17T12:30:00 UTC
dt_brussels = ZonedDateTime(2020, 10, 17, 14, 30, 0, tz"Europe/Brussels")
result_tz = solar_position(obs_ref, dt_brussels, alg)
@test result_tz == result_ref

# 2020-10-17T08:30:00-04:00 (America/New_York EDT) == 2020-10-17T12:30:00 UTC
dt_nyc = ZonedDateTime(2020, 10, 17, 8, 30, 0, tz"America/New_York")
result_nyc = solar_position(obs_ref, dt_nyc, alg)
@test result_nyc == result_ref
end

@testset "Vectorized Interface" begin
Expand Down Expand Up @@ -126,6 +137,21 @@ using Dates: Hour, @dateformat_str

@test pos1 == pos2
end

@testset "Return new with non-UTC ZonedDateTime (issue #73)" begin
# Convert UTC DateTimes to Brussels timezone ZonedDateTimes
# These represent the same instants in time, just in different timezones
dts_brussels = [
TimeZones.astimezone(
ZonedDateTime(dt, tz"UTC"), tz"Europe/Brussels"
) for dt in dts
]

pos_brussels = solar_position(obs, dts_brussels, alg)
pos_utc = solar_position(obs, dts, alg)

@test pos_brussels == pos_utc
end
end

@testset "Tables Interface" begin
Expand Down
Loading