Calling class method inside string format - python

Consider this:
from datetime import datetime
now = datetime.now()
now.strftime("%p") # returns 'PM'
'{0.day}'.format(now) # returns 22
'{0.strftime("%p")}'.format(now)
# gives
# AttributeError: 'datetime.datetime' object has no attribute 'strftime("%p")'
This seems to imply that I can't call a class method inside the format (I guess that's what strftime is).
What's a workaround for this (assuming I need to call the method inside the string, and keep using a format) ?

You could do this.
>>> from datetime import datetime
>>> now = datetime.now()
>>> '{0:%p}'.format(now)
'PM'
This will also work with f-strings.
>>> f"{now:%p}"
'PM'

You can use the f-string:
from datetime import datetime
now = datetime.now()
now.strftime("%p") # returns 'PM'
'{0.day}'.format(now) # returns 22
print(f'{now.strftime("%p")}')
Else:
from datetime import datetime
now = datetime.now()
now.strftime("%p") # returns 'PM'
'{0.day}'.format(now) # returns 22
print('{0:%p}'.format(now))
Documentation
strftime() and strptime() Behavior

You could use f-strings like this:
from datetime import datetime
now = datetime.now()
now.strftime("%p")
print(f'{now.day}')
print(f'{now.strftime("%p")}')

Related

How to make it work datetime datetime strptime

can you tell me why it doesn't translate the date into numbers?
import datetime
from datetime import datetime
from datetime import timedelta
from django.db import models
def end_date():
return datetime.date.today() + timedelta(days=7)
def convert_date_str(add_date):
return datetime.strftime(add_date, "%m/%m/%Y")
class add(models.Model):
add_date = models.DateField('Дата додавання', auto_now_add=True)
end_date = models.DateField('Дата здачі', default=end_date)
as I do not output from the DB string month
First of all, strftime needs to be called on a datetime object so you need to enclose your addition statement in brackets.
from datetime import datetime, timedelta
def end_date():
return (datetime.today() + timedelta(days=7)).strftime("%d %B, %Y")
strptime is under datetime.datetime so you are going too deep. In any case, your second function doesn't make sense. You can only strptime from a string, not a datetime object. You also shouldn't use the same function and variable names. If you are trying to translate a datestring like 31/01/1999 to a datetime object, you can do
def convert_to_datetime(date_str):
return datetime.strptime(date_str, '%d/%m/%Y')
Your function names should also be more descriptive because at the moment I don't think any of them describes its actual functionality.
You're probably getting an Attribute error because timedelta has no strftime method. what you want is:
def end_date():
# add date object to timedelta first then get string
return (datetime.date.today() + timedelta(days=7)).strftime("%d %B, %Y")
second, strptime method takes a string and makes a datetime object. add_date is a date object not a string
def add_date():
add_date = datetime.date.today() # <-- this should be a string for strptime to work
# whats dt in your example?, also strptime argument must be a string
data_object = datetime.datetime.strptime(add_date, "%d %B, %Y").date()
return data_object

Get current date from datetime.datetime

I'm trying to get current date so I can pass it to the DATE field in SQL. I'm using datetime.datetime, below is my code:
from datetime import datetime
dt = datetime.strptime(datetime.today().date(), "%m/%d/%Y").date()
However, i'm getting this error:
TypeError: strptime() argument 1 must be str, not datetime.datetime
How can I fix the issue above? I'm still confused about datetime and datetime.datetime, and i want to keep using from datetime import datetime not import datetime.
How can I fix the issue above? thank you
If you see closely, the result of following statement,
>>> datetime.today().date()
datetime.date(2019, 9, 30)
>>> str(datetime.today().date())
'2019-09-30'
You'll notice that the datetime returned is - seperated and you'll have to convert it explicitly to a string value. Hence, for the above statement to work, change it to :
dt = datetime.strptime(str(datetime.today().date()), "%Y-%M-%d").date()
Then change it to whatever format you desire for using strftime (in your case >>> "%d/%m/%Y")
>>> dt.strftime("%d/%m/%Y")
'30/01/2019'
Just use datetime.strftime:
from datetime import datetime
dt = datetime.today().strftime("%m/%d/%Y")
print(dt)
Prints:
'09/30/2019'
strptime takes a string and makes a datetime object. Whereas strftime does exactly the opposite, taking a datetime object and returning a string.

How to convert a timedelta to a string and back again

