mirror of https://github.com/zulip/zulip.git
Clean up timestamps.py and add a test.
This commit is contained in:
parent
95f5c96bec
commit
4dc791f393
|
@ -15,7 +15,6 @@ from django.conf import settings
|
|||
|
||||
from analytics.models import RealmCount, UserCount
|
||||
from analytics.lib.counts import COUNT_STATS, logger, process_count_stat
|
||||
from zerver.lib.timestamp import datetime_to_string, is_timezone_aware
|
||||
from zerver.models import UserProfile, Message
|
||||
|
||||
from typing import Any
|
||||
|
@ -30,7 +29,7 @@ class Command(BaseCommand):
|
|||
parser.add_argument('--time', '-t',
|
||||
type=str,
|
||||
help='Update stat tables from current state to --time. Defaults to the current time.',
|
||||
default=datetime_to_string(timezone.now()))
|
||||
default=timezone.now().isoformat())
|
||||
parser.add_argument('--utc',
|
||||
type=bool,
|
||||
help="Interpret --time in UTC.",
|
||||
|
@ -61,7 +60,7 @@ class Command(BaseCommand):
|
|||
if options['utc']:
|
||||
fill_to_time = fill_to_time.replace(tzinfo=timezone.utc)
|
||||
|
||||
if not (is_timezone_aware(fill_to_time)):
|
||||
if fill_to_time.tzinfo is None:
|
||||
raise ValueError("--time must be timezone aware. Maybe you meant to use the --utc option?")
|
||||
|
||||
logger.info("Starting updating analytics counts through %s" % (fill_to_time,))
|
||||
|
|
|
@ -3,7 +3,7 @@ from django.utils import timezone
|
|||
|
||||
from zerver.models import Realm, UserProfile, Stream, Recipient
|
||||
from zerver.lib.str_utils import ModelReprMixin
|
||||
from zerver.lib.timestamp import datetime_to_UTC, floor_to_day
|
||||
from zerver.lib.timestamp import floor_to_day
|
||||
|
||||
import datetime
|
||||
|
||||
|
@ -29,7 +29,7 @@ class FillState(ModelReprMixin, models.Model):
|
|||
def installation_epoch():
|
||||
# type: () -> datetime.datetime
|
||||
earliest_realm_creation = Realm.objects.aggregate(models.Min('date_created'))['date_created__min']
|
||||
return floor_to_day(datetime_to_UTC(earliest_realm_creation))
|
||||
return floor_to_day(earliest_realm_creation)
|
||||
|
||||
def last_successful_fill(property):
|
||||
# type: (str) -> Optional[datetime.datetime]
|
||||
|
|
|
@ -4,37 +4,27 @@ import datetime
|
|||
import calendar
|
||||
from django.utils import timezone
|
||||
|
||||
def is_timezone_aware(datetime_object):
|
||||
# type: (datetime.datetime) -> bool
|
||||
return datetime_object.tzinfo is not None
|
||||
|
||||
def datetime_to_UTC(datetime_object):
|
||||
def floor_to_hour(dt):
|
||||
# type: (datetime.datetime) -> datetime.datetime
|
||||
if is_timezone_aware(datetime_object):
|
||||
return datetime_object.astimezone(timezone.utc)
|
||||
return datetime_object.replace(tzinfo=timezone.utc)
|
||||
return datetime.datetime(*dt.timetuple()[:4]) \
|
||||
.replace(tzinfo=dt.tzinfo)
|
||||
|
||||
def floor_to_hour(datetime_object):
|
||||
def floor_to_day(dt):
|
||||
# type: (datetime.datetime) -> datetime.datetime
|
||||
return datetime.datetime(*datetime_object.timetuple()[:4]) \
|
||||
.replace(tzinfo=datetime_object.tzinfo)
|
||||
return datetime.datetime(*dt.timetuple()[:3]) \
|
||||
.replace(tzinfo=dt.tzinfo)
|
||||
|
||||
def floor_to_day(datetime_object):
|
||||
def ceiling_to_hour(dt):
|
||||
# type: (datetime.datetime) -> datetime.datetime
|
||||
return datetime.datetime(*datetime_object.timetuple()[:3]) \
|
||||
.replace(tzinfo=datetime_object.tzinfo)
|
||||
|
||||
def ceiling_to_hour(datetime_object):
|
||||
# type: (datetime.datetime) -> datetime.datetime
|
||||
floor = floor_to_hour(datetime_object)
|
||||
if floor == datetime_object:
|
||||
floor = floor_to_hour(dt)
|
||||
if floor == dt:
|
||||
return floor
|
||||
return floor + datetime.timedelta(hours=1)
|
||||
|
||||
def ceiling_to_day(datetime_object):
|
||||
def ceiling_to_day(dt):
|
||||
# type: (datetime.datetime) -> datetime.datetime
|
||||
floor = floor_to_day(datetime_object)
|
||||
if floor == datetime_object:
|
||||
floor = floor_to_day(dt)
|
||||
if floor == dt:
|
||||
return floor
|
||||
return floor + datetime.timedelta(days=1)
|
||||
|
||||
|
@ -42,12 +32,11 @@ def timestamp_to_datetime(timestamp):
|
|||
# type: (float) -> datetime.datetime
|
||||
return datetime.datetime.fromtimestamp(float(timestamp), tz=timezone.utc)
|
||||
|
||||
def datetime_to_timestamp(datetime_object):
|
||||
# type: (datetime.datetime) -> int
|
||||
return calendar.timegm(datetime_object.timetuple())
|
||||
class TimezoneNotUTCException(Exception):
|
||||
pass
|
||||
|
||||
def datetime_to_string(datetime_object):
|
||||
# type: (datetime.datetime) -> str
|
||||
assert is_timezone_aware(datetime_object)
|
||||
date_string = datetime_object.strftime('%Y-%m-%d %H:%M:%S%z')
|
||||
return date_string
|
||||
def datetime_to_timestamp(dt):
|
||||
# type: (datetime.datetime) -> int
|
||||
if dt.tzinfo is None or dt.tzinfo.utcoffset(dt) != timezone.utc.utcoffset(dt):
|
||||
raise TimezoneNotUTCException("Datetime %s to be converted does not have a UTC timezone." % (dt,))
|
||||
return calendar.timegm(dt.timetuple())
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
from __future__ import absolute_import
|
||||
|
||||
from django.utils import timezone
|
||||
|
||||
from zerver.lib.test_classes import ZulipTestCase
|
||||
from zerver.lib.timestamp import floor_to_hour, floor_to_day, ceiling_to_hour, \
|
||||
ceiling_to_day, timestamp_to_datetime, datetime_to_timestamp, \
|
||||
TimezoneNotUTCException
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
from dateutil import parser
|
||||
import pytz
|
||||
|
||||
from six.moves import zip
|
||||
|
||||
class TestTimestamp(ZulipTestCase):
|
||||
def test_datetime_and_timestamp_conversions(self):
|
||||
# type: () -> None
|
||||
timestamp = 1483228800
|
||||
for dt in [
|
||||
parser.parse('2017-01-01 00:00:00.123 UTC'),
|
||||
parser.parse('2017-01-01 00:00:00.123').replace(tzinfo=timezone.utc),
|
||||
parser.parse('2017-01-01 00:00:00.123').replace(tzinfo=pytz.utc)]:
|
||||
self.assertEqual(timestamp_to_datetime(timestamp), dt-timedelta(microseconds=123000))
|
||||
self.assertEqual(datetime_to_timestamp(dt), timestamp)
|
||||
|
||||
for dt in [
|
||||
parser.parse('2017-01-01 00:00:00.123+01:00'),
|
||||
parser.parse('2017-01-01 00:00:00.123')]:
|
||||
with self.assertRaises(TimezoneNotUTCException):
|
||||
datetime_to_timestamp(dt)
|
Loading…
Reference in New Issue