admin管理员组文章数量:1122832
I have the following function that for a provided date and a pair of lat/long variables is supposed to return the the list of 3 timestamps in UTC
- one in the afternoon on that day
- one in the late evening on that day
- and next one shortly before sunrise next day.
Unfortunately, likely because the calculations jump from one day to another, the results are totally off. Where I got this wrong? Is there a better approach to this?
import datetime as dt
from suntime import Sun
def key_timestamps(date, latitude, longitude):
date = dt.datetime.strptime(date, "%Y-%m-%d")
sun = Sun(latitude, longitude)
sunrise = sun.get_sunrise_time(date)
sunset = sun.get_sunset_time(date)
next_day = date + dt.timedelta(days=1)
sunrise_next_day = sun.get_sunrise_time(next_day)
solar_noon = sunrise + (sunset - sunrise) / 2
peak_heating = solar_noon + dt.timedelta(hours=2, minutes=30)
evening_release = sunset + dt.timedelta(hours=3)
morning_minimum = sunrise_next_day - dt.timedelta(hours=1)
return [
int(peak_heating.timestamp()),
int(evening_release.timestamp()),
int(morning_minimum.timestamp())
]
singapore_results = key_timestamps("2022-05-29", 1.3521, 103.8198)
print(singapore_results)
Output is [1653809526, 1653746868, 1653947784]
which translates to:
- Sunday, May 29, 2022 7:32:06 AM - probably correct
- Saturday, May 28, 2022 2:07:48 PM - should be a few hours later than #1 so totally wrong
- Monday, May 30, 2022 9:56:24 PM - also wrong
Another example:
la_results = key_timestamps("2022-05-29", 34.0549, 118.2426)
Output:
[1653806070, 1653747048, 1653940656]
which translates to:
- Sunday, May 29, 2022 6:34:30 AM - wrong
- Saturday, May 28, 2022 2:10:48 PM - wrong
- Monday, May 30, 2022 7:57:36 PM - wrong
I have the following function that for a provided date and a pair of lat/long variables is supposed to return the the list of 3 timestamps in UTC
- one in the afternoon on that day
- one in the late evening on that day
- and next one shortly before sunrise next day.
Unfortunately, likely because the calculations jump from one day to another, the results are totally off. Where I got this wrong? Is there a better approach to this?
import datetime as dt
from suntime import Sun
def key_timestamps(date, latitude, longitude):
date = dt.datetime.strptime(date, "%Y-%m-%d")
sun = Sun(latitude, longitude)
sunrise = sun.get_sunrise_time(date)
sunset = sun.get_sunset_time(date)
next_day = date + dt.timedelta(days=1)
sunrise_next_day = sun.get_sunrise_time(next_day)
solar_noon = sunrise + (sunset - sunrise) / 2
peak_heating = solar_noon + dt.timedelta(hours=2, minutes=30)
evening_release = sunset + dt.timedelta(hours=3)
morning_minimum = sunrise_next_day - dt.timedelta(hours=1)
return [
int(peak_heating.timestamp()),
int(evening_release.timestamp()),
int(morning_minimum.timestamp())
]
singapore_results = key_timestamps("2022-05-29", 1.3521, 103.8198)
print(singapore_results)
Output is [1653809526, 1653746868, 1653947784]
which translates to:
- Sunday, May 29, 2022 7:32:06 AM - probably correct
- Saturday, May 28, 2022 2:07:48 PM - should be a few hours later than #1 so totally wrong
- Monday, May 30, 2022 9:56:24 PM - also wrong
Another example:
la_results = key_timestamps("2022-05-29", 34.0549, 118.2426)
Output:
[1653806070, 1653747048, 1653940656]
which translates to:
- Sunday, May 29, 2022 6:34:30 AM - wrong
- Saturday, May 28, 2022 2:10:48 PM - wrong
- Monday, May 30, 2022 7:57:36 PM - wrong
- 2 If you print sunrise and sunset for the Singapore example, you get: sunrise = datetime.datetime(2022, 5, 29, 22, 56, 24, tzinfo=datetime.timezone.utc) sunset = datetime.datetime(2022, 5, 28, 11, 7, 48, tzinfo=datetime.timezone.utc); it's probably a tz problem; you want to convert these utcs datetimes to local ones; perhaps have a look at rhodesmill.org/pyephem/toc.html – Swifty Commented Nov 21, 2024 at 10:31
2 Answers
Reset to default 1Sun.get_sunset_time()
appears to return the sunset time from the previous day (even if you set the time component to 23:59:59) so to get today's sunset time you need to add 1 day.- You also may need to pass in a time-zone aware
datetime
and then useSun.get_sunrise_time(date, tzinfo)
(and for sunset) to ensure that the output has the correct time zone.
from datetime import datetime, time, timedelta
from zoneinfo import ZoneInfo
from suntime import Sun
def key_timestamps(date, latitude, longitude):
sun = Sun(latitude, longitude)
sunrise = sun.get_sunrise_time(date, date.tzinfo)
sunset = sun.get_sunset_time(date + timedelta(days=1), date.tzinfo)
sunrise_next_day = sun.get_sunrise_time(date + timedelta(days=1), date.tzinfo)
peak_heating = sunrise + (sunset - sunrise)/2 + timedelta(hours=2, minutes=30)
evening_release = sunset + timedelta(hours=3)
morning_minimum = sunrise_next_day - timedelta(hours=1)
return [peak_heating, evening_release, morning_minimum]
singapore_results = key_timestamps(
datetime(2022, 5, 29, 0, 0, 0, tzinfo=ZoneInfo("Asia/Singapore")),
1.3521,
103.8198,
)
print(singapore_results)
print([int(t.timestamp()) for t in singapore_results])
Outputs:
[ datetime.datetime(2022, 5, 29, 15, 32, 6, tzinfo=zoneinfo.ZoneInfo(key='Asia/Singapore')),
datetime.datetime(2022, 5, 29, 22, 7, 48, tzinfo=zoneinfo.ZoneInfo(key='Asia/Singapore')),
datetime.datetime(2022, 5, 30, 5, 56, 24, tzinfo=zoneinfo.ZoneInfo(key='Asia/Singapore'))]
[1653809526, 1653833268, 1653861384]
import datetime as dt
from suntime import Sun
import pytz
def key_timestamps(date, latitude, longitude):
# Parse the date and assume it's in local time
date = dt.datetime.strptime(date, "%Y-%m-%d")
# Sun calculation object
sun = Sun(latitude, longitude)
# Get sunrise and sunset in UTC
sunrise_utc = sun.get_sunrise_time(date)
sunset_utc = sun.get_sunset_time(date)
# Convert date to the next day for the next sunrise
next_day = date + dt.timedelta(days=1)
sunrise_next_day_utc = sun.get_sunrise_time(next_day)
# Calculate solar noon
solar_noon = sunrise_utc + (sunset_utc - sunrise_utc) / 2
# Calculate timestamps in UTC
peak_heating_utc = solar_noon + dt.timedelta(hours=2, minutes=30)
evening_release_utc = sunset_utc + dt.timedelta(hours=3)
morning_minimum_utc = sunrise_next_day_utc - dt.timedelta(hours=1)
# Return timestamps in UTC
return [
int(peak_heating_utc.timestamp()),
int(evening_release_utc.timestamp()),
int(morning_minimum_utc.timestamp())
]
本文标签: pythonMisaligned dates for crossday calculationsStack Overflow
版权声明:本文标题:python - Misaligned dates for cross-day calculations - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736312131a1934988.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论