
from datetime import datetime
import re

from dateutil import parser
import pytz
import six

UTC_EPOCH = datetime(1970, 1, 1).replace(tzinfo=pytz.utc)
MAX_POSIX_TIMESTAMP = pow(2, 32) - 1


class timestamp_ms(object):
    """Build UTC timestamp in milliseconds
    """

    @classmethod
    def feeling_lucky(cls, obj):
        """Tries to convert given object to an UTC timestamp is ms, based
        on its type.
        """
        if isinstance(obj, six.string_types):
            return cls.from_str(obj)
        elif isinstance(obj, six.integer_types) and obj <= MAX_POSIX_TIMESTAMP:
            return cls.from_posix_timestamp(obj)
        elif isinstance(obj, datetime):
            return cls.from_datetime(obj)
        else:
            raise Exception("Don't know how to get timestamp")

    @classmethod
    def from_str(cls, timestr):
        """Use `dateutil` module to parse the give string
        """
        return cls.from_datetime(parser.parse(timestr))

    @classmethod
    def from_ymd(cls, year, month=1, day=1):
        return cls.from_datetime(datetime(
            year=year, month=month, day=day
        ))

    @classmethod
    def from_posix_timestamp(cls, ts):
        return cls.from_datetime(datetime.utcfromtimestamp(ts))

    @classmethod
    def from_datetime(cls, date):
        if date.tzinfo is None:
            date = date.replace(tzinfo=pytz.utc)
        return (date - UTC_EPOCH).total_seconds() * 1e3 + \
            date.microsecond / 1e3

    @classmethod
    def from_imap_header(cls, date_header_value):
        if re.match(r".*\d{4}.*\d{4}", date_header_value):
            # replace '-0000' timezone information to '-00:00'
            date_header_value = re.sub(
                r"(.*)(\s+[\+-]?\d\d)(\d\d).*$",
                r"\1 \2:\3",
                date_header_value
            )
        return cls.from_str(date_header_value)

    @classmethod
    def now(cls):
        return cls.from_datetime(datetime.utcnow())

@@ -1676,36 +1676,24 @@
             
-date_header_
 value = re.s
@@ -1696,16 +1696,16 @@
 re.sub(%0A
+
         
@@ -1822,16 +1822,360 @@
       )%0A
+        else:%0A            value = date_header_value%0A        try:%0A            return cls.from_str(value)%0A        except ValueError:%0A            if re.match(r%22.*%5B%5C-+%5D?%5Cd%7B2%7D:%5Cd%7B2%7D$%22, value):%0A                value = re.sub(%0A                    r%22(.*)(%5Cs%5B%5C+-%5D?%5Cd%5Cd:%5Cd%5Cd)$%22,%0A                    r%22%5C1%22,%0A                    value%0A                )%0A    
         
@@ -2194,28 +2194,16 @@
 rom_str(
-date_header_
 value)%0A%0A

improve IMAP date extraction