find Last mid-night time stamp in python - python

I want to find the last mid-night time stamp (only input is current timestamp). What is the best way?
I am writing python script for a global mobile application. The user request with the current timestamp, and in server side I want to find the last mid-night timestamp of the user with out affect time zone parameters.
I searched for it, I got a solution
import time
etime = int(time.time())
midnight = (etime - (etime % 86400)) + time.altzon
Its worked for me. But I am confused with time.altzon function, Is it create any problem for the users in different timezones.

To get the midnight timestamp of the client(mobile) you need to know the client's timezone.
from datetime import datetime
import pytz # pip install pytz
fmt = '%Y-%m-%d %H:%M:%S %Z%z'
tz = pytz.timezone("America/New_York") # supply client's timezone here
# Get correct date for the midnight using given timezone.
# due to we are interested only in midnight we can:
# 1. ignore ambiguity when local time repeats itself during DST change e.g.,
# 2012-04-01 02:30:00 EST+1100 and
# 2012-04-01 02:30:00 EST+1000
# otherwise we should have started with UTC time
# 2. rely on .now(tz) to choose timezone correctly (dst/no dst)
now = datetime.now(tz)
print(now.strftime(fmt))
# Get midnight in the correct timezone (taking into account DST)
midnight = tz.localize(now.replace(hour=0, minute=0, second=0, microsecond=0, tzinfo=None),
is_dst=None)
print(midnight.strftime(fmt))
# Convert to UTC (no need to call `tz.normalize()` due to UTC has no DST transitions)
dt = midnight.astimezone(pytz.utc)
print(dt.strftime(fmt))
# Get POSIX timestamp
print((dt - datetime(1970,1,1, tzinfo=pytz.utc)).total_seconds())
Output
2012-08-09 08:46:29 EDT-0400
2012-08-09 00:00:00 EDT-0400
2012-08-09 04:00:00 UTC+0000
1344484800.0
Note: on my machine #phihag's answer produces 1344470400.0 that is different from the above (my machine is not in New York).

Related

Is it the right way to add/subtract GMT related hours to UTC time

I have a UTC date timezone aware, and I would like to add/substract hours which are UTC aware (+/- hours from GMT/UTC).
Meaning -4:00 hours are 4 hours behind UTC date time etc.
I'm running the bellow code which is working, but it feels like there is a better way.
Please confirm/infirm.
PS: I saw a few urls with examples showing how to change the time zone which I want to avoid because of DST.
from datetime import datetime, timedelta
import pytz
# Date aware of time zone
today_date = datetime.today().utcnow().replace(hour=0, minute=0, second=0, microsecond=0, tzinfo=pytz.UTC)
print(today_date)
# UTC datetime (-) Hours from is defined as:
time_zone_to_utc_suffix: str = '-4:00' # I receive the data in str
time_zone_to_utc_hours:int = int(time_zone_to_utc_suffix.split(':')[0])
#### THE PART I FEEL CAN BE IMPROVED ######
result_date_adjusted_into_utc = today_date + timedelta(hours=time_zone_to_utc_hours)
print(f'Date adjusted by {time_zone_to_utc_hours} hours, is {result_date_adjusted_into_utc}')
Tx
You wrote "add/substract hours which are UTC aware" I think you are misunderstanding what "time zone aware" means. Your date is indeed time zone aware, you correctly constructed it like this:
today_date = datetime.today().utcnow().replace(hour=0, minute=0, second=0, microsecond=0, tzinfo=pytz.UTC)
There's other ways to achieve the same, but this is fine.
However, there is no such thing as a time zone aware interval of 4 hours. 4 hours is 4 hours, no matter where you are on the planet. Only the resulting time after you add or subtract an interval can be time zone aware, or not.
If you add 4 hours to a time zone aware time, it's still in the same time zone, just 4 hours later:
right_now = datetime.today().utcnow().replace(tzinfo=pytz.UTC)
four_hours_later = right_now + timedelta(hours=4)
The value of four_hours_later is still in the UTC zone, just 4 hours later.
If you want to compute what the same time is in a time zone that's 4 hours ahead, i.e. in the '+04:00' zone, you can do this:
from datetime import datetime, timezone
import pytz
right_now = datetime.today().utcnow().replace(tzinfo=pytz.UTC)
four_hours_later = right_now + timedelta(hours=4)
right_now_in_plus_4 = right_now.astimezone(timezone(timedelta(hours=4)))
print(right_now_in_plus_4) # same time, different zone
print(four_hours_later) # same zone, different time (4h later)
Typically, since you're already using pytz, you wouldn't want to use +4:00 or anything like that, but instead just the actual name of the timezone:
right_now_in_dubai = right_now.astimezone(pytz.timezone('asia/dubai'))

