I have an unusual datetime format in my dataset, which I need to convert to usable datetime object.
An example looks like: '1/3/2018 1:29:35 PM(UTC+0)'
I have tried to parse it with:
from dateutil.parser import parse
parse('1/3/2018 1:29:35 PM(UTC+0)')
but it doesn't recognize the format.
My current workaround is to parse the datetime column (the data is in pandas dataframe) using regex into two columns, like so:
and then depending on the value of the 'utc' column apply custom convert_to_eastern function.
I wonder if there is an easier way to accomplish it using datetime.datetime.strptime() ?
Following didn't work:
import datetime as dt
my_time='1/3/2018 1:29:35 PM(UTC+0)'
dt.datetime.strptime(my_time, '%m/%d/%Y %I:%M:%S %p(%z)')
Addition:
This is not a question: "How to convert UTC timezone into local timezone" My dataset has rows with UTC as well as Eastern time zone rows. The problem I have is that the format is not an ISO format, but some human-readable custom format.
Question: an easier way to accomplish it using datetime.datetime.strptime()
Split the datestring into parts: utc:[('1/3/2018 1:29:35 PM', '(UTC+0)', 'UTC', '+', '0')]
Rebuild the datestring, fixing the hour part padding with 0 to 2 digits.
I assume, there are no minutes in the UTC part, therefore defaults to 00.
If the datestring has more then 2 UTC digits, returns the unchanged datestring.
Note: The strptime format have to be %Z%z!
Documentation: strftime-and-strptime-behavior
from datetime import datetime
import re
def fix_UTC(s):
utc = re.findall(r'(.+?)(\((\w{3})(\+|\-)(\d{1,2})\))', s)
if utc:
utc = utc[0]
return '{}({}{}{})'.format(utc[0], utc[2], utc[3], '{:02}00'.format(int(utc[4])))
else:
return s
my_time = fix_UTC('1/3/2018 1:29:35 PM(UTC+0)')
date = datetime.strptime(my_time, '%m/%d/%Y %I:%M:%S %p(%Z%z)')
print("{} {}".format(date, date.tzinfo))
Output:
2018-01-03 13:29:35+01:00 UTC
Tested with Python: 3.4.2
The problem is with '+0' for your timezone 'UTC+0'. datetime only takes utc offset in the form of HHMM. Possible workaround:
import datetime as dt
my_time = '1/3/2018 1:29:35 PM(UTC+0)'
my_time=my_time.replace('+0','+0000')
dt.datetime.strptime(my_time, '%m/%d/%Y %I:%M:%S %p(%Z%z)')
It should be something like that:
import datetime as dt
my_time='1/3/2018 1:29:35 PM(UTC+0000)'
tmp = dt.datetime.strptime(my_time, '%m/%d/%Y %I:%M:%S %p(%Z%z)')
print(tmp)
Big "Z" for timezone (UTC, GMT etc), small "z" for delta. Also you should add more zeros to delta.
Related
The following code converts a string into a timestamp. The timestamp comes out to: 1646810127.
However, if I use Excel to convert this date and time into a float I get: 44629,34.
I need the Excel's output from the Python script.
I have tried with a few different datetime strings to see if there is any pattern in between the two numbers, but cannot seem to find any.
Any thoughts on how I get the code to output 44629,34?
Much appreciated
import datetime
date_time_str = '2022-03-09 08:15:27'
date_time_obj = datetime.datetime.strptime(date_time_str, '%Y-%m-%d %H:%M:%S')
print('Date:', date_time_obj.date())
print('Time:', date_time_obj.time())
print('Date-time:', date_time_obj)
print(date_time_obj.timestamp())
>>output:
Date: 2022-03-09
Time: 08:15:27
Date-time: 2022-03-09 08:15:27
1646810127.0
calculate the timedelta of your datetime object versus Excel's "day zero", then divide the total_seconds of the timedelta by the seconds in a day to get Excel serial date:
import datetime
date_time_str = '2022-03-09 08:15:27'
UTC = datetime.timezone.utc
dt_obj = datetime.datetime.fromisoformat(date_time_str).replace(tzinfo=UTC)
day_zero = datetime.datetime(1899,12,30, tzinfo=UTC)
excel_serial_date = (dt_obj-day_zero).total_seconds()/86400
print(excel_serial_date)
# 44629.3440625
Note: I'm setting time zone to UTC here to avoid any ambiguities - adjust as needed.
Since the question is tagged pandas, you'd do the same thing here, only that you don't need to set UTC as pandas assumes UTC by default for naive datetime:
import pandas as pd
ts = pd.Timestamp('2022-03-09 08:15:27')
excel_serial_date = (ts-pd.Timestamp('1899-12-30')).total_seconds()/86400
print(excel_serial_date)
# 44629.3440625
See also:
background: What is story behind December 30, 1899 as base date?
inverse operation: Convert Excel style date with pandas
I have 2 variables.
One is datetime in string format and the other is datetime in datetime.datetime format.
For example -
2021-09-06T07:58:19.032Z # string
2021-09-05 14:58:10.209675 # datetime.datetime
I want to find out the difference between these 2 times in seconds.
I think we need to have both in datetime before we can do this subtraction.
I'm having a hard time converting the string to datetime.
Can someone please help.
You can convert the string into datetime object with strptime()
An example with your given dates:
from datetime import datetime
# Assuming this is already a datetime object in your code, you don't need this part
# I needed this part to be able to use it as a datetime object
date1 = datetime.strptime("2021-09-05 14:58:10.209675", "%Y-%m-%d %H:%M:%S.%f")
## The part where the string is converted to datetime object
# Since the string has "T" and "Z", we will have to remove them before we convert
formatted = "2021-09-06T07:58:19.032Z".replace("T", " ").replace("Z", "")
>>> 2021-09-06 07:58:19.032
# Finally, converting the string
date2 = datetime.strptime(formatted, "%Y-%m-%d %H:%M:%S.%f")
# Now date2 variable is a datetime object
# Performing a simple operation
print(date1 - date2)
>>> -1 day, 6:59:51.177675
Convert the str to datetime via strptime() and then get the difference of the 2 datetime objects in seconds via total_seconds().
from datetime import datetime, timezone
# Input
dt1_str = "2021-09-06T07:58:19.032Z" # String type
dt2 = datetime(year=2021, month=9, day=5, hour=14, minute=58, second=10, microsecond=209675, tzinfo=timezone.utc) # datetime type
# Convert the string to datetime
dt1 = datetime.strptime(dt1_str, "%Y-%m-%dT%H:%M:%S.%f%z")
# Subtract the datetime objects and get the seconds
diff_seconds = (dt1 - dt2).total_seconds()
print(diff_seconds)
Output
61208.822325
The first string time you mention could be rfc3339 format.
A module called python-dateutil could help
import dateutil.parser
dateutil.parser.parse('2021-09-06T07:58:19.032Z')
datetime module could parse this time format by
datetime.datetime.strptime("2021-09-06T07:58:19.032Z","%Y-%m-%dT%H:%M:%S.%fZ")
But this way may cause trouble when get a time in another timezone because it doesn't support timezone offset.
How can i get datetime in ISO 8601 date format (YYYY-MM-DDThh:mmTZD). Example 2019-02-26T09:30:46+03:00
I tried using
from datetime import datetime
d = datetime.now()
d.isoformat()
But the output is now correct
'2020-07-29T15:47:46.974744'
d = datetime.now()
d.strftime("%Y-%m-%dT%H:%M:%S%z")
Do note that %z will return empty if its a naive datetime object
This should give you the format you're looking for.
https://strftime.org/
This is a good reference on the available formats
I have a CSV file with recorded datetimes with a particular format:
%Y-%m-%d %H:%M:%s %Z
Example:
2017-02-11 14:11:42 PST
I am trying to format the datetime to a friendlier value to use later on.
However, I have been unable to create a datetime object with my code so far.
Here is my code:
for r in row:
purchase_date.append(
datetime.strptime(row['purchase-date'], "%Y/%m/%d %H:%M:%S %Z")
)
This is the error received:
ValueError: time data '2017-02-11 14:11:42 PST' does not match format %Y/%m/%d %H:%M:%S %Z'
Timezones are often rather wonky when trying to convert from a string. It is often best to deal with the timezone string yourself. Here is a bit of code which separates the timezone from the timestamp, and then converts them separately.
Code:
import datetime as dt
import pytz
my_timezones = dict(
PST='US/Pacific',
)
def convert_my_datetime_str(dt_str):
# split into time and timezone
timestamp, tz_str = dt_str.rsplit(' ', 1)
# convert the date string to datetime
time = dt.datetime.strptime(timestamp, "%Y-%m-%d %H:%M:%S")
# get a timezone name
tz = pytz.timezone(my_timezones[tz_str])
# return a timezone aware datetime
return tz.localize(time)
Test Code:
print(convert_my_datetime_str('2017-02-11 14:11:42 PST'))
Results;
2017-02-11 14:11:42-08:00
You should be able to just change the format to match your date strings. In the error, your date string has dashes instead of slashes, so make the format string match:
for r in row:
purchase_date.append(
datetime.strptime(row['purchase-date'], "%Y-%m-%d %H:%M:%S %Z")
)
I'm given a timestamp (time since the epoch) and I need to convert it into this format:
yyyy/mm/dd hh:mm
I looked around and it seems like everyone else is doing this the other way around (date to timestamp).
If your answer involves dateutil that would be great.
Using datetime instead of dateutil:
import datetime as dt
dt.datetime.utcfromtimestamp(seconds_since_epoch).strftime("%Y/%m/%d %H:%M")
An example:
import time
import datetime as dt
epoch_now = time.time()
sys.stdout.write(str(epoch_now))
>>> 1470841955.88
frmt_date = dt.datetime.utcfromtimestamp(epoch_now).strftime("%Y/%m/%d %H:%M")
sys.stdout.write(frmt_date)
>>> 2016/08/10 15:09
EDIT: strftime() used, as the comments suggested.