forked from GithubBackups/healthchecks
Use timezone-aware datetimes with croniter, avoid conversions to and from naive datetimes. This avoids ambiguities around DST transitions and properly solves #196
This commit is contained in:
parent
e21801f44e
commit
cf08f54c30
@ -13,6 +13,7 @@ All notable changes to this project will be documented in this file.
|
||||
### Bug Fixes
|
||||
- Fix after-login redirects (the "?next=" query parameter)
|
||||
- Update Check.status field when user edits timeout & grace settings
|
||||
- Use timezone-aware datetimes with croniter, avoid ambiguities around DST
|
||||
|
||||
|
||||
## 1.3.0 - 2018-11-21
|
||||
|
@ -15,6 +15,7 @@ from django.utils import timezone
|
||||
from hc.api import transports
|
||||
from hc.lib import emails
|
||||
import requests
|
||||
import pytz
|
||||
|
||||
STATUSES = (
|
||||
("up", "Up"),
|
||||
@ -115,12 +116,15 @@ class Check(models.Model):
|
||||
if self.kind == "simple":
|
||||
return self.last_ping + self.timeout
|
||||
|
||||
# The complex case, next ping is expected based on cron schedule
|
||||
with timezone.override(self.tz):
|
||||
last_naive = timezone.make_naive(self.last_ping)
|
||||
it = croniter(self.schedule, last_naive)
|
||||
next_naive = it.get_next(datetime)
|
||||
return timezone.make_aware(next_naive, is_dst=True)
|
||||
# The complex case, next ping is expected based on cron schedule.
|
||||
# Don't convert to naive datetimes (and so avoid ambiguities around
|
||||
# DST transitions).
|
||||
# croniter does handle timezone-aware datetimes.
|
||||
|
||||
zone = pytz.timezone(self.tz)
|
||||
last_local = timezone.localtime(self.last_ping, zone)
|
||||
it = croniter(self.schedule, last_local)
|
||||
return it.next(datetime)
|
||||
|
||||
def get_status(self, now=None):
|
||||
""" Return "up" if the check is up or in grace, otherwise "down". """
|
||||
|
@ -28,7 +28,7 @@ from hc.front.schemas import telegram_callback
|
||||
from hc.front.templatetags.hc_extras import (num_down_title, down_title,
|
||||
sortchecks)
|
||||
from hc.lib import jsonschema
|
||||
from pytz import all_timezones
|
||||
import pytz
|
||||
from pytz.exceptions import UnknownTimeZoneError
|
||||
import requests
|
||||
|
||||
@ -130,7 +130,7 @@ def my_checks(request):
|
||||
"now": timezone.now(),
|
||||
"tags": pairs,
|
||||
"ping_endpoint": settings.PING_ENDPOINT,
|
||||
"timezones": all_timezones,
|
||||
"timezones": pytz.all_timezones,
|
||||
"num_available": request.team.check_limit - len(checks),
|
||||
"sort": request.profile.sort,
|
||||
"selected_tags": selected_tags,
|
||||
@ -325,13 +325,11 @@ def cron_preview(request):
|
||||
tz = request.POST.get("tz")
|
||||
ctx = {"tz": tz, "dates": []}
|
||||
try:
|
||||
with timezone.override(tz):
|
||||
now_naive = timezone.make_naive(timezone.now())
|
||||
it = croniter(schedule, now_naive)
|
||||
for i in range(0, 6):
|
||||
naive = it.get_next(datetime)
|
||||
aware = timezone.make_aware(naive, is_dst=True)
|
||||
ctx["dates"].append((naive, aware))
|
||||
zone = pytz.timezone(tz)
|
||||
now_local = timezone.localtime(timezone.now(), zone)
|
||||
it = croniter(schedule, now_local)
|
||||
for i in range(0, 6):
|
||||
ctx["dates"].append(it.get_next(datetime))
|
||||
except UnknownTimeZoneError:
|
||||
ctx["bad_tz"] = True
|
||||
except:
|
||||
@ -420,7 +418,7 @@ def details(request, code):
|
||||
"page": "details",
|
||||
"check": check,
|
||||
"channels": channels,
|
||||
"timezones": all_timezones
|
||||
"timezones": pytz.all_timezones
|
||||
}
|
||||
|
||||
return render(request, "front/details.html", ctx)
|
||||
|
@ -1,5 +1,5 @@
|
||||
croniter
|
||||
Django==2.1.3
|
||||
croniter==0.3.26
|
||||
Django==2.1.4
|
||||
django_compressor==2.2
|
||||
psycopg2==2.7.5
|
||||
pytz==2018.7
|
||||
|
@ -11,11 +11,13 @@
|
||||
{% else %}
|
||||
<table id="cron-preview-table" class="table">
|
||||
<tr><th id="cron-preview-title" colspan="3">Expected Ping Dates</th></tr>
|
||||
{% for naive, aware in dates %}
|
||||
{% for d in dates %}
|
||||
<tr>
|
||||
<td>{{ naive|date:"M j, H:i" }}</td>
|
||||
<td>{{ aware|naturaltime }}</td>
|
||||
<td class="hidden-xs">{{ aware|date:"c" }}</td>
|
||||
{% timezone tz %}
|
||||
<td>{{ d|date:"M j, H:i" }}</td>
|
||||
{% endtimezone %}
|
||||
<td>{{ d|naturaltime }}</td>
|
||||
<td class="hidden-xs">{{ d|date:"c" }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
|
Loading…
x
Reference in New Issue
Block a user