-1

I was really surprised to not find an easy way to do this in Python. We wrote this in December and it passed, because it was winter:

def get_utc_time(dt_or_str, number_of_days=None, time_format=DATETIME_FORMAT):
    """

    :param dt_or_str:
    :return:
    """
    eastern = pytz.timezone('US/Eastern')

    # try:
    if isinstance(dt_or_str, datetime):
        new_date_str = dt_or_str.strftime(time_format)
        new_date_obj = dt_or_str
    else:
        new_date_str = dt_or_str
        new_date_obj = datetime.strptime(dt_or_str, time_format)

    if not number_of_days:
        utc_time = eastern.localize(
            datetime.strptime(new_date_str, time_format),
            is_dst=None).astimezone(pytz.utc)
    else:
        est_time = new_date_obj - timedelta(days=number_of_days)
        utc_time = eastern.localize(est_time, is_dst=None).astimezone(pytz.utc)

    utc_time = utc_time.replace(tzinfo=None)

What this did is add 5 hours to your time to make it UTC. It turns out in Spring/Summer Eastern time is only 4 hours behind UTC, so our code is now broken.

This is the test we wrote that does not work in Summer:

def test_get_utc_time_incoming_string(self):
    result = get_utc_time("2017-02-02 04:38")
    self.assertEqual(result, datetime.datetime(2017, 2, 2, 8, 38))

How can you convert EST to UTC that will work year round? I don't want to hard code it since daylight savings period changes each year.

halfer
  • 19,824
  • 17
  • 99
  • 186
codyc4321
  • 9,014
  • 22
  • 92
  • 165
  • Why do you think that a date from the winter should only be 4 hours different? Are you saying you want to apply today's timezone difference (with DST) to another date that wouldn't be in DST? That doesn't make much sense. – Mark Ransom May 12 '17 at 21:26
  • No, a winter date is 5 hours different...it's the summer/spring/early fall dates that are 4 hours off. I'll post the solution – codyc4321 May 12 '17 at 21:50
  • But your test date is a winter date in February, and you're testing to see if it's 4 hours different (4:38 vs. 8:38). – Mark Ransom May 12 '17 at 21:53

1 Answers1

0

Found this on an answer:

def is_daylight_savings(timezone_name):
    tz = pytz.timezone(timezone_name)
    now = pytz.utc.localize(datetime.utcnow())
    return now.astimezone(tz).dst() != timedelta(0)

so now this:

def get_utc_time(dt_or_str, number_of_days=None, time_format=DATETIME_FORMAT):
    """
    :param dt_or_str:
    :return:
    """
    eastern = pytz.timezone(TIMEZONE)
    it_is_daylight_savings = is_daylight_savings(TIMEZONE)

    if isinstance(dt_or_str, datetime):
        new_date_str = dt_or_str.strftime(time_format)
        new_date_obj = dt_or_str
    else:
        new_date_str = dt_or_str
        new_date_obj = datetime.strptime(dt_or_str, time_format)

    if not number_of_days:
        utc_time = eastern.localize(
            datetime.strptime(new_date_str, time_format),
            is_dst=it_is_daylight_savings).astimezone(pytz.utc)
    else:
        est_time = new_date_obj - timedelta(days=number_of_days)
        utc_time = eastern.localize(est_time, is_dst=it_is_daylight_savings).astimezone(pytz.utc)

    utc_time = utc_time.replace(tzinfo=None)

    return utc_time

as freedom of speech dies, freedom to be rude increases exponentionally

codyc4321
  • 9,014
  • 22
  • 92
  • 165