I'm using MixPanel and trying to convert the ['property']['time'] field that I get when I'm reviewing events. I thought it was a UTC time, and this is how I'm trying to convert the value back to my local timezone.
from dateutil import tz
from_zone = tz.tzutc()
to_zone = tz.tzlocal()
def convert_from_mix_time(mix_time):
utc_date = datetime.fromtimestamp(int(mix_time))
utc_date = utc_date.replace(tzinfo=from_zone)
local_date = utc_date.astimezone(to_zone)
return local_date
Taking the MixPanel time 1394199886 (this should be 4:44 PM EST), the UTC time is 2014-03-07 08:44:46+00:00 and the converted time is 2014-03-07 03:44:46 (definitely not the right time). Anyone know how to do the conversion?
I don't get that timestamp to be 4:44 PM EST, but I could recommend utcfromtimestamp() if you want your code to be a bit simpler.
dt = datetime.datetime.utcfromtimestamp(ts)
You need to normalize the datetime object:
def convert_mix_time(mix_time):
utc_date = datetime.utcfromtimestamp(int(mix_time))
utc_date = utc_date.replace(tzinfo=from_zone)
local_date = utc_date.astimezone(to_zone)
return from_zone.normalize(local_date)
The timzeone of the data is defined per project. Click on the geat icon at the bottom right of Mixpanel's Web UI. It'll open a window. In the Data management section there's a Timezone field. Set it to UTC. that's the timezone Mixpanel will record the data coming in. Note that it won't affect past data. After that you can convert the timezone like you did.
Related
I am writing Python code using arrow library to convert timezone (which will be UTC by default) in the string (without date) to another timezone.
A sample string value is: 18:30+0000
The code snippet is :
start = '18:30+0000'
start_time = arrow.get(start,'hh:mmZ')
print(start_time.format('hh:mm A ZZ'))
print(start_time.to('Australia/Melbourne').format('hh:mm A ZZ'))
# This should print 05:30 AM +11:00 - but showing 04:09 AM +09:39
I have also tried to convert to other timezones as well.
print(start_time.to('Europe/London').format('hh:mm A ZZ'))
# This should print 06:30 PM +00:00 - but showing 06:28 PM -00:01
Getting UTC now and then converting it to different timezone working perfectly fine
print(arrow.utcnow().to('Australia/Melbourne').format('hh:mm A ZZ'))
SOLUTION:
We have to add temporary date value for conversion if we don't have date value.
def convert_timezone(time_to_convert,timezone):
time_to_convert='20111111 '+time_to_convert
return arrow.get(time_to_convert).to(timezone)
print(convert_timezone('18:30+0000','Australia/Melbourne').format('hh:mm A ZZ'))
add an appropriate date to the input string and this works as you expect:
import arrow
start = '2021-02-01 18:30+0000'
start_time = arrow.get(start)
print(start_time.to('Australia/Melbourne').format('hh:mm A ZZ'))
# 05:30 AM +11:00
I have read the docs saying that to pass the value for a Hubspot date field you should format your Date as midnight UTC. However, I've had no luck doing so in Python. I assume I am just missing the magic Python incantation that will get the right result. Here is what I have:
from pytz import timezone, utc
from hubspot.crm.contacts import SimplePublicObject,
created_dt = # datetime from sqlalchemy query
utcdt = utc.localize(
datetime(
year=created_dt.year,
month=created_dt.month,
day=created_dt.day
)
)
ts = int(utcdt.timestamp())
props = SimplePublicObjectInput({"last_booking": str(ts)})
return client.crm.companies.basic_api.update(
hs_id, simple_public_object_input=props
)
this returns this error:
{"status":"error",
"message":"Property values were not valid: [{\"isValid\":false,\"message\":\"1570233600 is at 4:10:33.600 UTC, not midnight!\"...
}
Ah, the answer was right there. Python timestamp returns the time in seconds, and HubSpot expects milliseconds. I just had to multiply by 1000:
ts = int(utcdt.timestamp()*1000)
now all looks good.
did you try adding hours and minutes to your datetime call
datetime(
year=created_dt.year,
month=created_dt.month,
day=created_dt.day,
hour=0,
minute=0
)
Use the Hubspot supported "sanetime" module: https://github.com/HubSpot/sanetime
Then to get a date:
yourdate = datetime.datetime.date()
hubspot_date = sanetime.time(yourdate )
Or if you do not want a dependency:
#convert datetime to UTC
your_utc_datetime = your_datetime.astimezone(pytz.UTC)
#replace time with midnight
your_utc_date_midnight = your_utc_datetime.replace(hour=0,minute=0,second=0, microsecond=0)
# convert to epoch (Python 3.3+)
your_hubspot_date = your_utc_date_midnight.timestamp()*1000
from django.utils import timezone
time_zone = timezone.get_current_timezone_name() # Gives 'Asia/Kolkata'
date_time = datetime.time(12,30,tzinfo=pytz.timezone(str(time_zone)))
Now I need to convert this time to UTC format and save it in Django model. I am not able to use date_time.astimezone(pytz.timezone('UTC')). How can I convert the time to UTC. Also Back to 'time_zone'.
This is a use case when user type time in a text box and we need to save time time in UTC format. Each user will also select his own time zone that we provide from Django timezone module.
Once the user request back the saved time it must be shown back to him in his selected time zone.
These things are always easier using complete datetime objects, e.g.:
import datetime
import pytz
time_zone = pytz.timezone('Asia/Kolkata')
# get naive date
date = datetime.datetime.now().date()
# get naive time
time = datetime.time(12, 30)
# combite to datetime
date_time = datetime.datetime.combine(date, time)
# make time zone aware
date_time = time_zone.localize(date_time)
# convert to UTC
utc_date_time = date_time.astimezone(pytz.utc)
# get time
utc_time = utc_date_time.time()
print(date_time)
print(utc_date_time)
print(utc_time)
Yields:
2014-07-13 12:30:00+05:30
2014-07-13 07:00:00+00:00
07:00:00
right now for me.
set the timezone to UTC in your settings.py. Get the user input of time and timezone in certain format. Suppose you get the user time as 'Jul-7-2014 12:35PM:30' (consider using date input in your html).
from datetime import datetime, timedelta
// convert the time to standard format
user_date = datetime.strptime('Jul-7-2014 12:35PM:30', '%b-%d-%Y %I:%M%p:%S')
user_date_string = user_date.strftime('%Y-%m-%d %H:%M:%S')
// save the time to model with users timezone
// now when user asks back for his time, add the timezone with timedelta
user_date = datetime.strptime(user_date_string, '%Y-%m-%d %H:%M:%S')
user_date = user_date + timedelta(hours = 5, minutes = 30)
// finally display it
print user_data.strftime('%Y-%m-%d %H:%M:%S')
*this is not considering django inbuild datetime functions which returns datetime object for datetime model field. If implemented that it will be more simple
There are a ton of questions about UTC datetime conversions and there doesn't seems to be a consensus of a "best way".
According to this: http://lucumr.pocoo.org/2011/7/15/eppur-si-muove/ , pytz is the best way to go. he shows converting to timezone like this datetime.datetime.utcnow().replace(tzinfo=pytz.utc) but he doesn't say how to get the user's timezone...
This guy https://stackoverflow.com/a/7465359/523051 says "localize adjusts for Daylight Savings Time, replace does not"
Everyone I see using pytz is supplying their own timezone (users_timezone = timezone("US/Pacific")), which I don't understand because you can't know if that's where your viewer is...
This guy https://stackoverflow.com/a/4771733/523051 has a way to auto-detect the timezones, but this is using the dateutil library, and not pytz, as is recommended by both Armin Ronacher and the official python docs ( http://docs.python.org/library/datetime.html#strftime-and-strptime-behavior , just above that anchor in yellow box)
All I need is the most simplest, future-proof, all daylight savings time/etc considered way to take my datetime.utcnow() stamp (2012-08-25 10:59:56.511479), convert it the user's timezone. And show it like this:
Aug 25 - 10:59AM
and if the year is not the current year, I'd like to say
Aug 25 '11 - 10:59AM
alright, here it is (also, my first contribution to SO :))
it does require 2 external libraries which may throw some off...
from datetime import datetime
from dateutil import tz
import pytz
def standard_date(dt):
"""Takes a naive datetime stamp, tests if time ago is > than 1 year,
determines user's local timezone, outputs stamp formatted and at local time."""
# determine difference between now and stamp
now = datetime.utcnow()
diff = now - dt
# show year in formatting if date is not this year
if (diff.days / 365) >= 1:
fmt = "%b %d '%y # %I:%M%p"
else:
fmt = '%b %d # %I:%M%p'
# get users local timezone from the dateutils library
# http://stackoverflow.com/a/4771733/523051
users_tz = tz.tzlocal()
# give the naive stamp timezone info
utc_dt = dt.replace(tzinfo=pytz.utc)
# convert from utc to local time
loc_dt = utc_dt.astimezone(users_tz)
# apply formatting
f = loc_dt.strftime(fmt)
return f
# parses some string into that format.
datetime1 = datetime.strptime(somestring, "%Y-%m-%dT%H:%M:%S")
# gets the seconds from the above date.
timestamp1 = time.mktime(datetime1.timetuple())
# adds milliseconds to the above seconds.
timeInMillis = int(timestamp1) * 1000
How do I (at any point in that code) turn the date into UTC format? I've been ploughing through the API for what seems like a century and cannot find anything that I can get working. Can anyone help? It's currently turning it into Eastern time i believe (however I'm in GMT but want UTC).
EDIT: I gave the answer to the guy with the closest to what I finally found out.
datetime1 = datetime.strptime(somestring, someformat)
timeInSeconds = calendar.timegm(datetime1.utctimetuple())
timeInMillis = timeInSeconds * 1000
:)
datetime.utcfromtimestamp is probably what you're looking for:
>>> timestamp1 = time.mktime(datetime.now().timetuple())
>>> timestamp1
1256049553.0
>>> datetime.utcfromtimestamp(timestamp1)
datetime.datetime(2009, 10, 20, 14, 39, 13)
I think you can use the utcoffset() method:
utc_time = datetime1 - datetime1.utcoffset()
The docs give an example of this using the astimezone() method here.
Additionally, if you're going to be dealing with timezones, you might want to look into the PyTZ library which has lots of helpful tools for converting datetime's into various timezones (including between EST and UTC)
With PyTZ:
from datetime import datetime
import pytz
utc = pytz.utc
eastern = pytz.timezone('US/Eastern')
# Using datetime1 from the question
datetime1 = datetime.strptime(somestring, "%Y-%m-%dT%H:%M:%S")
# First, tell Python what timezone that string was in (you said Eastern)
eastern_time = eastern.localize(datetime1)
# Then convert it from Eastern to UTC
utc_time = eastern_time.astimezone(utc)
def getDateAndTime(seconds=None):
"""
Converts seconds since the Epoch to a time tuple expressing UTC.
When 'seconds' is not passed in, convert the current time instead.
:Parameters:
- `seconds`: time in seconds from the epoch.
:Return:
Time in UTC format.
"""
return time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime(seconds))`
This converts local time to UTC
time.mktime(time.localtime(calendar.timegm(utc_time)))
http://feihonghsu.blogspot.com/2008/02/converting-from-local-time-to-utc.html
If converting a struct_time to seconds-since-the-epoch is done using mktime, this
conversion is in local timezone. There's no way to tell it to use any specific timezone, not even just UTC. The standard 'time' package always assumes that a time is in your local timezone.
You probably want one of these two:
import time
import datetime
from email.Utils import formatdate
rightnow = time.time()
utc = datetime.datetime.utcfromtimestamp(rightnow)
print utc
print formatdate(rightnow)
The two outputs look like this
2009-10-20 14:46:52.725000
Tue, 20 Oct 2009 14:46:52 -0000