Scenario A:
Suppose the current time is 3 am on Jan 12th, 2014, I want to get two times in past for midnight just before 3 am and noon just before 3 am
So, I am looking at getting 00:00 hours of Jan 12th and noon of Jan 11th from the current time of 3 am on Jan 12th, 2014
Scenario B:
Suppose the current time is 6:37 pm on Jan 13th, 2014, I want to get two times in past for midnight just before 6:37 pm and noon just before 3 pm
So, I am looking at getting 00:00 hours of Jan 13th and noon of Jan 13th for the current time of 6:37 pm on Jan 13th, 2014
The times can be in epoch - I am just not able to figure out the math to get the two times given a current time.
Can someone help me out?
You can combine a date and time using datetime.datetime.combine, so you can get just the current date:
today = datetime.datetime.now().date()
Create your times, e.g.:
midday = datetime.time(hour=12)
And add them together, e.g.:
midday_today = datetime.datetime.combine(today, midday)
This is much less complicated than trying to add or subtract times from the current time. To decide whether you want today or yesterday, you can check whether we are before or after midday:
if datetime.datetime.now().time() < midday:
Putting this together:
import datetime
now = datetime.datetime.now()
today = now.date()
midnight = datetime.time(hour=0)
midday = datetime.time(hour=12)
last_midnight = datetime.datetime.combine(today, midnight)
if now.time() < midday:
yesterday = today - datetime.timedelta(days=1)
last_midday = datetime.datetime.combine(yesterday, midday)
else:
last_midday = datetime.datetime.combine(today, midday)
Related
Is there a way to use Python to get last Friday's date and store it in a variable, regardless of which day of the week the program runs?
That is, if I run the program on Monday June 19th 2021 or Thursday June 22nd 2021, it always returns the previus Friday as a date variable: 2021-07-16.
To get the day of the week as an int we use datetime.datetime.today().weekday() and to subtract days from a datetime we use datetime.today() - timedelta(days=days_to_subtract) now we can make a dictionary linking the day of the week to the number of days to subtract and use that dictionary to make a subtraction:
from datetime import datetime, timedelta
d = {0:3,1:4,2:5,3:6,4:0,5:1,6:2}
lastfriday = datetime.today()-timedelta(days=d[datetime.today().weekday()])
Your question is similar to this one
Here's a starting point:
import datetime
def get_last_friday():
current_time = datetime.datetime.now()
last_friday = (current_time.date()
- datetime.timedelta(days=current_time.weekday())
+ datetime.timedelta(days=4, weeks=-1))
return last_friday
I'd like to write a small function that can calculate the number of hours in any given day, for any time zone. The obvious approach was to count the hours between the first instant of the day and the next day. Unfortunately, whatever day I choose, this approach always says that a day is 24 hours long.
In the UK, the clocks are advanced at 1am in March by 1 hour. That means the 28th March 2021 should have 23 hours. The time-range from 1am to 2am will not have existed that day.
Likewise, on the 31st October 2021 the clock is pushed back at 1am, so that day will have 25 hours. The time-range midnight to 1am will have occurred twice in that day.
import datetime
import pytz
# When do the clocks change?
# https://www.gov.uk/when-do-the-clocks-change
day0=datetime.datetime(2021,3,28, tzinfo=pytz.timezone("Europe/London"))
day1=datetime.datetime(2021,3,29, tzinfo=pytz.timezone("Europe/London"))
delta = day1-day0
print(delta)
hours = delta / datetime.timedelta(hours=1)
print(hours)
This script gives output that seems incorrect:
1 day, 0:00:00
24.0
Is there a simpler way to get the number of hours in a particular day, that gives the right answer?
Ideally this should be able to account for daylight savings, leap-years and even leap seconds.
Part of the issue is "using the tzinfo argument of the standard datetime constructors ‘’does not work’’ with pytz for many timezones."
So we can work around that by using timezone.localize() with a local naive time (no tz):
London = pytz.timezone("Europe/London")
day0 = London.localize(datetime.datetime(2021,3,28))
day1 = London.localize(datetime.datetime(2021,3,29))
(day1 - day0).total_seconds() / 60 / 60 # in hours
# 23.0
And for 31st October:
day0 = London.localize(datetime.datetime(2021, 10, 31))
day1 = London.localize(datetime.datetime(2021, 11, 1))
(day1 - day0).total_seconds() / 60 / 60
# 25.0
I am working on a website with weekly votations, but only the first three weeks of the month, so in each instance I have a start_date and end_date field.
I'd like to know if there's a way to automitically create these instances based on the current date, for instance:
Today it is 6 of March, and votations end tomorrow, so a function should be run (tmrw) that, taking into account this month calendar, would fill in the appropiate dates for the next votations. What calendar do you recommend me, and how shoul I do it?
(Never mind the automatically run part, I'll go with celery).
Thanks!
I am not sure what your problem is and I don't know what votations are. But as a general direction of thinking: there is timeboard library that can generate rule-based schedules (calendars) and do calculations over them (DISCLAIMER: I am the author).
The code below designates, for every month of 2018, the days of the first three weeks of the month as 'on-duty' (i.e. 'active', 'usable') and the rest as 'off-duty':
>>> import timeboard as tb
>>> weekly = tb.Organizer(marker='W', structure=[[1],[1],[1],[0],[0],[0]])
>>> monthly = tb.Organizer(marker='M', structure=[weekly])
>>> clnd = tb.Timeboard(base_unit_freq='D',
... start='01 Jan 2018', end='31 Dec 2018',
... layout=monthly)
For example, in March 2018, the days from Thursday, 1st, through Sunday, 18th, are marked 'on-duty', and the days 19-31 are marked 'off-duty'.
Now you can move along the calendar picking only on-duty days. For example, adding 1 to March, 17 gives you March 18:
>>> (clnd('17 Mar 2018') + 1).to_timestamp()
Timestamp('2018-03-18 00:00:00')
However, adding 2 carries you over to April 1, as March 19 is NOT within the first 3 weeks of March:
>>> (clnd('17 Mar 2018') + 2).to_timestamp()
Timestamp('2018-04-01 00:00:00')
I want to design an algorithm which will calculate the week number according to the start week day set. for eg : - If I set the start day as WEDNESDAY and currently its 40 week and its TUESDAY, it should print 40 as the week number. If it is WEDNESDAY or THURSDAY, I should get 41.
Think of it like a cycle. From Wednesday till tuesday, it should be assigned a week no + 1, then when next wednesday comes, week should be incremented again.
I tried using calendar.setfirstweekday(calendar.WEDNESDAY) and then altering my system machine time, all I get is 40 as the week number everytime.
How do I design such as algorithm in python?
I have a similar problem for month, but I have designed a solution for it. Here is it.
current_date = datetime.datetime.now()
if current_date.day < gv.month_start_date:
month = current_date.month -1
if month == 0:
month = 12
else:
month = current_date.month
How can I design it for week?
I finally designed a solution for this.
if current_day >= set_week_day:
week = current_week
else:
week = current_week - 1
Works for all cases.
datetime in python has a function called isocalender to get the ISO week number (starts on Monday)
import datetime
datetime.date(2013, 9, 30).isocalendar()[1]
You can use this with a little bit of logic (this script should have the week begin on Wednesdays)
import datetime
day = 30
month = 9
year = 2013
weekcount = datetime.date(year, month, day).isocalendar()[1]
if datetime.date(year, month, day).isocalendar()[2] <= 3: # start on wednesday
weekcount -= 1
print weekcount
I need to get the following values
Today = 6th Feb
time 1 = 5th Feb 0000 hrs
time 2 = 6th Feb 0000 hrs.
So I have 24 hours in epoch time. The reference is today but not now()
So far I have this.
yesterday = datetime.date.today() - datetime.timedelta(days=1)
epoch_yesterday = time.mktime(yesterday.timetuple())
epoch_today = time.mktime(datetime.date.today().timetuple())
Both epoch_ values are actually returning seconds from now() like 1600 hrs (depends on when I run the script) not from 0000/2400 hrs. I understand it would be better to get yesterdays epoch time and then ad 24 hours to it to get the end date. But I need to get the first part right :) , maybe I need sleep?
p.s. Sorry code styling isn't working, SO won't let me post with code styling and was very frustrating to get SO to post this.
The simpler way might be to construct the date explicitly as so:
now = datetime.now()
previous_midnight = datetime.datetime( now.year, now.month, now.day )
That gets you the timestamp for the just passed midnight. As you already know time.mktime will get you your the epoch value. Just add or subtract 24 * 60 * 60 to get the previous or next midnight from there.
Oh! And be aware that the epochal value will be seconds from midnight 1970, Jan 1st UTC. If you need seconds from midnight in your timezone, remember to adjust accordingly!
Update: test code, executed from the shell at just before 1 pm, PST:
>>> from datetime import datetime
>>> import time
>>> time_now = datetime.now()
>>> time_at_start_of_today_local = datetime( n.year, n.month, n.day )
>>> epochal_time_now = time.mktime( time_now.timetuple() )
>>> epochal_time_at_start_of_today_local = time.mktime( time_at_start_of_today.timetuple() )
>>> hours_since_start_of_day_today = (epochal_time_at_start_of_today_local - epochal_time_now) / 60 / 60
12.975833333333332
Note: time_at_start_of_today_local is the number of seconds between 1970 Jan 1st, midnight, and the start of the current day in your timezone. If you want the number of seconds to the start of the current day in UTC, then subtract your time zone from time_at_start_of_today_local:
>>> time_at_start_of_today_utc = time_at_start_of_today_local - time.timezone
Be aware that you get into odd territory here, specifically who's day do you care about? If it's currently Tuesday in your timezone, but still Monday in UTC, which midnight do you consider today's midnight for your purposes?