Is there a library in python that can produce date dimensions given a certain day? I'd like to use this for data analysis. Often I have a time series of dates, but for aggregation purposes I'd like to be able to quickly produce dates associated with that day - like first date of month, first day in week, and the like.
I think I could create my own, but if there is something out there already it'd be nice.
Thanks
Have a look at dateutil.
The recurrence rules and relative deltas are what you want.
For example, if you wanted to get last monday:
import dateutil.relativedelta as rd
import datetime
last_monday = datetime.date.today() + rd.relativedelta(weekday=rd.MO(-1))
time and datetime modules
For some of your purposes you can use time module with strftime() method or date module with its strftime() method. It allows you to pull, among other data:
number of the week of the year,
number of the weekday (you can also use weekday() method for getting weekday number between 0 for Monday and 6 for Sunday),
year,
month,
Which will suffice to calculate first day of the month, first day of the week and some other data.
Examples
To pull the data you need, do just:
to pull the number of the day of the week
>>> from datetime import datetime
>>> datetime.now().weekday()
6
to pull the first day of the month use replace() function of datetime object:
>>> from datetime import datetime
>>> datetime.now()
datetime.datetime(2012, 3, 3, 21, 41, 20, 953000)
>>> first_day_of_the_month = datetime.now().replace(day=1)
>>> first_day_of_the_month
datetime.datetime(2012, 3, 1, 21, 41, 20, 953000)
EDIT: As J.F. Sebastian suggested within comments, datetime objects have weekday() methods, which makes using int(given_date.strftime('%w')) rather pointless. I have updated the answer above.
Related
In a Django query, how would you filter by a timestamp's week within a month?
There's a built-in week accessor, but that refers to week-of-the-year, e.g. 1-52. As far as I can tell, there's no other built-in option.
The only way I see to do this is to calculate the start and end date range for the week, and then filter on that using the conventional means.
So I'm using a function like:
def week_of_month_date(year, month, week):
"""
Returns the date of the first day in the week of the given date's month,
where Monday is the first day of the week.
e.g. week_of_month_date(year=2022, month=8, week=2) -> date(2022, 8, 7)
"""
assert 1 <= week <= 5
assert 1 <= month <= 12
for i in range(1, 32):
dt = date(year, month, i)
_week = week_of_month(dt)
if _week == week:
return dt
and then to calculate for, say, the 3rd week of July, 2022, I'd do:
start_date = week_of_month_date(2022, 7, 3)
end_date = week_of_month_date(2022, 7, 3) + timedelta(days=7)
qs = MyModel.objects.filter(created__gte=start_date, created__lte=end_date)
Is there an easier or more efficient way to do this with the Django ORM or SQL?
The easiest way to do this using datetime objects is to quite simply subtract the current date weekly year value, with the yearly week value for the 1st day (or 1st week) of the month.
You can use the .isocalendar() function to achieve this:
dt.isocalendar[1] - dt.replace(day=1).isocalendar()[1] + 1
Basically if the week is 46 and that means the first week is week 44 then the resulting output should be 2.
UPDATE
I misunderstood the question, the answer is clear below. However, you may want to consider revising your function based on my above comments.
Come to think of it, if you have a datetime object, you can get the isocalendar week and filter using that like so:
MyModel.objects.filter(created__week=dt.isocalendar()[1])
dt.isocalendar() returns essentially a tuple of 3 integers, [0], is the year, [1], is the iso week (1-52 or 53) and [2], the day of the week (1-7).
As per the docs here:
https://docs.djangoproject.com/en/4.1/ref/models/querysets/#week
There is a built-in filter for isoweek out of the box :)
However, filtering by "week of month" is not possible within the realms of "out of the box".
You might consider writing your own query expression object which accepts an isocalendar object and converts that? But I think you would be better off converting a datetime object and use the isoweek filter.
There's a neat little blog post here to get you started if you really want to do that:
https://dev.to/idrisrampurawala/writing-custom-django-database-functions-4dmb
How do I convert a number to its correlating day of the week?
For example:
def string(hour_of_day, day_of_week, date) :
print(f'{day_of_week} {date} at hour {hour_of_day}')
how can I re-write the 'day_of_week' part in print so that when I use the function:
string(12, 1, '2020/02/18')
How can I get Tuesday 2020/02/18 at hour 12 instead of 1 2020/02/18 at hour 12?
Use a dictionary along the lines of
daysdict = { 1: 'Monday', 2: 'Tuesday'} exetended for all the days
then access using daysdict[1]
Although your day 1 seems to be Tuesday!
It is possible to get the day directly from the date itself - something for you to check out.
Use calendar module
If you have already the weekday number, do:
import calendar
day_of_week = 1
calendar.day_name[day_of_week]
## 'Tuesday'
The calendar module is always available in Python (it is belongs to the inbuilt standard modules).
So the dictionary {0: "Monday", 1: "Tuesday", ...} is already defined as calendar.day_name. So no need to define it yourself. Instead type import calendar and you have it available.
Use datetime module to get weekday directly from the date
from datetime import datetime
def date2weekday(date):
return datetime.strptime(date, "%Y/%m/%d").strftime('%A')
def myfunction(hour_of_day, date):
return f"{date2weekday(date)} {date} at hour {hour_of_day}"
myfunction(12, '2020/02/18')
## 'Tuesday 2020/02/18 at hour 12'
You can use the strftime method from a datetime object:
import datetime
print(datetime.datetime(2022, 10, 21).strftime('%A %Y/%m/%d'))
It will give you this answer:
Friday 2022/10/21
To adapt it to your solution just do this:
from datetime import datetime
def string(hour_of_day, date):
print(f'{date.strftime('%A %Y/%m/%d')} at hour {hour_of_day}')
string(12, datetime(year=2022, month=10, day=21))
The good thing about this solution is that you don't need to know the day of the week of a date, Python already knows that, just ask him ;)
To know more about date formatting you can visit the datetime documentation in the official Python site
I would LIKe to know how to set a specific DateTime timestamp using the DateTime module in python. For example if I want ... To happen on 1 August 2022. How can I make a DateTime timestamp that will hold that date. Thanks for all help in advance
You can construct a new datetime object with your date (and optionally with time) and then call timestamp() on it.
For example, you can do:
from datetime import datetime
timestamp = datetime(2022, 8, 1).timestamp()
# timestamp is now 1659304800.0
You can find the official documentation here.
To create a date, we can use the datetime() class (constructor) of the datetime module.
The datetime() class requires three parameters to create a date: year, month, day.
Example
Create a date object:
import datetime
x = datetime.datetime(2020, 5, 17)
print(x)
source
I'm hoping to create a program that takes todays date and a given date in the future and finds the difference in days between those two dates. I'm not too sure as to how I would go about doing this and I have very little experience using datetime.
From what I've been trying and reading up, I need to import datetime, and then grab todays date. After that, I need to take an input from the user for the day, month and year that they want in the future, and to make a check that the current year is less than the future year. After that, I'll need to do a calculation in the difference in days between them and print that to the screen.
Any help would be very much appreciated.
Many Thanks
here a hint for you small program using datetime and time:
>>> import time
>>> import datetime
>>> today_time = time.time()
>>> today_time
1415848116.311676
>>> today_time = datetime.datetime.fromtimestamp(today_time)
>>> today_time
datetime.datetime(2014, 11, 13, 8, 38, 36, 311676)
>>> future_time = input("Enter Year,month,day separeted by space:")
Enter Year,month,day separeted by space:2015 06 24
>>> year,month,day = future_time.split()
>>> diff = datetime.datetime(int(year),int(month),int(day)) - today_time
>>> diff.days
222
you can use datetime.date but instead asking user current date, you can have it from the system using time.time
Situation:
I am trying to construct a simple method that accepts two different integers that represent two different dates. 20120525 for May 25, 2012 and 20120627 for June 26, 2012 as an example. I want this method to return a list of these integer types that represent all days between the two date parameters.
Question:
Could I get any suggestions on how to do this and how to handle months of either 28, 29, 30 or 31 days in each. I think I can do this by extracting the numbers as integers through division/modding of powers of 10, and then incrementing these numbers as such with the particular conditions above, but I feel like there must be an easier way to do this.
You don't have to reinvent the wheel. Just parse the strings into datetime objects and let python do the math for you:
from dateutil import rrule
from datetime import datetime
a = '20120525'
b = '20120627'
for dt in rrule.rrule(rrule.DAILY,
dtstart=datetime.strptime(a, '%Y%m%d'),
until=datetime.strptime(b, '%Y%m%d')):
print dt.strftime('%Y%m%d')
prints
20120525
20120526
20120527
…
20120625
20120626
20120627
An alternative solution without using rrule goes here:
import datetime
d1 = datetime.date(2015, 1, 1)
d2 = datetime.date(2015, 2, 6)
days = [d1 + datetime.timedelta(days=x) for x in range((d2-d1).days + 1)]
for day in days:
print(day.strftime('%Y%m%d'))
Output:
20150101
20150102
20150103
<snip>
20150205
20150206
You can use pandas.date_range,
import pandas
pd.date_range('2012-05-25', '2012-06-27', freq='D')
which would produce,
DatetimeIndex(['2012-05-25', '2012-05-26', '2012-05-27', '2012-05-28',
'2012-05-29', '2012-05-30', '2012-05-31', '2012-06-01',
...
'2012-06-22', '2012-06-23', '2012-06-24', '2012-06-25',
'2012-06-26', '2012-06-27'],
dtype='datetime64[ns]', freq='D')