Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update to add timezone support. #42

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
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
5 changes: 3 additions & 2 deletions app_metrics/management/commands/move_to_mixpanel.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

from app_metrics.models import MetricItem
from app_metrics.backends.mixpanel import metric
from app_metrics.utils import get_backend
from app_metrics.utils import get_backend, get_timestamp


class Command(NoArgsCommand):
help = "Move MetricItems from the db backend to MixPanel"
Expand All @@ -23,7 +24,7 @@ def handle_noargs(self, **options):

for i in items:
properties = {
'time': i.created.strftime('%s'),
'time': int(get_timestamp(i.created)),
}
metric(i.metric.slug, num=i.num, properties=properties)

Expand Down
9 changes: 5 additions & 4 deletions app_metrics/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from django.db import models, IntegrityError
from django.template.defaultfilters import slugify
from django.utils.translation import ugettext_lazy as _
from django.utils import timezone

from app_metrics.compat import User

Expand Down Expand Up @@ -55,7 +56,7 @@ class MetricItem(models.Model):
""" Individual metric items """
metric = models.ForeignKey(Metric, verbose_name=_('metric'))
num = models.IntegerField(_('number'), default=1)
created = models.DateTimeField(_('created'), default=datetime.datetime.now)
created = models.DateTimeField(_('created'), default=timezone.datetime.now)

class Meta:
verbose_name = _('metric item')
Expand Down Expand Up @@ -146,8 +147,8 @@ class Gauge(models.Model):
name = models.CharField(_('name'), max_length=50)
slug = models.SlugField(_('slug'), unique=True, max_length=60)
current_value = models.DecimalField(_('current value'), max_digits=15, decimal_places=6, default='0.00')
created = models.DateTimeField(_('created'), default=datetime.datetime.now)
updated = models.DateTimeField(_('updated'), default=datetime.datetime.now)
created = models.DateTimeField(_('created'), default=timezone.datetime.now)
updated = models.DateTimeField(_('updated'), default=timezone.datetime.now)

class Meta:
verbose_name = _('gauge')
Expand All @@ -160,5 +161,5 @@ def save(self, *args, **kwargs):
if not self.id and not self.slug:
self.slug = slugify(self.name)

self.updated = datetime.datetime.now()
self.updated = timezone.datetime.now()
return super(Gauge, self).save(*args, **kwargs)
30 changes: 30 additions & 0 deletions app_metrics/tests/base_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from django.core import mail
from django.contrib.auth.models import User
from django.core.exceptions import ImproperlyConfigured
from django.utils import timezone

from app_metrics.exceptions import TimerError
from app_metrics.models import Metric, MetricItem, MetricDay, MetricWeek, MetricMonth, MetricYear, Gauge
Expand Down Expand Up @@ -336,3 +337,32 @@ def test_mixpanel_op(self):

def tearDown(self):
settings.APP_METRICS_BACKEND = self.old_backend

class TestTimezone(datetime.tzinfo):
def utcoffset(self, dt):
return datetime.timedelta(hours=-9)

class TimestampTest(TestCase):
""" Test timestamp utilities """

def test_tz_timestamp(self):
dt = datetime.datetime(2016, 05, 01, 0, 0, 0, tzinfo=timezone.utc)
utc_ts = get_timestamp(dt)
dt_tz = datetime.datetime(2016, 05, 01, 0, 0, 0, tzinfo=TestTimezone())
tz_ts = get_timestamp(dt_tz)

# timestamp with a UTC offset of -9 hours should be ahead by 32400 seconds.
self.assertEqual(utc_ts, tz_ts - 32400)

def test_naive_timestamp(self):
dt = datetime.datetime(2016, 05, 01, 0, 0, 0, tzinfo=None)

# Naive datetime to timestamp will just use local timezone. Same
# behavior as using strftime('%s') on 'nix systems.

# The above dt, even in a TZ of -12 hours would have to be more than
# or equal to 1462060800 (UTC) - 43200 seconds as a timestamp.
self.assertGreaterEqual(get_timestamp(dt), 1462060800 - 43200)

# However, it should be less than or equal to the same +12 hours.
self.assertLessEqual(get_timestamp(dt), 1462060800 + 43200)
15 changes: 15 additions & 0 deletions app_metrics/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import time
from django.conf import settings
from django.utils.importlib import import_module
from django.utils import timezone

from app_metrics.exceptions import InvalidMetricsBackend, TimerError
from app_metrics.models import Metric, MetricSet
Expand Down Expand Up @@ -227,3 +228,17 @@ def get_previous_year(date):
new = date
return new.replace(year=new.year-1)

def timedelta_total_seconds(timedelta):
return timedelta.seconds + timedelta.days * 24 * 3600

def get_timestamp(dt):
if dt.tzinfo is None:
return time.mktime((dt.year, dt.month, dt.day,
dt.hour, dt.minute, dt.second,
-1, -1, -1))
else:
timedelta = dt - datetime.datetime(1970, 1, 1, tzinfo=timezone.utc)
try:
return timedelta.total_seconds()
except AttributeError:
return timedelta_total_seconds(timedelta)