From 68040bad9abbf3806eee2551ac1423632cb1f99e Mon Sep 17 00:00:00 2001 From: fawce Date: Wed, 18 Apr 2012 17:11:01 -0400 Subject: [PATCH] consolidated some of the date util methods. added iso8061 support --- etc/requirements.txt | 1 + zipline/date_utils.py | 47 +++++++++++++++++++++++++++++++++++++++++++ zipline/protocol.py | 32 +---------------------------- 3 files changed, 49 insertions(+), 31 deletions(-) diff --git a/etc/requirements.txt b/etc/requirements.txt index 318942c9..679b1315 100644 --- a/etc/requirements.txt +++ b/etc/requirements.txt @@ -4,3 +4,4 @@ gevent-zeromq==0.2.2 msgpack-python==0.1.12 humanhash==0.0.1 ujson==1.18 +iso8601==0.1.4 \ No newline at end of file diff --git a/zipline/date_utils.py b/zipline/date_utils.py index 966525c5..14a88571 100644 --- a/zipline/date_utils.py +++ b/zipline/date_utils.py @@ -2,6 +2,7 @@ from collections import namedtuple import time import pytz +import iso8601 import calendar from dateutil import rrule from datetime import datetime, date, timedelta @@ -11,6 +12,50 @@ from dateutil.relativedelta import * # -------------- d_tuple = namedtuple('dt', ['year', 'month', 'day', 'hour', 'minute', 'second', 'micros']) +# iso8061 utility +# --------------------- +def parse_iso8061(date_string): + dt = iso8601.parse_date(date_string) + dt = dt.replace(tzinfo = pytz.utc) + return dt + +# Epoch utilities +# --------------------- +UNIX_EPOCH = datetime(1970, 1, 1, 0, 0, tzinfo = pytz.utc) +def EPOCH(utc_datetime): + """ + The key is to ensure all the dates you are using are in the utc timezone + before you start converting. See http://pytz.sourceforge.net/ to learn how + to do that properly. By normalizing to utc, you eliminate the ambiguity of + daylight savings transitions. Then you can safely use timedelta to calculate + distance from the unix epoch, and then convert to seconds or milliseconds. + + Note that the resulting unix timestamp is itself in the UTC timezone. If you + wish to see the timestamp in a localized timezone, you will need to make + another conversion. + + Also note that this will only work for dates after 1970. + """ + assert isinstance(utc_datetime, datetime) + # utc only please + assert utc_datetime.tzinfo == pytz.utc + + # how long since the epoch? + delta = utc_datetime - UNIX_EPOCH + seconds = delta.total_seconds() + ms = seconds * 1000 + return ms + +def UN_EPOCH(ms_since_epoch): + seconds_since_epoch = ms_since_epoch / 1000 + delta = timedelta(seconds = seconds_since_epoch) + dt = UNIX_EPOCH + delta + return dt + +def iso8061_to_epoch(datestring): + dt = parse_iso8061(datestring) + return EPOCH(dt) + # UTC Datetime Subclasses # ----------------------- def utcnow(): @@ -22,6 +67,8 @@ class utcdatetime(datetime): dt = datetime.__new__(cls, *args, **kwargs) return dt + + # Datetime Calculations # --------------------- diff --git a/zipline/protocol.py b/zipline/protocol.py index b3558b6e..471238a4 100644 --- a/zipline/protocol.py +++ b/zipline/protocol.py @@ -124,6 +124,7 @@ import copy from collections import namedtuple from protocol_utils import Enum, FrameExceptionFactory, namedict +from date_utils import EPOCH, UN_EPOCH #import ujson #import ultrajson_numpy @@ -683,37 +684,6 @@ def BT_UPDATE_UNFRAME(msg): # ----------------------- # Date Helpers # ----------------------- - -UNIX_EPOCH = datetime.datetime(1970, 1, 1, 0, 0, tzinfo = pytz.utc) -def EPOCH(utc_datetime): - """ - The key is to ensure all the dates you are using are in the utc timezone - before you start converting. See http://pytz.sourceforge.net/ to learn how - to do that properly. By normalizing to utc, you eliminate the ambiguity of - daylight savings transitions. Then you can safely use timedelta to calculate - distance from the unix epoch, and then convert to seconds or milliseconds. - - Note that the resulting unix timestamp is itself in the UTC timezone. If you - wish to see the timestamp in a localized timezone, you will need to make - another conversion. - - Also note that this will only work for dates after 1970. - """ - assert isinstance(utc_datetime, datetime.datetime) - # utc only please - assert utc_datetime.tzinfo == pytz.utc - - # how long since the epoch? - delta = utc_datetime - UNIX_EPOCH - seconds = delta.total_seconds() - ms = seconds * 1000 - return ms - -def UN_EPOCH(ms_since_epoch): - seconds_since_epoch = ms_since_epoch / 1000 - delta = datetime.timedelta(seconds = seconds_since_epoch) - dt = UNIX_EPOCH + delta - return dt def PACK_DATE(event): """