Dateutil's timedelta object appears to have a custom __str__ method:
In [1]: from datetime import timedelta
In [2]: td = timedelta(hours=2)
In [3]: str(td)
Out[3]: '2:00:00'
What I'd like to do is re-create a timedelta object from its string representation. As far as I can tell, however, the datetime.parser.parse method will always return a datetime.datetime object (cf. https://dateutil.readthedocs.io/en/stable/parser.html):
In [4]: import dateutil.parser
In [5]: dateutil.parser.parse(str(td))
Out[5]: datetime.datetime(2016, 11, 25, 2, 0)
The only way I see now to do this is to, in the parlance of Convert a timedelta to days, hours and minutes, 'bust out some nauseatingly simple (but verbose) mathematics' to obtain the seconds, minutes, hours, etc., and pass these back to the __init__ of a new timedelta. Or is there perhaps a simpler way?
Use datetime.strptime to convert a string to timedelta.
import datetime
td = datetime.timedelta(hours=2)
# timedelta to string
s = str(td) # 2:00:00
# string to timedelta
t = datetime.datetime.strptime(s,"%H:%M:%S")
td2 = datetime.timedelta(hours=t.hour, minutes=t.minute, seconds=t.second)
The module pytimeparse, which was inspired by How to construct a timedelta object from a simple string, seems to do the heavy lifting by returning the number of seconds. I just put a wrapper around it which returns a timedelta object with the same number of seconds:
#!/usr/bin/env python3.5
import datetime
import pytimeparse
import unittest
def reconstruct_timedelta(td_string):
seconds = pytimeparse.parse(td_string)
return datetime.timedelta(seconds=seconds)
class TestReconstruction(unittest.TestCase):
def test_reconstruct_timedelta_is_inverse_of_str(self):
td = datetime.timedelta(weeks=300, days=20, hours=3, minutes=4, milliseconds=254, microseconds=984)
td_reconstructed = reconstruct_timedelta(str(td))
self.assertTrue(td == td_reconstructed)
if __name__ == "__main__":
unittest.main()
As you can see from the test, the reconstructed timedelta object is the same as the original one, even when it is initialized with an arbitrary number if milliseconds and microseconds.
How about use pickle? You may refer to https://docs.python.org/2/library/pickle.html
Serialize the time delta object, and get back the object later.
import pickle
tdi = pickle.dumps(td)
tdo = pickle.loads(tdi) # will have the time delta object
str(tdo)

Python time and strftime

I am wanting to pass the current time as an object into a strftime reference. If I use:
d = date.fromtimestamp(time.time())
print d.strftime("%d-%b-%Y %H:%M:%S")
This will print out the time, but not include the minutes/hours etc:
04-Jul-2014 00:00:00
If I try use a different call to try and get the minutes/hours:
d = date.fromtimestamp(time.localtime())
I get:
TypeError: a float is required
Both time.time() and time.localtime() appears to actually contain seconds/minutes etc, but not display them. Thoughts? gmtime also returns "AttributeError: 'time.struct_time' object has no attribute 'strftime'".
You should use
from datetime import datetime
not
from datetime import date
eg.
import time
from datetime import datetime
d = datetime.fromtimestamp(time.time())
print d.strftime("%d-%b-%Y %H:%M:%S")
use datetime.fromtimestamp(time.time()) since date.fromtimestamp(time.time()) only draws date
d = datetime.fromtimestamp(time.time())
print d
print d.strftime("%d-%b-%Y %H:%M:%S")
#output 04-Jul-2014 11:32:40

Troubleshooting "descriptor 'date' requires a 'datetime.datetime' object but received a 'int'"

In my code I ask the user for a date in the format dd/mm/yyyy.
currentdate = raw_input("Please enter todays date in the format dd/mm/yyyy: ")
day,month,year = currentdate.split('/')
today = datetime.date(int(year),int(month),int(day))
This returns the error
TypeError: descriptor 'date' requires a 'datetime.datetime' object but received a 'int'
if I remove the int() then I end up with the same error only it says it received a 'str'
What am I doing wrong?
It seems that you have imported datetime.datetime module instead of datetime. This should work though:
import datetime
currentdate = raw_input("Please enter todays date in the format dd/mm/yyyy: ")
day,month,year = currentdate.split('/')
today = datetime.date(int(year),int(month),int(day))
..or this:
from datetime import date
currentdate = raw_input("Please enter todays date in the format dd/mm/yyyy: ")
day,month,year = currentdate.split('/')
today = date(int(year),int(month),int(day))
Do you import like this?
from datetime import datetime
Then you must change it to look like this:
import datetime
Explanation: In the first case you are effectively calling datetime.datetime.date(), a method on the object datetime in the module datetime. In the later case you create a new date() object with the constructor datetime.date().
Alternatively, you can change the import to:
from datetime import datetime, date
and then construct with date(y,m,d) (without the datetime. prefix).
if you already have
from datetime import datetime
then you can construct like so:
christmas = datetime(2013,12,25)
You can use both datetime and datetime.datetime.
Write the imports like this:
from datetime import datetime
import datetime as dt
time_1 = datetime.strptime('17:00:00', '%H:%M:%S')
time_1 = dt.time(time_1.hour, time_1.minute, time_1.second)
I can reproduce the error if I do
from datetime import *
It goes away when I do
import datetime
So check your imports.
I suspect that the datetime reference the object and not the module. You probably did have the following code (probably more complex):
from datetime import datetime
currentdate = raw_input("Please enter todays date in the format dd/mm/yyyy: ")
day,month,year = currentdate.split('/')
today = datetime.date(int(year),int(month),int(day))
You are thus calling the date method of the datetime class instead of calling the date function of the datetime module.
You can print the datetime object to see if this is really the case:
>>> import datetime
>>> print datetime
<module 'datetime' (built-in)>
>>> print datetime.date(1, 1, 1)
0001-01-01
>>> datetime = datetime.datetime
>>> print datetime
<type 'datetime.datetime'>
>>> print datetime.date(1, 1, 1)
Traceback (most recent call last):
File "<pyshell#12>", line 1, in <module>
print datetime.date(1, 1, 1)
TypeError: descriptor 'date' requires a 'datetime.datetime' object but received a 'int'
TypeError: descriptor 'date' requires a 'datetime.datetime' object but received a 'int'
This is because you have used variables like year, month, day.
Use something like this:
year1, month1, day1 = [int(d) for d in startDate.split('-')]
print(date(year1, month1, day1))
and it will work.
The error suggest's your import looks fine. Instead, while doing an operation using datetime, make sure the values are converted to datetime format first.
use pandas.to_datetime to do the same, before you use any operation on the same.

Categories