Python check that the date is 30 days in the future - python

I want to write a test, that takes a time from a saved object recipient.expiry_date and checks that the date is 30 days in the future.
This is what I have tried:
days_to_match = timezone.now() + timedelta(days=30)
self.assertEqual(recipient.expiry_date, days_to_match)
Because it also contains the time this won't match.
How can this be done?
Please note that recipient.expiry_date is set in my model using timezone.now()so comparison on dates from python seemed to error.

As you can see in this SO answer, you can use the date() to compare only the date and not the time. Or you can put the time data = 0.
self.assertEqual(recipient.expiry_date.date(), days_to_match.date())

You can just look at the date portions:
self.assertEqual(recipient.expiry_date.year, days_to_match.year)
self.assertEqual(recipient.expiry_date.month, days_to_match.month)
self.assertEqual(recipient.expiry_date.day, days_to_match.day)

Related

How to test if a time variable is in a series or not in python

Background: Sometimes we need to take a date which is a month after than the original timestamp, since not all days are trading days, some adjustments must be made.
I extracted the index of stock close price, getting a time series with lots of timestamps of trading days.
trading_day_glossory = stock_close_full.index
Now, given a datetime-format variable date, with the following function, the program should return me the day variable indicating a trading day. But indeed it did not. The if condition is never evoked, eventually it added up to 9999:99:99 and reported error.
def return_trading_day(day,trading_day_glossory):
while True:
day = day + relativedelta(days=1)
if day in trading_day_glossory:
break
I reckon that comparing a timestamp with a datetime is problematic, so I rewrote the first part of my function in this way:
trading_day_glossory = stock_close_full.index
trading_day_glossory = trading_day_glossory.to_pydatetime()
# Error message: OverflowError: date value out of range
However this change makes no difference. I further tested some characteristics of the variables involved:
testing1 = trading_day_glossory[20] # returns a datetime variable say 2000-05-08 00:00:00
testing2 = day # returns a datetime variable say 2000-05-07 00:00:00
What may be the problem and what should I do?
Thanks.
Not quite sure what is going on because the errors cannot be reproduced from your codes and variables.
However, you can try searchsorted to find the first timestamp not earlier than a given date in a sorted time series by binary search:
trading_day_glossory.searchsorted(day)
It's way better than comparing values in a while loop.

How to get a year-week text in Python?

I have a table which contains information on the number of changes done on a particular day. I want to add a text field to it in the format YYYY-WW (e. g. 2022-01) which indicates the week number of the day. I need this information to determine in what week the total number of changes was the highest.
How can I determine the week number in Python?
Below is the code based on this answer:
week_nr = day.isocalendar().week
year = day.isocalendar().year
week_nr_txt = "{:4d}-{:02d}".format(year, week_nr)
At a first glance it seems to work, but I am not sure that week_nr_txt will contain year-week tuple according to the ISO 8601 standard.
Will it?
If not how do I need to change my code in order to avoid any week-related errors (example see below)?
Example of a week-related error: In year y1 there are 53 weeks and the last week spills over into the year y1+1.
The correct year-week tuple is y1-53. But I am afraid that my code above will result in y2-53 (y2=y1+1) which is wrong.
Thanks. I try to give my answer. You can easily use datetime python module like this:
from datetime import datetime
date = datetime(year, month, day)
# And formating the date time object like :
date.strftime('%Y-%U')
Then you will have the year and wich week the total information changes

Convert UTC+0 to other time zone Python

I have a time string obtained from API, it's UTC+0. I would like to change to other time zone.
I have tried below but it doesn't work. Could you please give me some idea ? many thanks.
utc0time='2021-04-17T15:50:14.614646+00:00'
dt = datetime.strptime('utc0time', '%Y-%m-%dT%H:%M:%S%z'). #it results as an error, not match the format
time.mktime(dt.timetuple())
calendar.timegm(dt.timetuple())
You could actually use timedelta in datetime module to +/- number of hours to achieve the time in other timezone you wish.
Here is an example where you can use timedelta:
https://www.geeksforgeeks.org/python-datetime-timedelta-function/
thanks for the comments and it gave me the idea. Because i only need to convert from one time zone to another one, i don't need to convert to multi-timezone. I don't use pytz this time. I used a silly method, changed the str to timestamp first, then used timedelta to adjust the hours. Below is my final code.
utc0time='2021-04-17T15:50:14.614646+00:00'
utc0time = utc0time[:-13]
timestamp = time.mktime(time.strptime(utc0time, '%Y-%m-%dT%H:%M:%S'))
datatimeformat = datetime.fromtimestamp(timestamp)
utc8time = datatimeformat + timedelta(hours = 8)

Get all objects created on same day till now

