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
Related
I'm new to python and I'm trying to get the actual minutes passed every day since 7:00.
I am using mktime to get now_date1 and now_date2 in seconds, and then the plan it's to subtract and divide by 60 to get the minutes.
But I get the following error:
AttributeError: 'str' object has no attribute 'timetuple'
It's this the correct approach?
Here it's the code
import time
import pytz
from datetime import datetime
from time import mktime as mktime
now_date = datetime.now(pytz.timezone('Europe/Bucharest'))
now_date1 = now_date.strftime('%H:%M:%S')
now_date2 = now_date.strftime('7:00:00')
# Convert to Unix timestamp
d1_ts = time.mktime(now_date1.timetuple())
strftime returns a string. Not what you want.
You were pretty close, but there's no need to put time in the mix. Just modify your code like this and use time delta from datetime (inspired by How to calculate the time interval between two time strings):
import pytz
from datetime import datetime
now_date = datetime.now(pytz.timezone('Europe/Bucharest'))
from datetime import datetime
FMT = '%H:%M:%S'
now_date1 = now_date.strftime(FMT)
now_date2 = now_date.strftime('7:00:00')
tdelta = datetime.strptime(now_date1, FMT) - datetime.strptime(now_date2, FMT)
print(tdelta)
I get: 6:40:42 which seems to match since it's 12:42 here.
To get the result in minutes just do:
tdelta.seconds//60
(note that the dates have only correct hour/time/seconds, the year, month, etc.. are 1900 ... since they're not used)
I think something like this might work:
import time
import datetime
from time import mktime as mktime
#current time
now_date = datetime.datetime.now()
#time at 7am
today = datetime.date.today()
now_date2 = datetime.datetime(today.year, today.month, today.day, 7, 0, 0, 0)
#difference in minutes
(now_date - now_date2).days * 24 * 60
I'm trying to serialize datetime in an API, but I don't want milliseconds. What I want is here: https://en.wikipedia.org/wiki/ISO_8601 - "2015-09-14T17:51:31+00:00"
tz = pytz.timezone('Asia/Taipei')
dt = datetime.datetime.now()
loc_dt = tz.localize(dt)
Try A:
loc_dt.isoformat()
>> '2015-09-17T10:46:15.767000+08:00'
Try B:
loc_dt.strftime("%Y-%m-%dT%H:%M:%S%z")
>> '2015-09-17T10:46:15+0800'
The latter one is almost perfect except it's missing the colon in the timezone part. How can I solve this without string manipulation (deleting milliseconds or adding colon)?
You can replace the microseconds with 0 and use isoformat:
import pytz
from datetime import datetime
tz = pytz.timezone('Asia/Taipei')
dt = datetime.now()
loc_dt = tz.localize(dt).replace(microsecond=0)
print loc_dt.isoformat()
2015-09-17T19:12:33+08:00
If you want to keep loc_dt as is do the replacing when you output:
loc_dt = tz.localize(dt)
print loc_dt.replace(microsecond=0).isoformat()
As commented you would be better passing the tz to datetime.now:
dt = datetime.now(tz)
The reasons are discussed in pep-0495, you might also want to add an assert to catch any bugs when doing the replace:
ssert loc_dt.resolution >= timedelta(microsecond=0)
Since python 3.6, datetime.isoformat accepts a timespec keyword to pick a precision. This argument gives the smallest time unit you want to be included in the output:
>>> loc_dt.isoformat()
'2022-10-21T19:59:59.991999+08:00'
>>> loc_dt.isoformat(timespec='seconds')
'2022-10-21T19:59:59+08:00'
>>> loc_dt.isoformat(timespec='milliseconds')
'2022-10-21T19:59:59.991+08:00'
Notice how the time is truncated and not rounded.
You can also use timespec to remove seconds/minutes:
>>> loc_dt.isoformat(timespec='minutes')
'2022-10-21T19:59+08:00'
>>> loc_dt.isoformat(timespec='hours')
'2022-10-21T19+08:00'
This all assume you ran the following setup script beforehand:
from datetime import datetime
import pytz
tz = pytz.timezone('Asia/Taipei')
dt = datetime.now()
loc_dt = tz.localize(dt)
Also note that this works without timezone:
>>> from datetime import datetime
>>> now = datetime.now()
>>> now.isoformat(timespec='minutes')
>>> '2022-10-21T19:59'
I'm trying to make a object with the same year and month as the current date but change the day around to a different date in the month.
from datetime import timedelta, date, datetime
whole = date.today()
wholestr= str(whole)
vali = wholestr.split('-')
year=int(vali[0])
month=int(vali[1])
day=int(vali[2])
sub = datetime.date(year,month,16)
print sub
Here it says that ints work when constructing but I get an error saying that it needs a datetime.date obj and not ints.
http://docs.python.org/library/datetime.html#date-objects
I believe your problem is that you call datetime.date when you just want to call date in your second to last line. Changing to just using date gave me this result:
>>> from datetime import timedelta, date, datetime
>>> whole = date.today()
>>> wholestr = str(whole)
>>> vali = wholestr.split('-')
>>> year = int(vali[0])
>>> month = int(vali[1])
>>> day = int(vali[2])
>>> sub = date(year, month, 16)
>>> sub
datetime.date(2012, 4, 16)
>>> print sub
2012-04-16
Alternatively you could just call datetime like this:
>>> datetime(year, month, 16)
datetime.datetime(2012, 4, 16, 0, 0)
Personally, this is why I always prefer to just do import datetime.
Your problem is pretty straightforward:
from datetime import [some items including] datetime
After the import finishes, datetime refers to what used to be called datetime.datetime, and datetime.date is what would otherwise be referred to as datetime.datetime.date.
You can either use date (which, since you imported it, now refers to what would otherwise be datetime.date) or just import datetime and qualify all the names, e.g., whole = datetime.date.today() and so on. I prefer the latter myself because it's easy to get lost otherwise, but it's a personal preference thing.
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)`
I'm trying to do something like this:
time() + timedelta(hours=1)
however, Python doesn't allow it, apparently for good reason.
Does anyone have a simple work around?
Related:
What is the standard way to add N seconds to datetime.time in Python?
The solution is in the link that you provided in your question:
datetime.combine(date.today(), time()) + timedelta(hours=1)
Full example:
from datetime import date, datetime, time, timedelta
dt = datetime.combine(date.today(), time(23, 55)) + timedelta(minutes=30)
print dt.time()
Output:
00:25:00
If it's worth adding another file / dependency to your project, I've just written a tiny little class that extends datetime.time with the ability to do arithmetic. If you go past midnight, it just wraps around:
>>> from nptime import nptime
>>> from datetime import timedelta
>>> afternoon = nptime(12, 24) + timedelta(days=1, minutes=36)
>>> afternoon
nptime(13, 0)
>>> str(afternoon)
'13:00:00'
It's available from PyPi as nptime ("non-pedantic time"), or on GitHub: https://github.com/tgs/nptime
The documentation is at http://tgs.github.io/nptime/
Workaround:
t = time()
t2 = time(t.hour+1, t.minute, t.second, t.microsecond)
You can also omit the microseconds, if you don't need that much precision.
This is a bit nasty, but:
from datetime import datetime, timedelta
now = datetime.now().time()
# Just use January the first, 2000
d1 = datetime(2000, 1, 1, now.hour, now.minute, now.second)
d2 = d1 + timedelta(hours=1, minutes=23)
print d2.time()
You can change time() to now() for it to work
from datetime import datetime, timedelta
datetime.now() + timedelta(hours=1)
A little bit late to the party but you can also do something along the lines of:
init_time = time(4,0)
added_time = 8
new_time = datetime.time(init_time.hour+added_time)
Note that you'll need to add in correction code to make sure init+time.hour + added+time do not go above 23,59.