When subtracting a datetime that was converted from string, total_seconds() is wrong

The total_seconds() is incorrect when I do this:
from datetime import timedelta, datetime
from pytz import timezone
timezone = timezone('Australia/Sydney')
startDate = datetime.now(timezone)
dateStr = '2020-05-18 20:12:30' # In our brain we know this time is in Sydney Time
endDate = datetime.strptime(dateStr, '%Y-%m-%d %H:%M:%S').replace(tzinfo=timezone)
diff = endDate - startDate
print(diff.total_seconds()) # incorrect answer
When both datetime objects are datetime objects originally, and you substract them, they are right
from datetime import timedelta, datetime
from pytz import timezone
timezone = timezone('Australia/Sydney')
startDate = datetime.now(timezone)
endDate = datetime.now(timezone) + timedelta(hours=2, seconds=32)
diff = endDate - startDate
print(diff.total_seconds()) # correct answer
How can I fix my issue ?
So it seems like all things in the horrible world of date-times, timezones and offsets this is one of these weird and wonderful things. the issue seems to stem from the fact that pytz.timezone will return a timezone object with several timezones.
{
(datetime.timedelta(seconds=36300), datetime.timedelta(0), 'LMT'): <DstTzInfo 'Australia/Sydney' LMT+10:05:00 STD>,
(datetime.timedelta(seconds=36000), datetime.timedelta(0), 'AEST'): <DstTzInfo 'Australia/Sydney' AEST+10:00:00 STD>,
(datetime.timedelta(seconds=39600), datetime.timedelta(seconds=3600), 'AEDT'): <DstTzInfo 'Australia/Sydney' AEDT+11:00:00 DST>
}
It seems when you are passing the timezone to the now method it's picking the timezone from your choice of 3 based on probably some local TZINFO in your setup. However, when passing the timezone to replace, it's just picking the LMT which is different by 300. A quick mention about LMT:
Local Mean Time Today: While Local Mean Time does not directly
determine civil time these days, it is still used to make sure our
clocks follow the Sun as closely as possible. UT1, a version of
Universal Time is the Local Mean Time at the prime meridian in
Greenwich, London. It is one of the components used to calculate
Coordinated Universal Time (UTC), the time scale used to determine
local times worldwide.
LMT is also used by astronomers around the world to time their
observations.
Essentially your issue spans from datetime.now() acting on the local timezone and datetime.replace() acting on the LMT timezone. So as I mentioned in my post create your dates consistently either create them both via replace (although you will still be off by 5 mins in terms of actual time, the difference will be correct.)
UPDATE
If you want both datetime objects to be in local Sydney time then you can create your stardate as you did before using datetime.now(). But you should create your end date from your timezone objects asking it to localize it for you like.
from datetime import datetime
from pytz import timezone
timezone = timezone('Australia/Sydney')
startDate = datetime.now(timezone)
dateStr = '2020-05-18 18:52:30' # In our brain we know this time is in Sydney Time
endDate = timezone.localize(datetime.strptime(dateStr, '%Y-%m-%d %H:%M:%S'))
print(startDate, endDate, sep="\n")
diff = endDate - startDate
print(diff.total_seconds())
OUTPUT
2020-05-18 18:51:24.722614+10:00
2020-05-18 18:52:30+10:00
65.277386

Is there a "local" timestamp?