I have a model which contains created_at DateTimeField. I want to filter the model to get all object created on this day, month till now.
For Example : Date = 21/06/2016
Now I want to get all objects created on 21/06 till now irrespective of year.
Edit:
To be precise, I have model which stores Date of Birth of Users. I want to get all the users who were born on this day.
I tried using the __range, __gte, __month & __day. This things did not work.
Thanks for your comments and answers. I have used this answer to solve the problem. I have removed the timedelta(days) from the code.
An example of filtering outside of the queryset.
Get the date u want and remove unwanted results
from datetime import datetime, timedelta
twodaysago = str(datetime.strptime(str(datetime.now().date()-timedelta(days=2)), '%Y-%m-%d')).split()[0]
now do your query and filter it like this, you may also do it in the query filter, but if u need some extra manipulations do it in your code
date_filtered = [x for x in query\
if datetime.strptime(
x.get('created_at ', ''),
'%Y-%m-%d') > twodaysago
]
Not sure if I understand the problem correctly, but try this:
before = datetime.date(2016, 06, 21)
today = datetime.date.today()
MyModel.objects.filter(
created_at__month__range=(before.month, today.month),
created_at__day__range=(before.day, today.day)
)
From what I can understand from your question, you want to get all objects with the same date as today, irrespective of the year.
I would use something like this. See if this helps.
from datetime import datetime
today = datetime.now()
OneModel.objects.filter(created_at__day = today.day.__str__(),
created_at__month = today.month.__str__())
For more see this link: How can I filter a date of a DateTimeField in Django?

Sorting scheduled events python

So I have list of events that are sort of like alarms. They're defined by their start and end time (in hours and minutes), a range of days (ie 1-3 which is sunday through wed.), and a range of months (ie 1-3, january through march). The format of that data is largely unchangeable. I need to, not necessarily sort the list, but I need to find the next upcoming event based on the current time. There's just so many different ways to do this and so many different corner cases. This is my pseudo code:
now = time()
diff = []
# Start difference between now and start times
for s in schedule #assuming appending to diff
diff.minutes = s.minutes - time.minutes #
diff.hours = s.hours - time.hours
diff.days = s.days - time.days
diff.months = s.months - time.months
for d in diff
if d < 0
d = period + d
# period is the maximum period of the attribute. ie minutes is 60, hours is 24
# repeat for event end times
So now I have a list of tuples of differences in hours, minutes, days, and weeks. This tuple already takes into account if it's passed the start time, but before the end time. So let's say it's in August and the start month of the event is July and the end month is September, so diff.month == 0.
Now this specific corner case is giving me trouble:
Let's say a schedule runs from 0 to 23:59 thursdays in august. And it's Friday the 27th. Running my algorithm, the difference in months would be 0 when in reality it won't run again until next august, so it should be 12. And I'm stuck. The month is the only problem I think because the month is the only attribute that directly depends on what the date of the specific month is (versus just the day). Is my algorithm OK and I can just deal with this special case? Or is there something better out there for this?
This is the data I'm working with
map['start_time']=''
map['end_time']=''
map['start_moy']=''
map['end_moy']=''
map['start_dow']=''
map['end_dow']=''
The schedule getAllSchedules method just returns a list to all of the schedules. I can change the schedule class but I'm not sure what difference I can make there. I can't add/change the format of the schedules I'm given
Convert the items from the schedule into datetime objects. Then you can simply sort them
from datetime import datetime
events = sorted(datetime(s.year, s.month, s.day, s.hour, s.minute) for s in schedule)
Since your resolution is in minutes, and assuming that you don't have many events, then I'd simply scan all the events every minute.
Filter your events so that you have a new list where the event range match the current month and day.
Then for each of those events declare that they are active or inactive according to whether the current time matches the event's range.
The primary issue seems to be with the fact that you're using the day of the week, instead of explicit days of the month.
While your cited edge case is one example, does this issue not crop up with all events scheduled in any month outside of the current one?
I think the most robust approach here would be to do the work to get your scheduled events into datetime format, then use #gnibbler's suggestion of sorting the datetime objects.
Once you have determined that the last event for the current month has already passed, calculate the distance to the next month the event occurs in (be it + 1 year, or just + 1 month), then construct a datetime object with that information:
first_of_month = datetime.date(calculated_year, calculated_month, 1)
By using the first day of the month, you can then use:
day_of_week = first_of_month.strftime('%w')
To give you what day of the week the first of that month falls on, which you can then use to calculate how many days to add to get to the first, second, third, etc. instance of a given day of the week, for that month. Once you have that day, you can construct a valid datetime object and do whatever comparisons you wish with now().
I couldn't figure out how to do it using only datetimes. But I found a module and used this. It's perfect
http://labix.org/python-dateutil

Categories