mirror of
https://github.com/GSA/notifications-api.git
synced 2025-12-14 09:12:06 -05:00
move days_ago to utils and make it tz aware
it's used in a few places - it should definitely know what timezones are and return datetimes rather than dates, which are hard to work with in terms of figuring out how tz aware they are.
This commit is contained in:
@@ -28,8 +28,3 @@ class DAOClass(object):
|
||||
db.session.delete(inst)
|
||||
if _commit:
|
||||
db.session.commit()
|
||||
|
||||
|
||||
def days_ago(number_of_days):
|
||||
from datetime import date, timedelta
|
||||
return date.today() - timedelta(days=number_of_days)
|
||||
|
||||
@@ -4,15 +4,13 @@ from datetime import datetime, timedelta
|
||||
from flask import current_app
|
||||
from notifications_utils.statsd_decorators import statsd
|
||||
from sqlalchemy import (
|
||||
Date as sql_date,
|
||||
asc,
|
||||
cast,
|
||||
desc,
|
||||
func,
|
||||
)
|
||||
|
||||
from app import db
|
||||
from app.dao import days_ago
|
||||
from app.utils import days_ago
|
||||
from app.models import (
|
||||
Job,
|
||||
JOB_STATUS_PENDING,
|
||||
@@ -53,7 +51,7 @@ def dao_get_jobs_by_service_id(service_id, limit_days=None, page=1, page_size=50
|
||||
Job.original_file_name != current_app.config['ONE_OFF_MESSAGE_FILENAME'],
|
||||
]
|
||||
if limit_days is not None:
|
||||
query_filter.append(cast(Job.created_at, sql_date) >= days_ago(limit_days))
|
||||
query_filter.append(Job.created_at >= days_ago(limit_days))
|
||||
if statuses is not None and statuses != ['']:
|
||||
query_filter.append(
|
||||
Job.job_status.in_(statuses)
|
||||
|
||||
@@ -21,7 +21,7 @@ from sqlalchemy.sql import functions
|
||||
from notifications_utils.international_billing_rates import INTERNATIONAL_BILLING_RATES
|
||||
|
||||
from app import db, create_uuid
|
||||
from app.dao import days_ago
|
||||
from app.utils import days_ago
|
||||
from app.errors import InvalidRequest
|
||||
from app.models import (
|
||||
Notification,
|
||||
@@ -75,7 +75,6 @@ def dao_get_template_usage(service_id, limit_days=None, day=None):
|
||||
).group_by(
|
||||
Notification.template_id
|
||||
).subquery()
|
||||
|
||||
query = db.session.query(
|
||||
Template.id.label('template_id'),
|
||||
Template.name,
|
||||
@@ -256,8 +255,7 @@ def get_notifications_for_service(
|
||||
filters = [Notification.service_id == service_id]
|
||||
|
||||
if limit_days is not None:
|
||||
days_ago = date.today() - timedelta(days=limit_days)
|
||||
filters.append(func.date(Notification.created_at) >= days_ago)
|
||||
filters.append(Notification.created_at >= days_ago(limit_days))
|
||||
|
||||
if older_than is not None:
|
||||
older_than_created_at = db.session.query(
|
||||
|
||||
@@ -39,7 +39,7 @@ def get_london_midnight_in_utc(date):
|
||||
This function converts date to midnight as BST (British Standard Time) to UTC,
|
||||
the tzinfo is lastly removed from the datetime because the database stores the timestamps without timezone.
|
||||
:param date: the day to calculate the London midnight in UTC for
|
||||
:return: the datetime of London midnight in UTC, for example 2016-06-17 = 2016-06-17 23:00:00
|
||||
:return: the datetime of London midnight in UTC, for example 2016-06-17 = 2016-06-16 23:00:00
|
||||
"""
|
||||
return local_timezone.localize(datetime.combine(date, datetime.min.time())).astimezone(
|
||||
pytz.UTC).replace(
|
||||
@@ -90,3 +90,10 @@ def get_public_notify_type_text(notify_type, plural=False):
|
||||
notify_type_text = 'text message'
|
||||
|
||||
return '{}{}'.format(notify_type_text, 's' if plural else '')
|
||||
|
||||
|
||||
def days_ago(number_of_days):
|
||||
"""
|
||||
Returns midnight a number of days ago. Takes care of daylight savings etc.
|
||||
"""
|
||||
return get_london_midnight_in_utc(datetime.utcnow() - timedelta(number_of_days))
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
from datetime import datetime
|
||||
|
||||
import pytest
|
||||
from freezegun import freeze_time
|
||||
|
||||
from app.utils import (
|
||||
get_london_midnight_in_utc,
|
||||
get_midnight_for_day_before,
|
||||
convert_utc_to_bst,
|
||||
convert_bst_to_utc)
|
||||
convert_bst_to_utc,
|
||||
days_ago
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('date, expected_date', [
|
||||
@@ -44,3 +48,21 @@ def test_convert_bst_to_utc():
|
||||
bst_datetime = datetime.strptime(bst, "%Y-%m-%d %H:%M")
|
||||
utc = convert_bst_to_utc(bst_datetime)
|
||||
assert utc == datetime(2017, 5, 12, 12, 15)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('current_time, expected_datetime', [
|
||||
# winter
|
||||
('2018-01-10 23:59', datetime(2018, 1, 9, 0, 0)),
|
||||
('2018-01-11 00:00', datetime(2018, 1, 10, 0, 0)),
|
||||
|
||||
# bst switchover at 1am 25th
|
||||
('2018-03-25 10:00', datetime(2018, 3, 24, 0, 0)),
|
||||
('2018-03-26 10:00', datetime(2018, 3, 25, 0, 0)),
|
||||
('2018-03-27 10:00', datetime(2018, 3, 25, 23, 0)),
|
||||
|
||||
# summer
|
||||
('2018-06-05 10:00', datetime(2018, 6, 3, 23, 0))
|
||||
])
|
||||
def test_days_ago(current_time, expected_datetime):
|
||||
with freeze_time(current_time):
|
||||
assert days_ago(1) == expected_datetime
|
||||
|
||||
Reference in New Issue
Block a user