I can convert from an UTC timestamp e.g. 1417392000 to a local datetime object including daylight saving time, but when I try and convert the local datetime object to a "local timestamp" then I get the same UTC timestamp as before.
Am I thinking in circles and they are the same? I was supposed to save "local timestamp" from incoming UTC timestamp.
This is my code
print("UTC timestamp %d" % hour[0])
day = self.get_day(hour)
month = self.get_month(hour)
year = self.get_year(hour)
tz = pytz.timezone('Europe/Stockholm')
utc_dt = datetime.utcfromtimestamp(int(hour[0])).replace(tzinfo=pytz.utc)
print("UTC datetime %s" % utc_dt)
dt = tz.normalize(utc_dt.astimezone(tz))
print("STO datetime %s" % dt.strftime('%Y-%m-%d %H:%M:%S %Z%z'))
print("STO ts %d" % int(time.mktime(dt.timetuple())))
print("STO timestamp %d" % utc_dt.astimezone(tz).timestamp())
day = int(dt.strftime('%d'))
month = int(dt.strftime('%m'))
year = int(dt.strftime('%Y'))
Output
UTC timestamp 1417395600
UTC datetime 2014-12-01 01:00:00+00:00
STO datetime 2014-12-01 02:00:00 CET+0100
STO ts 1417395600
STO timestamp 1417395600
All "timestamps" (i.e. integer representations of the time) are the same. Is it possible to make a "local timestamp" ? The data type is supposed to be a timestamp that is a number and in local time.
As per Wikipedia
Unix time (also known as POSIX time or Epoch time) is a system for
describing instants in time, defined as the number of seconds that
have elapsed since 00:00:00 Coordinated Universal Time (UTC),
Thursday, 1 January 1970
So regardless of what timezone you're on, the epoch will always be calculated in the UTC timezone.
For display purposes, you can convert the timestamp to a local time, but as otherwise the internal representation of the epoch will always be in the UTC timezone
Formal timestamps
The Unix timestamp typically refers to the number of seconds since the epoch in UTC. This value is invariant to timezone. It allows global event ordering but loses timezone information.
Preserving timezone
To preserve timezone information, a standardized format is RFC3339, Date and Time on the Internet: Timestamps. This is just a standardized formatting that encodes date+time+timezone. Some examples:
1985-04-12T23:20:50.52Z
1996-12-19T16:39:57-08:00
1990-12-31T23:59:60Z
1990-12-31T15:59:60-08:00
Normalizing for timezone without preservation of timezone
However, it may depend on your requirements. I once wanted to record some events relative to local-time-of-day and did not mind losing timezone information. I normalized the timestamp with respect to 1970-01-01T00:00:00 in the local timezone. I am a little sheepish about this now as I think it may too easily cause confusion.
import time
# Number of seconds since 1970-01-01T00:00+LTZ (current timezone).
# unix timestamp - timezone offset in seconds
timestamp_localized = time.time() - time.mktime(time.gmtime(0))
However this syntax can be simplified, perhaps at the loss of clarity, by noticing that Python has some localtime and UTC specific functions.
import time
import calendar
# Number of seconds since 1970-01-01T00:00+LTZ (current timezone).
# Interpret local date and time as if it were UTC
timestamp_localized = calendar.timegm(time.localtime())
The difference between these two is that calendar conversion truncates to the second while the difference calculation includes a fractional second.

python converting string in localtime to UTC epoch timestamp

