What is the proper way to convert a timedelta object into a datetime object?
I immediately think of something like datetime(0)+deltaObj, but that's not very nice... Isn't there a toDateTime() function or something of the sort?
It doesn't make sense to convert a timedelta into a datetime, but it does make sense to pick an initial or starting datetime and add or subtract a timedelta from that.
>>> import datetime
>>> today = datetime.datetime.today()
>>> today
datetime.datetime(2010, 3, 9, 18, 25, 19, 474362)
>>> today + datetime.timedelta(days=1)
datetime.datetime(2010, 3, 10, 18, 25, 19, 474362)
Since a datetime represents a time within a single day, your timedelta should be less than 24 hours (86400 seconds), even though timedeltas are not subject to this constraint.
import datetime
seconds = 86399
td = datetime.timedelta(seconds=seconds)
print(td)
dt = datetime.datetime.strptime(str(td), "%H:%M:%S")
print(dt)
23:59:59
1900-01-01 23:59:59
If you don't want a default date and know the date of your timedelta:
date = "05/15/2020"
dt2 = datetime.datetime.strptime("{} {}".format(date, td), "%m/%d/%Y %H:%M:%S")
print(dt2)
2020-05-15 23:59:59
I found that I could take the .total_seconds() and use that to create a new time object (or datetime object if needed).
import time
import datetime
start_dt_obj = datetime.datetime.fromtimestamp(start_timestamp)
stop_dt_obj = datetime.datetime.fromtimestamp(stop_timestamp)
delta = stop_dt_obj - start_dt_obj
delta_as_time_obj = time.gmtime(delta.total_seconds())
This allows you to do something like:
print('The duration was {0}'.format(
time.strftime('%H:%M', delta_as_time_obj)
)
Improving #sadpanduar answer with example on converting one column in pandas.DataFrame:
from datetime import timedelta
import time
def seconds_to_datetime(seconds, format='%Y-%m-%d %H:%M:%S'):
td = timedelta(seconds=seconds)
time_obj = time.gmtime(td.total_seconds())
return time.strftime(format, time_obj)
df = pd.read_csv(CSV_PATH)
df['TIMESTAMP_COLUMN'] = df['TIMESTAMP_COLUMN'].apply(seconds_to_datetime)
import datetime`enter code here
lastDownloadedDate = datetime.date(2022,8,4)
print('lastDownloadedDate: ', lastDownloadedDate)
fdate = lastDownloadedDate + datetime.timedelta(days=1)
fdate = datetime.datetime.strptime(str(fdate), "%Y-%m-%d")
fdate = datetime.date(fdate.year, fdate.month, fdate.day)
print('fdate: ', dt3)`
Related
I have a day/month string, I want to convert that string to date object and compare the last day of that month to another date
Example:
For 08/2021 (august, 2021) I want to compare the last day of that month (31-08-2021) to another date (date field),
For 02/2020 I what to compare 29-02-2020 < another_date (date field)
For 02/2021 I what to compare 28-02-2020 < another_date (date field)
You can use calendar.monthrange to find the last day in the month if you don't want to add dateutil.
import calendar
from datetime import datetime
def get_last_day_date(year_month_str):
date = datetime.strptime(year_month_str, "%m/%Y")
last_day = calendar.monthrange(date.year, date.month)[1]
return datetime(date.year, date.month, last_day)
get_last_day_date("08/2020")
# datetime.datetime(2020, 8, 31, 0, 0)
This examples shows you how to convert '02/2020' to a Python datetime and how to get the last day of that month. You can use it to compare the result to another datetime:
import datetime
from dateutil.relativedelta import relativedelta
date = '02/2020'
last_day = datetime.datetime.strptime(date, '%m/%Y') + relativedelta(day=31)
# last_day will be a datetime of the last day of the month which you can use to compare against another datetime
In this example, the result is datetime.datetime(2020, 2, 29, 0, 0) because 2020 was a leap year
b='08/2021'
a=b.split('/')
import calendar
import datetime
z=(str(calendar.monthrange(int(a[1]),int(a[0]))[1])+'-'+b.replace('/','-'))
d=datetime.datetime.strptime(z,'%d-%m-%Y').date()
print(d)
n=datetime.date.today()
print(n)
n<d
Output:
2021-08-31
2021-01-28
True
It can be done by just importing/using datetime library and here you can see how.
By passing string date into method.
import datetime
def convert_string_to_datetime(self, datetime_in_string):
datetime_in_string = str(datetime_in_string)
datetime_format = "%Y-%m-%d %H:%M:%S"
datetime_in_datetime_format = datetime.datetime.strptime(datetime_in_string, datetime_format)
return datetime_in_datetime_format
new_datetime_field = convert_string_to_datetime(datetime_in_string)
By modifying with in single line
import datetime
new_datetime_field = datetime.datetime.strptime(YOUR_DATETIME_IN_STRING, "%Y-%m-%d %H:%M:%S")
After converting into datetime now comparison is possible like.
if new_datetime_field > odoo_datetime_field:
pass
from datetime import datetime, timedelta
api_time = datetime.strptime(parsed_json["result"]["parameters"]["time"], "%H:%M:%S")
What I'm getting in api_time after debugging is 900-01-01 12:30:22. What I want is 12:30:22 only. I have checked other docs and .strptime should have done it but it didn't work.
Method 1: Strip space
One quick solution, if your input doesn't change.
from datetime import datetime, timedelta
api_time = datetime.strptime("1900-01-01 12:30:22".split(" ")[1], "%H:%M:%S")
print api_time
>1900-01-01 12:30:22
In your case:
api_time = datetime.strptime(parsed_json["result"]["parameters"]["time"], "%H:%M:%S")
Method 2: Construct datetime
Or you can just construct your datetime object and then access it's second, minute, hour attributes as follows:
from datetime import datetime, timedelta
api_time = datetime.strptime("1900-01-01 12:30:22", "%Y-%m-%d %H:%M:%S")
print "{0}:{1}:{2}".format(api_time.second, api_time.minute, api_time.hour)
>22:30:12
You can convert them from datetime to string, then just use string split:
a = '1900-01-01 12:30:22'
a.split(' ')[1]
-->
from datetime import datetime
api_time = datetime(1900, 01, 01, 12, 30, 22).strftime("%Y-%m-%d %H:%M:%S")
api_time.split(' ')[1]
I am parsing a 3rd party website HTML with dates and times which are always in UK time format, however they don't have any timezone info in the source. Converting the string to an object is easy enough using datetime.strptime(), but how do I add timezone info?
Ultimately, I need to convert these strings to a datetime object in UTC format. The code will always run on a PC which is timezone aware, i.e. datetime.now() will return UK time.
temp = '07/12/2017 13:30'
dt = datetime.strptime(temp, '%d/%m/%Y %H:%M')
Is there a nicer way to do this?
offset = datetime.now() - datetime.utcnow()
dt -= offset
Use pytz
import datetime
import pytz
temp = '07/12/2017 13:30'
dt = datetime.strptime(temp, '%d/%m/%Y %H:%M')
timezone = pytz.timezone("Etc/Greenwich")
d_aware = timezone.localize(dt)
d_aware.tzinfo
> <DstTzInfo 'Etc/Greenwich' PST-1 day, 16:00:00 STD>
d_aware
datetime.datetime(2017, 12, 7, 13, 30, tzinfo=<StaticTzInfo 'Etc/Greenwich'>)
There are some good libraries that make working with dates so much easier. I like dateparser, parsedatetime, and arrow;
import dateparser as dp
dt = dp.parse('07-12-2017 13:30 PST')
print (dt)
dt = dp.parse("Yesterday at 3:00am EST")
print(dt)
2017-07-12 13:30:00-08:00
2017-12-06 17:07:07.557109-05:00
When subtracting two datetime objects, I understand the result is timedelta object:
import datetime
AcDepart = 1900-01-01 18:00:00
AcArrival = 1900-01-01 07:00:00
ActualHours = AcDepart - AcArrival
I want to then subtract the sum of two other date time objects from ActualHours
These are the two other objects:
HrsEarly = 1900-01-01 02:00:00
HrsLate = 1900-01-01 00:30:00
This is the equation that fails to complete:
UnCalcTime = ActualHours - (HrsEarly + HrsLate)
This is the error:
UnCalcTime = ActualHours - (HrsEarly + HrsLate)
TypeError: unsupported operand type(s) for +: 'datetime.datetime' and 'datetime.datetime'
So, I obviously can't add datetime.datetime. Does anyone know how I could get around this? Can timedelta be added together? If so, how can I convert datetime to timedelta?
Any help would be greatly appreciated as I have been trying to solve this unsuccessfully for a long time.
The best solution is to create your variables as timedelta in the first place.
HrsEarly = datetime.timedelta(hours=2)
HrsLate = datetime.timedelta(minutes=30)
If you can't do that, you can simply subtract your "zero date" from the datetime objects.
>>> HrsEarly
datetime.datetime(1900, 1, 1, 2, 0)
>>> HrsEarly = HrsEarly - datetime.datetime(1900, 1, 1)
>>> HrsEarly
datetime.timedelta(0, 7200)
Convert the string to timedelta
from datetime import datetime
AcDepart = '1900-01-01 18:00:00'
AcDepart_ = datetime.strptime(AcDepart, '%Y-%m-%d %H:%M:%S')
AcArrival = '1900-01-01 07:00:00'
AcArrival_ = datetime.strptime(AcArrival, '%Y-%m-%d %H:%M:%S')
ActualHours = (AcDepart_ - AcArrival_).total_seconds()/3600
print ActualHours
It makes no sense to add two datetime objects: It might seem, in your example, that "2AM on the 1st of January 1900" plus "half past midnight on the 1st of January 1900" should be "half past two on the 1st of January 1900", but in another context the desired result could as easily be "half past two on the 2nd of February 3800", or even (if the UNIX epoch is used as an origin) "half past two on the first of January 1830".
Looking at a different example might make this more obvious: what should be the result of Tuesday + Saturday?
Your HrsEarly and HrsLate variables are presumably meant to store a time difference, and there's an appropriate type for that: datetime.timedelta. Adding two of those together does what you want:
>>> from datetime import timedelta
>>> HrsEarly = timedelta(hours=2)
>>> HrsLate = timedelta(minutes=30)
>>> HrsTotal = (HrsEarly + HrsLate)
>>> str(HrsTotal)
'2:30:00'
How about this method using built-in timestamp function?
import datetime
a = "2017-01-01 14:30:00"
b = datetime.datetime.strptime(a, '%Y-%m-%d %H:%M:%S')
c = b.timestamp()
d = datetime.timedelta(seconds=c)
Runtime environment
OS: Ubuntu 16.04
Python 3.6
Create a modules.py and paste the following two functions. Import them wherever you want and use as is.
import datetime
def JsTimestampToPyDatetime(js_date):
"""
converts javascript timestamp to python datetime taking care of
milliseconds and seconds
Args:
js_date(Timestamp, required)
Returns:
Datetime
"""
try:
# handles seconds
date = datetime.datetime.fromtimestamp(int(js_date))
except (ValueError):
# handles miliseconds
date = datetime.datetime.fromtimestamp(int(js_date) / 1000)
return date
# consuming javascript generated timestamps
a = JsTimestampToPyDatetime(1627303810000) # with miliseconds
b = JsTimestampToPyDatetime(1627476610) # with seconds only
def GetDaysInDateTime(min_stamp, max_stamp):
"""
Calculates time difference between two timestamps in days
Args:
min_stamp(Datetime, required): Minimum/start datetime
max_stamp(Datetime, required): Maximum/end datetime
Returns:
Int: Days
"""
days = (max_stamp-min_stamp).days
return int(days)
print(GetDaysInDateTime(a, b))
Is there a built-in method for converting a date to a datetime in Python, for example getting the datetime for the midnight of the given date? The opposite conversion is easy: datetime has a .date() method.
Do I really have to manually call datetime(d.year, d.month, d.day)?
You can use datetime.combine(date, time); for the time, you create a datetime.time object initialized to midnight.
from datetime import date
from datetime import datetime
dt = datetime.combine(date.today(), datetime.min.time())
There are several ways, although I do believe the one you mention (and dislike) is the most readable one.
>>> import datetime
>>> t=datetime.date.today()
>>> datetime.datetime.fromordinal(t.toordinal())
datetime.datetime(2009, 12, 20, 0, 0)
>>> datetime.datetime(t.year, t.month, t.day)
datetime.datetime(2009, 12, 20, 0, 0)
>>> datetime.datetime(*t.timetuple()[:-4])
datetime.datetime(2009, 12, 20, 0, 0)
and so forth -- but basically they all hinge on appropriately extracting info from the date object and ploughing it back into the suitable ctor or classfunction for datetime.
The accepted answer is correct, but I would prefer to avoid using datetime.min.time() because it's not obvious to me exactly what it does. If it's obvious to you, then more power to you. I also feel the same way about the timetuple method and the reliance on the ordering.
In my opinion, the most readable, explicit way of doing this without relying on the reader to be very familiar with the datetime module API is:
from datetime import date, datetime
today = date.today()
today_with_time = datetime(
year=today.year,
month=today.month,
day=today.day,
)
That's my take on "explicit is better than implicit."
You can use the date.timetuple() method and unpack operator *.
args = d.timetuple()[:6]
datetime.datetime(*args)
Today being 2016, I think the cleanest solution is provided by pandas Timestamp:
from datetime import date
import pandas as pd
d = date.today()
pd.Timestamp(d)
Timestamp is the pandas equivalent of datetime and is interchangable with it in most cases. Check:
from datetime import datetime
isinstance(pd.Timestamp(d), datetime)
But in case you really want a vanilla datetime, you can still do:
pd.Timestamp(d).to_datetime()
Timestamps are a lot more powerful than datetimes, amongst others when dealing with timezones. Actually, Timestamps are so powerful that it's a pity they are so poorly documented...
you can also use
date = datetime.utcnow().date()
dt = datetime.fromisoformat(date.isoformat())
print(dt)
datetime.datetime(2021, 11, 15, 0, 0)
One way to convert from date to datetime that hasn't been mentioned yet:
from datetime import date, datetime
d = date.today()
datetime.strptime(d.strftime('%Y%m%d'), '%Y%m%d')
You can use easy_date to make it easy:
import date_converter
my_datetime = date_converter.date_to_datetime(my_date)
Do I really have to manually call datetime(d.year, d.month, d.day)
No, you'd rather like to call
date_to_datetime(dt)
which you can implement once in some utils/time.py in your project:
from typing import Optional
from datetime import date, datetime
def date_to_datetime(
dt: date,
hour: Optional[int] = 0,
minute: Optional[int] = 0,
second: Optional[int] = 0) -> datetime:
return datetime(dt.year, dt.month, dt.day, hour, minute, second)
To make dt timezone aware datetime (with Django timezone util):
from django.utils import timezone
timezone.now().replace(*(*dt.timetuple()[:6], 0))
An alternative to toisoformat/fromisoformat: you can use date.toordinal and datetime.fromordinal:
import datetime
start_date = datetime.date(1991, 2, 20)
start_date_midnight = datetime.datetime.fromordinal(start_date.toordinal())
I suspect this is more efficient than converting to/from a string.
You can test this process as so:
def test_datetime_from_date():
for x in range(1,1000000):
date_ = datetime.date.fromordinal(x)
datetime_ = datetime.datetime.fromordinal(date_.toordinal())
datetime_iso_date, t, datetime_iso_time = datetime_.isoformat().partition("T")
assert datetime_iso_date == date_.isoformat()
You can use this class:
import time
import datetime
class TimingClass():
def __init__(self):
self.YEAR = datetime.date.today().year
self.MONTH = datetime.date.today().month
self.DATE = datetime.date.today().day
self.HOUR = datetime.datetime.now().hour
self.MINUTE = datetime.datetime.now().minute
self.SECONDS = datetime.datetime.now().second
self.TODAY = datetime.date.today()
self.YESTERDAY = datetime.datetime.strftime( (self.TODAY - datetime.timedelta(days = 1)) , '%Y-%m-%d')
self.TOMORROW = datetime.datetime.strftime( (self.TODAY + datetime.timedelta(days = 1)) , '%Y-%m-%d')
self.TODAY_datetime = datetime.datetime.combine(datetime.date.today(), datetime.datetime.min.time())
If you need something quick, datetime_object.date() gives you a date of a datetime object.
I am a newbie to Python. But this code worked for me which converts the specified input I provide to datetime. Here's the code. Correct me if I'm wrong.
import sys
from datetime import datetime
from time import mktime, strptime
user_date = '02/15/1989'
if user_date is not None:
user_date = datetime.strptime(user_date,"%m/%d/%Y")
else:
user_date = datetime.now()
print user_date