1

I have a UTC time string like so

supplied_datetime = 20160711230000 -0500

This is the format

yyyyMMddhhmmss +/-hhmm

Now if I take that offset (-5hrs) from the original time it should read

supplied_datetime = 20160711180000

The next part is that I need to correct based on the local time making sure to account for any dst times.

So lets say i'm in the UK which is UTC 0000 but we are in DST +0100, then the time that ultimately gets displayed to the user will be

supplied_datetime = 20160711190000

So the formula is supplied_datetime - (supplied_utc_offset + local_utc_offset)

This is as far as I have got before asking here.

local_utc_offset = calendar.timegm(time.localtime()) - calendar.timegm(time.gmtime(time.mktime(time.localtime())))

supplied_utc_offset = parse(programme.get('start')[:20])
totalitarian
  • 3,606
  • 6
  • 32
  • 55
  • Is your code working with integers? Or with strings? – mgilson Jul 11 '16 at 19:56
  • I'm not 100% sure, but it sounds like you're trying to do the opposite of what is done here: http://stackoverflow.com/questions/79797/how-do-i-convert-local-time-to-utc-in-python?rq=1 – Bamcclur Jul 11 '16 at 20:00
  • @Bamcclur I can't use pytz as the environment I'm developing it doesn't support it. – totalitarian Jul 11 '16 at 20:03
  • @totalitarian -- What environment are you developing in? As far as I'm aware, `pytz` is pure-python so you'd have to be in a pretty exotic environment for it to be unsupported... – mgilson Jul 11 '16 at 20:10
  • @mgilson it's a plugin for plex media server. – totalitarian Jul 11 '16 at 20:21
  • Can you use django? `from django.utils import timezone; timezone.localtime(date)` – CentAu Jul 11 '16 at 20:25
  • @CentAu no I can't. I don't think it needs anything fancy. I just need to work out how many seconds -0500 is and I should be able to figure out the rest – totalitarian Jul 11 '16 at 20:26

2 Answers2

0

If the format of your date time strings are always consistent, you can manually obtain the local datetime given the utc datetime.

time.timezone gives local offset in seconds.

Then you just need to parse the datetime string and add it with local offset in hours as well as the offset in the datetime string:

from datetime import datetime
import time
dst = time.localtime().tm_isdst # daylight saving
local_offset = (dst-(time.timezone / 3600))  * 10000  # Local offset in hours format
strtime = '20160711230000 -0500'  # The original datetime string
dtstr, offset = strtime[:-6], strtime[-5:]  # separate the offset from the datetime string
utc_dt = datetime.strptime(dtstr, '%Y%m%d%H%M%S')
local_dtstr = str(int(dtstr) + int(offset) * 100 + local_offset)  # get local time string
local_dt = datetime.strptime(local_dtstr, '%Y%m%d%H%M%S')

In [37]: utc_dt
Out[37]: datetime.datetime(2016, 7, 11, 23, 0)

In [38]: local_dt
Out[38]: datetime.datetime(2016, 7, 11, 19, 0)
CentAu
  • 10,660
  • 15
  • 59
  • 85
  • Set it as a config option (Shows if you are in day light saving or not). If you need to automatically figure out if you are in dst or not, this obviously won't work. – CentAu Jul 11 '16 at 21:04
  • Yes it needs to automatic. I already have worked out the local time offset in my code above – totalitarian Jul 11 '16 at 21:05
  • Just to understand your question, your main problem is with DST? That is depending on the time of the year, you need your program to be able to figure out if you are in day light saving or not? – CentAu Jul 11 '16 at 21:07
  • No it was just a statement saying that the code needs to take DST into account. My main issue is converting the -0500 part of the string into seconds so I can do the calculation – totalitarian Jul 11 '16 at 21:08
  • Now it figures out if you are in DST or not automatically. 1 line before the last line converts the offset to local offset based on the difference in time zones (Specified in the last 5 characters of the string). It works both for negative and positive time offsets. – CentAu Jul 11 '16 at 21:19
  • Looking good but where does it work out the offset between my local time and UTC? – totalitarian Jul 11 '16 at 21:31
  • Here: `local_dtstr = str(int(str1) + int(str2) * 100 + DST)` and `str2` is just the last 5 characters of your local time offset with respect to UTC (e.g. `-0500`) – CentAu Jul 11 '16 at 21:35
  • Not sure I understand how that works. What if I was in a country where the time was -0800 from utc. Remember the offset in the string I'm given has nothing to do with my local time. – totalitarian Jul 11 '16 at 21:38
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/117023/discussion-between-totalitarian-and-centau). – totalitarian Jul 11 '16 at 21:44
0

Ok with the help of @CentAu I managed to answer this as below

import time
import calendar
from datetime import datetime, timedelta

def datetime_from_utc_to_local(input_datetime):
    #Get local offset from UTC in seconds
    local_offset_in_seconds = calendar.timegm(time.localtime()) - calendar.timegm(time.gmtime(time.mktime(time.localtime())))
    #split time from offset
    input_datetime_only, input_offset_only = input_datetime[:-6], input_datetime[-5:]
    #Convert input date to a proper date
    input_datetime_only_dt = datetime.strptime(input_datetime_only, '%Y%m%d%H%M%S')
    #Convert input_offset_only to seconds
    input_offset_mins, input_offset_hours = int(input_offset_only[3:]), int(input_offset_only[:-2])
    input_offset_in_total_seconds = (input_offset_hours * 60 * 60) + (input_offset_mins * 60);
    #Get the true offset taking into account local offset
    true_offset_in_seconds = local_offset_in_seconds + input_offset_in_total_seconds
    # add the true_offset to input_datetime
    local_dt = input_datetime_only_dt + timedelta(seconds=true_offset_in_seconds)
    return str(input_datetime) + ' ' + str(local_dt)

t = datetime_from_utc_to_local("20160711230000 +0300")
print (t)
totalitarian
  • 3,606
  • 6
  • 32
  • 55