I have strings in YMD hms format that had the timezone stripped. But I know they are in Eastern time with daylight savings time.
I am trying to convert them into epoch timestamps for UTC time.
I wrote the following function:
def ymdhms_timezone_dst_to_epoch(input_str, tz="US/Eastern"):
print(input_str)
dt = datetime.datetime.fromtimestamp(time.mktime(time.strptime(input_str,'%Y-%m-%d %H:%M:%S')))
local_dt = pytz.timezone(tz).localize(dt)
print(local_dt.strftime('%Y-%m-%d %H:%M:%S %Z%z'))
utc_dt = local_dt.astimezone(pytz.utc)
print(utc_dt.strftime('%Y-%m-%d %H:%M:%S %Z%z'))
e = int(utc_dt.strftime("%s"))
print(e)
return e
Given string `2015-04-20 21:12:07` this prints:
2015-04-20 21:12:07
2015-04-20 21:12:07 EDT-0400 #<- so far so good?
2015-04-21 01:12:07 UTC+0000 #<- so far so good?
1429596727
which looks ok up to the epoch timestamp. But http://www.epochconverter.com/epoch/timezones.php?epoch=1429596727 says it should mao to
Greenwich Mean Time Apr 21 2015 06:12:07 UTC.
What is wrong?
I have strings in YMD hms format that had the timezone stripped. But I know they are in Eastern time with daylight savings time.
A portable way is to use pytz:
#!/usr/bin/env python
from datetime import datetime
import pytz # $ pip install pytz
naive_dt = datetime.strptime('2015-04-20 21:12:07', '%Y-%m-%d %H:%M:%S')
tz = pytz.timezone('US/Eastern')
eastern_dt = tz.normalize(tz.localize(naive_dt))
print(eastern_dt)
# -> 2015-04-20 21:12:07-04:00
I am trying to convert them into epoch timestamps for UTC time.
timestamp = (eastern_dt - datetime(1970, 1, 1, tzinfo=pytz.utc)).total_seconds()
# -> 1429578727.0
See Converting datetime.date to UTC timestamp in Python.
There are multiple issues in your code:
time.mktime() may return a wrong result for ambiguous input time (50% chance) e.g., during "fall back" DST transition in the Fall
time.mktime() and datetime.fromtimestamp() may fail for past/future dates if they have no access to a historical timezone database on a system (notably, Windows)
localize(dt) may return a wrong result for ambiguous or non-existent time i.e., during DST transitions. If you know that the time corresponds to the summer time then use is_dst=True. tz.normalize() is necessary here, to adjust possible non-existing times in the input
utc_dt.strftime("%s") is not portable and it does not respect tzinfo object. It interprets input as a local time i.e., it returns a wrong result unless your local timezone is UTC.
Can I just always set is_dst=True?
You can, if you don't mind getting imprecise results for ambiguous or non-existent times e.g., there is DST transition in the Fall in America/New_York time zone:
>>> from datetime import datetime
>>> import pytz # $ pip install pytz
>>> tz = pytz.timezone('America/New_York')
>>> ambiguous_time = datetime(2015, 11, 1, 1, 30)
>>> time_fmt = '%Y-%m-%d %H:%M:%S%z (%Z)'
>>> tz.localize(ambiguous_time).strftime(time_fmt)
'2015-11-01 01:30:00-0500 (EST)'
>>> tz.localize(ambiguous_time, is_dst=False).strftime(time_fmt) # same
'2015-11-01 01:30:00-0500 (EST)'
>>> tz.localize(ambiguous_time, is_dst=True).strftime(time_fmt) # different
'2015-11-01 01:30:00-0400 (EDT)'
>>> tz.localize(ambiguous_time, is_dst=None).strftime(time_fmt)
Traceback (most recent call last):
...
pytz.exceptions.AmbiguousTimeError: 2015-11-01 01:30:00
The clocks are turned back at 2a.m. on the first Sunday in November:
is_dst disambiguation flag may have three values:
False -- default, assume the winter time
True -- assume the summer time
None -- raise an exception for ambiguous/non-existent times.
is_dst value is ignored for existing unique local times.
Here's a plot from PEP 0495 -- Local Time Disambiguation that illustrates the DST transition:
The local time repeats itself twice in the fold (summer time -- before the fold, winter time -- after).
To be able to disambiguate the local time automatically, you need some additional info e.g., if you read a series of local times then it may help if you know that they are sorted: Parsing of Ordered Timestamps in Local Time (to UTC) While Observing Daylight Saving Time.
First of all '%s' is not supported on all platforms , its actually working for you because your platform C library’s strftime() function (that is called by Python) supports it. This function is what is causing the issue most probably, I am guessing its not timezone aware , hence when taking difference from epoch time it is using your local timezone, which is most probably EST(?)
Instead of relying on '%s' , which only works in few platforms (linux, I believe) , you should manually subtract the datetime you got from epoch (1970/1/1 00:00:00) to get the actual seconds since epoch . Example -
e = (utc_dt - datetime.datetime(1970,1,1,0,0,0,tzinfo=pytz.utc)).total_seconds()
Demo -
>>> (utc_dt - datetime.datetime(1970,1,1,0,0,0,tzinfo=pytz.utc)).total_seconds()
1429578727.0
This correctly corresponds to the date-time you get.
I don't exactly know why but you have to remove the timezone info from your utc_dt before using %s to print it.
e = int(utc_dt.replace(tzinfo=None).strftime("%s"))
print(e)
return e

