Creating a date using another date in python using datetime module - python

I am making a simple program to calculate the difference between two dates: A specified date and the current date using datetime module.
def difference(current, until):
year, month, day = current.year, until.month, until.date
print("Year:", current.year, "Type:", type(current.year))
this_year = datetime.datetime(year, month, day)
return this_year - current
I can see that type(current.year) is an 'int'. However, when I try to make a new date, an error occurs. Output:
Year: 2023 Type: <class 'int'>
this_year = datetime.datetime(year, month, day)
TypeError: an integer is required (got type builtin_function_or_method)

tl;dr
Change
year, month, day = current.year, until.month, until.date
to
year, month, day = current.year, until.month, until.day
The current.year is definitely an integer. The issue is with your until.date variable that is getting assigned to day.
As mentioned in #chepner's comment: until.date is a bound method that returns a datetime.date object. Read more in the documentation about it here - https://docs.python.org/3/library/datetime.html#date-objects
Meanwhile, changing your until.date to until.day will fix your issue.

Related

Extraction of day, month and year from the date 4.5.6

Which function can I use to extract day, month and year from dates written in this manner 4.5.6 where 4 is the day, 5 is the month and 6 is the year (presumably 2006). I have already tried using dateparser.parse but it is not working.
day, month, year = map(int, '4.5.6'.split('.'))
And then add 2000 as necessary to the year.
You can then construct a datetime object with
from datetime import datetime
dt = datetime(year, month, day)
While it would be logical to use datetime.strptime, the one-digit year messes things up, and the above will just work fine.
Here is how you can use the datetime.datetime.strptime() method:
import datetime
s = "4.5.6"
i = s.rindex('.') + 1
s = s[:i] + s[i:].rjust(2, '0') # Add padding to year
dt = datetime.datetime.strptime(s, "%d.%m.%y")
print(dt)
Output:
2006-05-04 00:00:00
With the resulting datetime.datetime object, you can access plenty of information about the date, for example you can get the year by printing dt.year (outputs 2006).

Trying to make a countdown, where you input the the date

Trying to make a countdown, where you input the date:
from datetime import datetime
year = int(input('Enter a year: '))
month = int(input('Enter a month: '))
day = int(input('Enter a day: '))
date = datetime.date(year, month, day)
countdown = date - datetime.now()
print(countdown)
The error is:
line 7, in <module>
date = datetime.date(year, month, day)
TypeError: descriptor 'date' for 'datetime.datetime' objects doesn't apply to a 'int' object
Try this:
date = datetime(year, month, day).date()
countdown = date - datetime.now().date()
print(countdown)
That error is raised when an operation or function is applied to an object of inappropriate type.
A datetime object is a single object containing all the information from a date object and a time object.
A date object represents a date (year, month and day) in an idealized calendar, the current Gregorian calendar indefinitely extended in both directions.
Try adding .date() to datetime object.
e.g.: datetime(year, month, day).date()

TypeError: can't compare datetime.datetime to datetime.date

I have the following code
minDate = date(9999, 12, 31)
start = event.get('dtstart').dt
if isinstance(start, datetime.datetime):
newStart = start.date()
else:
newStart = start
if(newStart < minDate):
minDate = start
why am I getting this error as I have converted to date on both ends of the comparison
They are not the same type. From Docs:
class datetime.date
- An idealized naive date, assuming the current Gregorian calendar always was, and always will be, in effect. Attributes: year, month, and day.
class datetime.datetime
- A combination of a date and a time. Attributes: year, month, day, hour, minute, second, microsecond, and tzinfo
You will need to mitigate the comparison here:
if(newStart < minDate):
Where minDate is date type and newStart is dateTime

python dateutil relativedelta value out of range error

i am trying to get two dates, yesterday's and tomorrow's based on a given date which i then pass on to Django's Queryset filter function:
nxtday = relativedelta(day=+1) + date
yesterday = relativedelta(day=-1) + date
events = events.filter(start_datetime__gte=yesterday, end_datetime__lte=nxtday)
The point here is to get the events for the day as you've already probably deduced. Problem is i keep getting this error:
ValueError: day is out of range for month
Switching to timedelta objects raises issues later with dateutil's rrule:
TypeError: can't compare offset-naive and offset-aware datetimes
I am fond of dateutil module so i am just curious why it didn't work. Example date passed: 2014-02-26. Any ideas?
Passing -1 for the day parameter is requesting the -1 day of the month, which is why it complains about an out of range value.
For relative delta the day parameter is for absolute dates, and the days parameter is for relative dates. docs
nxtday = relativedelta(days=1) + date
yesterday = relativedelta(days=-1) + date

Convert year, day of year and fractional hour to a real date in python

I would like to convert arrays of year, day of year and fractional hours to a real date.
Thats my code up to now:
year = [2012,2012,2012]
day = [2,3,4] #day of year
hour = [12,12,12]
import datetime
import pytz
dt=list()
for i in range(len(year)):
dt.append(datetime.datetime(year[i], day[i], hour[i],tzinfo=pytz.UTC))
dt=np.array(dt)
print dt `
The constructor for datetime objects takes a year, month, and day, and optional hour, minute, etc. So, you're passing the day as the month, the hour as the day, and nothing as the hour.
On top of that, day has to be a day of the month, not a day of the year, and hour has to be an integer (with separate minutes, seconds, and microseconds if appropriate).
One easy way around this is to create a datetime with the start of the year, and add the days and hours on with timedelta.
While we're at it, you can make the code a bit cleaner by iterating directly over the arrays instead of over range(len(…)).
for y, d, h in zip(year, day, hour):
d0 = datetime.datetime(y, 1, 1, tzdata=pytz.UTC)
dt.append(d0 + datetime.timedelta(days=d, hours=h))
As a side note, I'd name the list variables years, days, hours, and dts, so I could name the individual iteration values year, day, hour, and dt. And, while we're at it, I'd write this as a helper function and a list comprehension rather than a for loop and a complicated body. And put the imports at the time. Like this:
import datetime
import pytz
years = [2012,2012,2012]
days = [2,3,4] #day of year
hours = [12,12,12]
def make_date(year, day, hour, tzdata=pytz.UTC):
dt = datetime.datetime(year, 1, 1, tzdata=tzdata)
return dt + datetime.timedelta(days=day, hours=hour)
dts = [make_date(year, day, hour) for year, day, hour in zip(years, days, hours)]
The above works for your original question, where years and days are lists of integers and hours is a list of floats (as in your description) or integers (as in your sample code). It will also work if days is a list of floats, but not years.
However, from a comment, it sounds like these are actually numpy arrays of int64 values. Although you call them floats, int64 is not a floating-point type, it's an integer type. And you can convert an int64 to a plain Python int with no loss of range or precision.
So, because the datetime and timedelta constructors won't accept int64 values, just convert each one into an int:
def make_date(year, day, hour, tzdata=pytz.UTC):
dt = datetime.datetime(int(year), 1, 1, tzdata=tzdata)
return dt + datetime.timedelta(days=int(day), hours=int(hour))
If your hours were actually of a floating-point type as you originally claimed, like float64, you'd want to use float(hour) instead of int(hour).
One last thing: From your description, I guessed that your days were 0-based (and your hours, but that's not likely to be wrong). If your days are actually 1-based, you're obviously going to need to do days=int(day)-1.

Categories

Resources