I need to calculate the date based on the number of minutes from the start of the year. I just need the day and month.
I have tried a few different classes within Python datetime but I can not get the desired result.
for example, at 1700 today, minutes since the 01/01/2022 is 263100
print(datetime.timedelta(0,0,0,0,263100))
This returns
182 days, 17:00:00
Before I explicitly write out the months and how many days they have and work it out that way, is there something already built in that I am missing within datetime?
I think this is what you are looking for. We add the minutes timedelta to the start datetime, and return it formatted.
from datetime import datetime, timedelta
def datesince_min(min:int, start:tuple=(2022,1,1)) -> str:
date = datetime(*start) + timedelta(minutes=min)
return date.strftime("%A, %B %d, %Y %I:%M:%S")
print(datesince_min(263100)) #Saturday, July 02, 2022 06:00:00
For more information regarding strftime formatting, refer to this.
Before I explicitly write out the months and how many days they have and work it out that way...
You shouldn't ever have to do that, and if you did it would almost certainly have to be for a system or language that is in development.
I found this code that should do the trick:
number_of_days = ((datetime.timedelta(0,0,0,0,263100)).split())[0]
months = (number_of_days - years * 365) // 30
days = (number_of_days - years * 365 - months*30)
print(months, days)
Where you replace 263100 with whatever minutes you wish ofc
(source: https://www.codesansar.com/python-programming-examples/convert-number-days-years-months-days.htm#:~:text=Python%20Source%20Code%3A%20Days%20to%20Years%2C%20Months%20%26,print%28%22Months%20%3D%20%22%2C%20months%29%20print%28%22Days%20%3D%20%22%2C%20days%29)
:)
Related
how to get same day last year in python
I tried datetime.datetime.now() - relativedelta(years=1) but this doesn't produce the result I'm looking.
Can anyone help. Thanks
example:
20/08/2020 (Thursday) last year will be 22/08/2019 (Thursday)
The answer from Pranav Hosangadi here is very nice, but please note that not every year has 52 weeks! It may be also 53, if you follow the
ISO8601 week numbering standard.
Number of ISO weeks in a year may be get according to this Stack Overflow thread, resulting in you code:
print(datetime.datetime.now())
2020-08-20 22:57:28.061648
def lastweeknumberoflastyear():
return datetime.date(datetime.datetime.now().year-1, 12, 28).isocalendar()[1]
print(datetime.datetime.now() - datetime.timedelta(weeks=lastweeknumberoflastyear()))
2019-08-22 22:57:28.061785
You want the same day of week one year ago. A year has 52 weeks
print(datetime.datetime.now())
2020-08-20 17:56:56.397626
print(datetime.datetime.now() - datetime.timedelta(weeks=52))
2019-08-22 17:56:56.397626
You can do something like:
now = datetime.datetime.now()
last_year = now.replace(now.year - 1)
Note that this will not account for leap years. If you want to find a date exactly 365 days prior, you would instead do something like:
now = datetime.datetime.now()
last_year = now - datetime.timedelta(days=365)
I'd probably do it like this, as a year is not always 365 days.
from datetime import datetime
x = datetime.now()
last_year = datetime(x.year-1,x.month,x.day,x.hour,x.minute,x.second,x.microsecond)
Let's say you want to look at today's date and then get the same date but last year:
today = datetime.date.today()
previous_year = today.year -1
today_last_year = today.replace(year = previous_year)
I have this function where it calculates today. I am wondering why is the following results are happening.
today = datetime.datetime.now()
shows as 2018-06-13 17:13:42.372469
today = datetime.datetime.now().date()
shows as 2018-06-13
but when I try to use timedelta like this:
today = datetime.datetime.now().date() + datetime.timedelta(hours=-8)
it shows 2018-06-12. A full day back instead of 8 hours (should show 2018-06-13 9:13:42)
Can someone please explain why this happens and have timedelta correctly go back 8 hours instead of a day?
By reducing the timestamp to the date only, you have effectively set the time to 00:00:00 - substracting 8 hours from 2018-06-13 midnight correctly results in 2018-06-12.
Why not use the correct timestamps for calculation, and only convert them to dates after you have performed them?
so I am a beginner with python and have been working with the datetime, time, and timedelta libraries a little bit. I am trying to create a piece of code that gives me the date approximately two months ago(exact_two_months_date) from today (whatever today happens to be). The catch is, I want to find that date approx. two months ago AND begin the actual start_date on the Monday of that week. So in theory, the actual start date will not be exactly two months ago. It will be the week beginning on Monday two months ago from today.
Example pseudocode:
today = '20150425' ## '%Y%m%d' ... Saturday
exact_two_months_date = '20150225' ## EXACTLY two months ago ... Wednesday
start_date = '20150223' ## this is the Monday of that week two months ago
So how do I find the 'start_date' above? If the day exactly two months ago begins on a Saturday or Sunday, then I would just want to go to the next Monday. Hope this is clear and makes sense... Once I find the start date, I would like to increment day by day(only week days) up to 'today'.
Appreciate any feedback, thanks.
Calculating with dates using python-dateutil
If a dependency on a third-party package is an option, then ☞ python-dateutil provides a convenient method to calculate with dates.
Browse the docs for ☞ relativedelta to see the wealth of supported parameters. The more calculations a package needs to do with dates, the more a helper module like dateutil justifies its dependency. For more inspiration on what it has to offer see the ☞ examples page.
Quick run-through:
>>> import datetime
>>> from dateutil.relativedelta import relativedelta
>>> today = datetime.date.today()
>>> two_m_ago = today - relativedelta(months=2)
>>> # print two_m_ago ~> datetime.date(2015, 2, 25)
>>> monday = two_m_ago - datetime.timedelta(days=two_m_ago.weekday())
>>> # print monday ~> datetime.date(2015, 2, 23)
Getting the Monday with weekday()
Once we have the date from two months ago in the variable two_m_ago, we subtract the index of the weekday() from it. This index is 0 for Monday and goes all the way to 6 for Sunday. If two_m_ago already is a Monday, then subtracting by 0 will not cause any changes.
Does something like this work for you?
import datetime
today = datetime.date.today()
delta = datetime.timedelta(days=60) # ~ 2 months
thatDay = today - delta
# subtract weekdays to get monday
thatMonday = thatDay - datetime.timedelta(days=thatDay.weekday())
Honestly, I find working with datetimes to be the hardest thing I ever have to regularly do and I make a lot of mistakes, so I'm going to work through this one and show some of the failures I regularly have with it. Here goes.
Two constraints: 1) Date two months ago, 2) Monday of that week
Date Two Months Ago
Okay, so Python's datetime library has a useful method called replace, which seems like it might help here:
>>> import datetime
>>> now = datetime.date.today()
>>> today
datetime.date(2015, 4, 25)
>>> today.month
4
>>> two_months_ago = today.replace(month=today.month-2)
>>> two_months_ago
datetime.date(2015, 2, 25)
>>> two_months_ago.month
2
But wait: what about negative numbers? That won't work:
>>> older = datetime.date(2015, 01, 01)
>>> older.replace(month=older.month-2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: month must be in 1..12
So there are two solutions:
1) I can build a 1-12 range that cycles forwards or back, or
2) To find two months previous, I can merely replace the day part of my date with the 1st day of the month I'm in and then go back 1 day to the previous month and then replace that day in the previous month with the day I want.
(If you think about it, you'll find that either of these may present bugs if I land on day 31 in a month with fewer days than that, for instance. This is part of what makes datetimes difficult.)
def previous_month(date):
current_day = date.day
first_day = date.replace(day=1)
last_day_prev_month = first_day - datetime.timedelta(days=1)
prev_month_day = last_day_prev_month.replace(day=current_day)
return prev_month_day
>>> today = datetime.date.today()
>>> older = previous_month(today)
>>> older
datetime.date(2015, 3, 25)
Well, let's say we're getting close, though, and we need to include some error-checking to make sure the day we want is a valid date inside the month we land in. Ultimately, the problem is that "two months ago" means a lot more than we think it means when we say it out loud.
Next, we'll take a crack at problem number two: How to get to the Monday of that week?
Well, datetime objects have a weekday method, so this part shouldn't be too hard and here's a nice SO answer on how to do that.
Simple version is: use the difference in weekday integers to figure out how many days to go back and do that using datetime.timedelta(days=days_difference).
Takeaway: Working with datetimes can be tough.
Date manipulation in Python is horribly convoluted. You will save a lot of time by using the arrow package which greatly simplifies these operations.
First install it
pip install arrow
Now your question:
import arrow
# get local current time
now = arrow.now('local')
# move 2 months back
old = now.replace(months=-2)
# what day of the week was that?
dow = old.isoweekday()
# reset old to Monday, for instance at 9:32 in the morning (this is just an example, just to show case)
old = old.replace(days=-dow, hour=9, minute=32, second=0)
print('now is {now}, we went back to {old}'.format(now=now.isoformat(), old=old.isoformat()))
The output:
now is 2015-04-25T20:37:38.174000+02:00, we went back to 2015-02-22T09:32:00.174000+01:00
Note that the various formats, timezones etc. are now transparent and you just need to rely on one package.
I would like to do something like this:
entries = Entry.objects.filter(created_at__in = current_week())
How to make it for good performance. Thanks!
Edit: I still have no idea for current_week() function.
Use __range. You'll need to actually calculate the beginning and end of the week first:
import datetime
date = datetime.date.today()
start_week = date - datetime.timedelta(date.weekday())
end_week = start_week + datetime.timedelta(7)
entries = Entry.objects.filter(created_at__range=[start_week, end_week])
Since Django 1.11, we you can use week Field lookup:
Entry.objects.filter(created_at__week=current_week)
It will give you the week from monday to sunday, according to ISO-8601.
To query for the current week:
from datetime import date
current_week = date.today().isocalendar()[1]
isocalendar() will return a tuple with 3 items: (ISO year, ISO week number, ISO weekday).
Yep, this question is at 2 years ago. Today with more experiences, I recommend using arrow with less pain in handling date time.
Checkout: https://github.com/crsmithdev/arrow
I have two datetime objects; a start date and an end date. I need to enumerate the days, weeks and months between the two, inclusive.
Ideally the results would be in datetime form, though any compatible form is fine. Weeks and months are represented by a date corresponding to the first day of the week/month, where Monday is the first day of a week, as in ISO-8601. This means that the result may contain a date earlier than the start date.
For example, given 2010-11-28 to 2010-12-01, the results would be as follows:
days: 2010-11-28, 2010-11-29, 2010-11-30, 2010-12-01
weeks: 2010-11-22, 2010-11-29
months: 2010-11-01, 2010-12-01
I realize that the list of days is by itself straightforward, but I'd like a clean and consistent solution that uses a similar approach for all three. It seems like the calendar module should be useful, but I'm not seeing a good way to use it for this purpose.
Using dateutil:
import datetime
import dateutil.rrule as drrule
import dateutil.relativedelta as drel
import pprint
def dt2d(date):
'''
Convert a datetime.datetime to datetime.date object
'''
return datetime.date(date.year,date.month,date.day)
def enumerate_dates(start,end):
days=map(dt2d,drrule.rrule(drrule.DAILY, dtstart=start, until=end))
# Find the Monday on or before start
start_week=start+drel.relativedelta(weekday=drel.MO(-1))
end_week=end+drel.relativedelta(weekday=drel.MO(-1))
weeks=map(dt2d,drrule.rrule(drrule.WEEKLY, dtstart=start_week, until=end_week))
# Find the first day of the month
start_month=start.replace(day=1)
end_month=end.replace(day=1)
months=map(dt2d,drrule.rrule(drrule.MONTHLY, dtstart=start_month, until=end_month))
return days,weeks,months
if __name__=='__main__':
days,weeks,months=enumerate_dates(datetime.date(2010,11,28),
datetime.date(2010,12,01))
print('''\
days: {d}
weeks: {w}
months: {m}'''.format(d=map(str,days),w=map(str,weeks),m=map(str,months)))
yields
days: ['2010-11-28', '2010-11-29', '2010-11-30', '2010-12-01']
weeks: ['2010-11-22', '2010-11-29']
months: ['2010-11-01', '2010-12-01']