Convert UTC datetime string to local datetime

I've never had to convert time to and from UTC. Recently had a request to have my app be timezone aware, and I've been running myself in circles. Lots of information on converting local time to UTC, which I found fairly elementary (maybe I'm doing that wrong as well), but I can not find any information on easily converting the UTC time to the end-users timezone.
In a nutshell, and android app sends me (appengine app) data and within that data is a timestamp. To store that timestamp to utc time I am using:
datetime.utcfromtimestamp(timestamp)
That seems to be working. When my app stores the data, it is being store as 5 hours ahead (I am EST -5)
The data is being stored on appengine's BigTable, and when retrieved it comes out as a string like so:
"2011-01-21 02:37:21"
How do I convert this string to a DateTime in the users correct time zone?
Also, what is the recommended storage for a users timezone information? (How do you typically store tz info ie: "-5:00" or "EST" etc etc ?) I'm sure the answer to my first question might contain a parameter the answers the second.
If you don't want to provide your own tzinfo objects, check out the python-dateutil library. It provides tzinfo implementations on top of a zoneinfo (Olson) database such that you can refer to time zone rules by a somewhat canonical name.
from datetime import datetime
from dateutil import tz
# METHOD 1: Hardcode zones:
from_zone = tz.gettz('UTC')
to_zone = tz.gettz('America/New_York')
# METHOD 2: Auto-detect zones:
from_zone = tz.tzutc()
to_zone = tz.tzlocal()
# utc = datetime.utcnow()
utc = datetime.strptime('2011-01-21 02:37:21', '%Y-%m-%d %H:%M:%S')
# Tell the datetime object that it's in UTC time zone since
# datetime objects are 'naive' by default
utc = utc.replace(tzinfo=from_zone)
# Convert time zone
central = utc.astimezone(to_zone)
Edit Expanded example to show strptime usage
Edit 2 Fixed API usage to show better entry point method
Edit 3 Included auto-detect methods for timezones (Yarin)
Here's a resilient method that doesn't depend on any external libraries:
from datetime import datetime
import time
def datetime_from_utc_to_local(utc_datetime):
now_timestamp = time.time()
offset = datetime.fromtimestamp(now_timestamp) - datetime.utcfromtimestamp(now_timestamp)
return utc_datetime + offset
This avoids the timing issues in DelboyJay's example. And the lesser timing issues in Erik van Oosten's amendment.
As an interesting footnote, the timezone offset computed above can differ from the following seemingly equivalent expression, probably due to daylight savings rule changes:
offset = datetime.fromtimestamp(0) - datetime.utcfromtimestamp(0) # NO!
Update: This snippet has the weakness of using the UTC offset of the present time, which may differ from the UTC offset of the input datetime. See comments on this answer for another solution.
To get around the different times, grab the epoch time from the time passed in. Here's what I do:
def utc2local(utc):
epoch = time.mktime(utc.timetuple())
offset = datetime.fromtimestamp(epoch) - datetime.utcfromtimestamp(epoch)
return utc + offset
See the datetime documentation on tzinfo objects. You have to implement the timezones you want to support yourself. The are examples at the bottom of the documentation.
Here's a simple example:
from datetime import datetime,tzinfo,timedelta
class Zone(tzinfo):
def __init__(self,offset,isdst,name):
self.offset = offset
self.isdst = isdst
self.name = name
def utcoffset(self, dt):
return timedelta(hours=self.offset) + self.dst(dt)
def dst(self, dt):
return timedelta(hours=1) if self.isdst else timedelta(0)
def tzname(self,dt):
return self.name
GMT = Zone(0,False,'GMT')
EST = Zone(-5,False,'EST')
print datetime.utcnow().strftime('%m/%d/%Y %H:%M:%S %Z')
print datetime.now(GMT).strftime('%m/%d/%Y %H:%M:%S %Z')
print datetime.now(EST).strftime('%m/%d/%Y %H:%M:%S %Z')
t = datetime.strptime('2011-01-21 02:37:21','%Y-%m-%d %H:%M:%S')
t = t.replace(tzinfo=GMT)
print t
print t.astimezone(EST)
Output
01/22/2011 21:52:09
01/22/2011 21:52:09 GMT
01/22/2011 16:52:09 EST
2011-01-21 02:37:21+00:00
2011-01-20 21:37:21-05:00a
If you want to get the correct result even for the time that corresponds to an ambiguous local time (e.g., during a DST transition) and/or the local utc offset is different at different times in your local time zone then use pytz timezones:
#!/usr/bin/env python
from datetime import datetime
import pytz # $ pip install pytz
import tzlocal # $ pip install tzlocal
local_timezone = tzlocal.get_localzone() # get pytz tzinfo
utc_time = datetime.strptime("2011-01-21 02:37:21", "%Y-%m-%d %H:%M:%S")
local_time = utc_time.replace(tzinfo=pytz.utc).astimezone(local_timezone)
This answer should be helpful if you don't want to use any other modules besides datetime.
datetime.utcfromtimestamp(timestamp) returns a naive datetime object (not an aware one). Aware ones are timezone aware, and naive are not. You want an aware one if you want to convert between timezones (e.g. between UTC and local time).
If you aren't the one instantiating the date to start with, but you can still create a naive datetime object in UTC time, you might want to try this Python 3.x code to convert it:
import datetime
d=datetime.datetime.strptime("2011-01-21 02:37:21", "%Y-%m-%d %H:%M:%S") #Get your naive datetime object
d=d.replace(tzinfo=datetime.timezone.utc) #Convert it to an aware datetime object in UTC time.
d=d.astimezone() #Convert it to your local timezone (still aware)
print(d.strftime("%d %b %Y (%I:%M:%S:%f %p) %Z")) #Print it with a directive of choice
Be careful not to mistakenly assume that if your timezone is currently MDT that daylight savings doesn't work with the above code since it prints MST. You'll note that if you change the month to August, it'll print MDT.
Another easy way to get an aware datetime object (also in Python 3.x) is to create it with a timezone specified to start with. Here's an example, using UTC:
import datetime, sys
aware_utc_dt_obj=datetime.datetime.now(datetime.timezone.utc) #create an aware datetime object
dt_obj_local=aware_utc_dt_obj.astimezone() #convert it to local time
#The following section is just code for a directive I made that I liked.
if sys.platform=="win32":
directive="%#d %b %Y (%#I:%M:%S:%f %p) %Z"
else:
directive="%-d %b %Y (%-I:%M:%S:%f %p) %Z"
print(dt_obj_local.strftime(directive))
If you use Python 2.x, you'll probably have to subclass datetime.tzinfo and use that to help you create an aware datetime object, since datetime.timezone doesn't exist in Python 2.x.
If using Django, you can use the timezone.localtime method:
from django.utils import timezone
date
# datetime.datetime(2014, 8, 1, 20, 15, 0, 513000, tzinfo=<UTC>)
timezone.localtime(date)
# datetime.datetime(2014, 8, 1, 16, 15, 0, 513000, tzinfo=<DstTzInfo 'America/New_York' EDT-1 day, 20:00:00 DST>)
The following worked for me in a Cloud environment for US west:
import datetime
import pytz
#set the timezone
tzInfo = pytz.timezone('America/Los_Angeles')
dt = datetime.datetime.now(tz=tzInfo)
print(dt)
Consolidating the answer from franksands into a convenient method.
import calendar
import datetime
def to_local_datetime(utc_dt):
"""
convert from utc datetime to a locally aware datetime according to the host timezone
:param utc_dt: utc datetime
:return: local timezone datetime
"""
return datetime.datetime.fromtimestamp(calendar.timegm(utc_dt.timetuple()))
You can use arrow
from datetime import datetime
import arrow
now = datetime.utcnow()
print(arrow.get(now).to('local').format())
# '2018-04-04 15:59:24+02:00'
you can feed arrow.get() with anything. timestamp, iso string etc
You can use calendar.timegm to convert your time to seconds since Unix epoch and time.localtime to convert back:
import calendar
import time
time_tuple = time.strptime("2011-01-21 02:37:21", "%Y-%m-%d %H:%M:%S")
t = calendar.timegm(time_tuple)
print time.ctime(t)
Gives Fri Jan 21 05:37:21 2011 (because I'm in UTC+03:00 timezone).
import datetime
def utc_str_to_local_str(utc_str: str, utc_format: str, local_format: str):
"""
:param utc_str: UTC time string
:param utc_format: format of UTC time string
:param local_format: format of local time string
:return: local time string
"""
temp1 = datetime.datetime.strptime(utc_str, utc_format)
temp2 = temp1.replace(tzinfo=datetime.timezone.utc)
local_time = temp2.astimezone()
return local_time.strftime(local_format)
utc_tz_example_str = '2018-10-17T00:00:00.111Z'
utc_fmt = '%Y-%m-%dT%H:%M:%S.%fZ'
local_fmt = '%Y-%m-%dT%H:%M:%S+08:00'
# call my function here
local_tz_str = utc_str_to_local_str(utc_tz_example_str, utc_fmt, local_fmt)
print(local_tz_str) # 2018-10-17T08:00:00+08:00
When I input utc_tz_example_str = 2018-10-17T00:00:00.111Z, (UTC +00:00)
then I will get local_tz_str = 2018-10-17T08:00:00+08:00 (My target timezone +08:00)
parameter utc_format is a format determined by your specific utc_tz_example_str.
parameter local_fmt is the final desired format.
In my case, my desired format is %Y-%m-%dT%H:%M:%S+08:00 ( +08:00 timezone). You should construct the format you want.
This worked for me:
from django.utils import timezone
from datetime import timedelta,datetime
ist_time = timezone.now() + timedelta(hours=5,minutes=30)
#second method
ist_time = datetime.now() + timedelta(hours=5,minutes=30)
I traditionally defer this to the frontend -- send times from the backend as timestamps or some other datetime format in UTC, then let the client figure out the timezone offset and render this data in the proper timezone.
For a webapp, this is pretty easy to do in javascript -- you can figure out the browser's timezone offset pretty easily using builtin methods and then render the data from the backend properly.
From the answer here, you can use the time module to convert from utc to the local time set in your computer:
utc_time = time.strptime("2018-12-13T10:32:00.000", "%Y-%m-%dT%H:%M:%S.%f")
utc_seconds = calendar.timegm(utc_time)
local_time = time.localtime(utc_seconds)
Here is a quick and dirty version that uses the local systems settings to work out the time difference. NOTE: This will not work if you need to convert to a timezone that your current system is not running in. I have tested this with UK settings under BST timezone
from datetime import datetime
def ConvertP4DateTimeToLocal(timestampValue):
assert isinstance(timestampValue, int)
# get the UTC time from the timestamp integer value.
d = datetime.utcfromtimestamp( timestampValue )
# calculate time difference from utcnow and the local system time reported by OS
offset = datetime.now() - datetime.utcnow()
# Add offset to UTC time and return it
return d + offset
Short and simple:
from datetime import datetime
t = "2011-01-21 02:37:21"
datetime.fromisoformat(t) + (datetime.now() - datetime.utcnow())

Categories