Size: 2621
Comment:
|
Size: 5543
Comment:
|
Deletions are marked like this. | Additions are marked like this. |
Line 3: | Line 3: |
[[attachment:dateutils.py|Download DateUtils]] This utility class will convert different date time formats into the proper format to create a Python {{{datetime}}} object. It will use the current locate to determine differences that can not be determined in any other way such as 01/01/2010 meaning either dd/mm/yyyy or mm/dd/yyyy. The methods are all {{{classmethods}}}. A string value is passed into the {{{DateUtils.toDatetime()}}} method. If you know the format of your date or only want to allow a specific format that format can be passed into the {{{format}}} keyword argument. Examples: - Date but no time |
|
Line 4: | Line 16: |
import re | from dateutils import DateUtils DateUtils.toDatetime('2010/04/05') Out[2]: datetime.datetime(2010, 4, 5, 0, 0) }}} - Date and Time {{{ from dateutils import DateUtils DateUtils.toDatetime('2010/04/05 23:20:59') Out[3]: datetime.datetime(2010, 4, 5, 23, 20, 59) }}} - Date, Time and the format is specified. {{{ from dateutils import DateUtils DateUtils.toDatetime('20100405232059', format="yyyymmddHHMMSS") Out[6]: datetime.datetime(2010, 4, 5, 23, 20, 59) }}} == Exceptions == 1. A {{{ValueError}}} will be raised if the value does not match the format or if the format can not be determined. 1. A {{{KeyError}}} will be raised if the the date time format is not supported. {{{ # # dateutils.py # import re, locale |
Line 8: | Line 54: |
class BaseUtils(object): | class DateUtils(object): |
Line 11: | Line 57: |
def __init__(self): pass |
__YMD = "yyyy-mm-dd hh:mm:ss" __MDY = "mm-dd-yyyy hh:mm:ss" __DMY = "dd-mm-yyyy hh:mm:ss" __YMD_NON_DLM = "yyyymmddHHMMSS" |
Line 16: | Line 63: |
return value | size = len(value) y = value[:4] m = value[5:7] d = value[8:10] H = M = S = 0 if size >= 13: H = value[11:13] if size >= 16: M = value[14:16] if size >= 19: S = value[17:] return "%s-%s-%s %02i:%02i:%02i" % (y, m, d, H, M, S) |
Line 19: | Line 74: |
size = len(value) | |
Line 22: | Line 78: |
if len(value) > 10: value = "%s-%s-%s %s" % (y, m, d, value[11:]) else: value = "%s-%s-%s" % (y, m, d) return value |
H = M = S = 0 if size >= 13: H = value[11:13] if size >= 16: M = value[14:16] if size >= 19: S = value[17:] return "%s-%s-%s %02i:%02i:%02i" % (y, m, d, H, M, S) |
Line 31: | Line 85: |
size = len(value) | |
Line 34: | Line 89: |
if len(value) > 10: value = "%s-%s-%s %s" % (y, m, d, value[11:]) else: value = "%s-%s-%s" % (y, m, d) return value |
H = M = S = 0 if size >= 13: H = value[11:13] if size >= 16: M = value[14:16] if size >= 19: S = value[17:] return "%s-%s-%s %02i:%02i:%02i" % (y, m, d, H, M, S) |
Line 43: | Line 96: |
size = len(value) | |
Line 46: | Line 100: |
H = value[8:10] M = value[10:12] |
H = M = S = 0 if size >= 10: H = value[8:10] if size >= 12: M = value[10:12] if size >= 14: S = value[12:] return "%s-%s-%s %02i:%02i:%02i" % (y, m, d, H, M, S) |
Line 49: | Line 106: |
if len(value) > 12: S = value[12:] value = "%s-%s-%s %s:%s:%s" % (y, m, d, H, M, S) else: value = "%s-%s-%s %s:%s" % (y, m, d, H, M) return value __FROM_DATE_FORMATS = {'yyyy-mm-dd hh:mm:ss': __transposeFromYMDHMS, 'mm-dd-yyyy hh:mm:ss': __transposeFromMDYHMS, 'dd-mm-yyyy hh:mm:ss': __transposeFromDMYHMS, 'yyyymmddHHMMSS': __transposeNonDelimiterYMDHMS} |
__FROM_DATE_FORMATS = {__YMD: __transposeFromYMDHMS, __MDY: __transposeFromMDYHMS, __DMY: __transposeFromDMYHMS, __YMD_NON_DLM: __transposeNonDelimiterYMDHMS} |
Line 63: | Line 112: |
def toDatetime(self, value, format='yyyy-mm-dd hh:mm:ss'): | def toDatetime(self, value, format=None): |
Line 72: | Line 121: |
format = self.__dateRegex.sub('-', format) | if format is None: format = DateUtils._snoopDateFormat(value) fmt = self.__dateRegex.sub('-', format) |
Line 75: | Line 125: |
value = self.__FROM_DATE_FORMATS[format](self, value) | value = self.__FROM_DATE_FORMATS[fmt](self, value) |
Line 78: | Line 128: |
msg = "Invalid date format should be one of %s." % \ self.__FROM_DATE_FORMATS.keys() raise KeyError(msg) |
msg = "Invalid date format should be one of %s." raise KeyError(msg % self.__FROM_DATE_FORMATS.keys()) except ValueError, e: msg = "The value %s does not match the format %s, %s" raise ValueError(msg % (value, format, e)) |
Line 87: | Line 139: |
(format, value, e) | (fmt, value, e) |
Line 89: | Line 141: |
@classmethod def _snoopDateFormat(self, value): """ We determine what we can then rely on the current systems locale setting to determine the difference of 01/01/2010 to mean mm/dd/yyy or dd/mm/yyyy. """ fmt = None delim = any([char for char in value if char in ('-', '.', '/', ':')]) year = value[:4].isdigit() lfmt = locale.nl_langinfo(locale.D_FMT) if year and not delim: fmt = self.__YMD_NON_DLM elif year and delim: fmt = self.__YMD elif lfmt[1] == 'm': fmt = self.__MDY elif lfmt[1] == 'd': fmt = self.__DMY else: msg = "Invalid date time format: %s" raise ValueError(msg % value) return fmt def getFormatTypes(self): return (self.__YMD, self.__MDY, self.__DMY, self.__YMD_NON_DLM) |
Date/Time Conversion
This utility class will convert different date time formats into the proper format to create a Python datetime object. It will use the current locate to determine differences that can not be determined in any other way such as 01/01/2010 meaning either dd/mm/yyyy or mm/dd/yyyy.
The methods are all classmethods.
A string value is passed into the DateUtils.toDatetime() method. If you know the format of your date or only want to allow a specific format that format can be passed into the format keyword argument.
Examples:
- - Date but no time
from dateutils import DateUtils DateUtils.toDatetime('2010/04/05') Out[2]: datetime.datetime(2010, 4, 5, 0, 0)
- - Date and Time
from dateutils import DateUtils DateUtils.toDatetime('2010/04/05 23:20:59') Out[3]: datetime.datetime(2010, 4, 5, 23, 20, 59)
- - Date, Time and the format is specified.
from dateutils import DateUtils DateUtils.toDatetime('20100405232059', format="yyyymmddHHMMSS") Out[6]: datetime.datetime(2010, 4, 5, 23, 20, 59)
Exceptions
A ValueError will be raised if the value does not match the format or if the format can not be determined.
A KeyError will be raised if the the date time format is not supported.
# # dateutils.py # import re, locale from datetime import datetime class DateUtils(object): __DATE_REGEX = r"[/.]+" __dateRegex = re.compile(__DATE_REGEX) __YMD = "yyyy-mm-dd hh:mm:ss" __MDY = "mm-dd-yyyy hh:mm:ss" __DMY = "dd-mm-yyyy hh:mm:ss" __YMD_NON_DLM = "yyyymmddHHMMSS" def __transposeFromYMDHMS(self, value): size = len(value) y = value[:4] m = value[5:7] d = value[8:10] H = M = S = 0 if size >= 13: H = value[11:13] if size >= 16: M = value[14:16] if size >= 19: S = value[17:] return "%s-%s-%s %02i:%02i:%02i" % (y, m, d, H, M, S) def __transposeFromMDYHMS(self, value): size = len(value) m = value[:2] d = value[3:5] y = value[6:10] H = M = S = 0 if size >= 13: H = value[11:13] if size >= 16: M = value[14:16] if size >= 19: S = value[17:] return "%s-%s-%s %02i:%02i:%02i" % (y, m, d, H, M, S) def __transposeFromDMYHMS(self, value): size = len(value) d = value[:2] m = value[3:5] y = value[6:10] H = M = S = 0 if size >= 13: H = value[11:13] if size >= 16: M = value[14:16] if size >= 19: S = value[17:] return "%s-%s-%s %02i:%02i:%02i" % (y, m, d, H, M, S) def __transposeNonDelimiterYMDHMS(self, value): size = len(value) y = value[:4] m = value[4:6] d = value[6:8] H = M = S = 0 if size >= 10: H = value[8:10] if size >= 12: M = value[10:12] if size >= 14: S = value[12:] return "%s-%s-%s %02i:%02i:%02i" % (y, m, d, H, M, S) __FROM_DATE_FORMATS = {__YMD: __transposeFromYMDHMS, __MDY: __transposeFromMDYHMS, __DMY: __transposeFromDMYHMS, __YMD_NON_DLM: __transposeNonDelimiterYMDHMS} @classmethod def toDatetime(self, value, format=None): """ Convert a string representation of a date and time to a python datetime object. @param value: The string value to convert. @keyword format: The format to convert from. @return: A Python datetime object. """ if format is None: format = DateUtils._snoopDateFormat(value) fmt = self.__dateRegex.sub('-', format) try: value = self.__FROM_DATE_FORMATS[fmt](self, value) date, time = value.split(' ') except KeyError, e: msg = "Invalid date format should be one of %s." raise KeyError(msg % self.__FROM_DATE_FORMATS.keys()) except ValueError, e: msg = "The value %s does not match the format %s, %s" raise ValueError(msg % (value, format, e)) try: return datetime(*[int(float(x)) for x in date.split("-")] + [int(float(x)) for x in time.split(":")]) except Exception, e: msg = "Invalid format for datetime %s, found: %s, %s" % \ (fmt, value, e) raise Exception(msg) @classmethod def _snoopDateFormat(self, value): """ We determine what we can then rely on the current systems locale setting to determine the difference of 01/01/2010 to mean mm/dd/yyy or dd/mm/yyyy. """ fmt = None delim = any([char for char in value if char in ('-', '.', '/', ':')]) year = value[:4].isdigit() lfmt = locale.nl_langinfo(locale.D_FMT) if year and not delim: fmt = self.__YMD_NON_DLM elif year and delim: fmt = self.__YMD elif lfmt[1] == 'm': fmt = self.__MDY elif lfmt[1] == 'd': fmt = self.__DMY else: msg = "Invalid date time format: %s" raise ValueError(msg % value) return fmt def getFormatTypes(self): return (self.__YMD, self.__MDY, self.__DMY, self.__YMD_NON_DLM)