Python, format() function - python

Months={"01":"January","02":"February","03":"March","04":"April","05":"May","06":"June","07":"July","08":"August","09":"September","10":"October","11":"November","12":"December"}
date_time = lambda D: "{day} {month} {year} year {hour} hour"+"{p1} "+"{minute} minute"+"{p2}".format(day=str(int(D.split('.')[0])),month=Months[D.split('.')[1]],year=D.split('.')[2].split(' ')[0],hour=str(int(D.split(' ')[1].split(':')[0])),p1=''if D.split(' ')[1].split(':')[0]=='01' else 's',minute=str(int(D.split(' ')[1].split(':')[1])),p2=''if D.split(' ')[1].split(':')[1]=='01' else 's')
how it should work :
date_time("01.01.2000 00:00") == "1 January 2000 year 0 hours 0 minutes"
how it does work:
date_time("01.01.2000 00:00") == "{day} {month} {year} year {hour} hour{p1} {minute} minute{p2}"

If you must do it yourself, try f-strings?
MONTHS={1:"January", 2:"February", 3:"March", 4:"April", 5:"May", 6:"June", 7:"July", 8:"August", 9:"September", 10:"October", 11:"November", 12:"December"}
def format(day, month, year, hour, minute):
return f"{day} {MONTHS[month]} {year} {hour} hour{('s' if hour > 1 else '')} {minute} minute{('s' if minute > 1 else '')}"
Otherwise, Python has a builtin package called datetime which may be of use...

You're only calling format() on the last string "{p2"} because . has higher precedence than +. You need to put the concatenations in parentheses.
date_time = lambda D: ("{day} {month} {year} year {hour} hour"+"{p1} "+"{minute} minute"+"{p2}").format(day=str(int(D.split('.')[0])),month=Months[D.split('.')[1]],year=D.split('.')[2].split(' ')[0],hour=str(int(D.split(' ')[1].split(':')[0])),p1=''if D.split(' ')[1].split(':')[0]=='01' else 's',minute=str(int(D.split(' ')[1].split(':')[1])),p2=''if D.split(' ')[1].split(':')[1]=='01' else 's')
Although I don't understand why you're concatenating a bunch of literal strings. Just make it one long string.
date_time = lambda D: "{day} {month} {year} year {hour} hour{p1} {minute} minute{p2}".format(day=str(int(D.split('.')[0])),month=Months[D.split('.')[1]],year=D.split('.')[2].split(' ')[0],hour=str(int(D.split(' ')[1].split(':')[0])),p1=''if D.split(' ')[1].split(':')[0]=='01' else 's',minute=str(int(D.split(' ')[1].split(':')[1])),p2=''if D.split(' ')[1].split(':')[1]=='01' else 's')

It is better if you use Template from string.
# import Template
from string import Template
date = "01.01.2000 00:00"
day = date.split('.')[0]
month = date.split('.')[1]
year = date.split('.')[2].split(' ')[0]
p1 = date.split(' ')[1].split(':')[0]
p2 = date.split(':')[1]
Months={
"01":"January",
"02":"February",
"03":"March",
"04":"April",
"05":"May",
"06":"June",
"07":"July",
"08":"August",
"09":"September",
"10":"October",
"11":"November",
"12":"December"
}
# Creating Template
template = Template("$day $month $year year $hour hours $minute minutes")
# Using Template
date = template.substitute({
'day' : int(day),
'month' : Months[month],
'year' : year,
'hour' : int(p1),
'minute' : int(p2),
})
print(date) # 1 January 2000 year 0 hours 0 minutes

The datetime module exists for this purpose, use it!
from datetime import datetime
dt = datetime.strptime("01.01.2000 00:00", "%m.%d.%Y %H:%M")
print(dt.strftime("%-m %B %Y year %-H hours %-M minutes"))
Output:
1 January 2000 year 0 hours 0 minutes

Related

How to take months as inputs then determine start and end date for each month? I also want to go from Dec 2021 to April 2022

This is the code I have so far:
from calendar import isleap
import datetime
year =2021
month= 4
year2=2022
months_choices=[]
for i in range(1, 5):
month = datetime.date(2021, i, 1).strftime('%b')
startDate = f"01-Dec-{year}"
if month in ["Jan", "Mar", "May", "Jul", "Aug", "Oct", "Dec"]:
endDate = f"31-{month}-{year}"
elif month in ["Apr", "Jun", "Sep", "Nov"]:
endDate = f"30-{month}-{year}"
else:
isLeap = isleap(1900)
if isLeap:
endDate = f"29-{month}-{year}"
else:
endDate = f"28-{month}-{year}"
months_choices.append((startDate, endDate))
print(months_choices)
I would like my output to print as [('01-Dec-2021', '31-Dec-2021'), ('01-Jan-2022', '31-Jan-2022'), ('01-Feb-2022', '28-Feb-2022'), ('01-March-2021', '31-March-2021'),('01-April-2021', '30-Apr-2021')], but it prints like below.
print(months_choices)
[('01-Dec-2021', '31-Jan-2021'), ('01-Dec-2021', '28-Feb-2021'), ('01-Dec-2021', '31-Mar-2021'), ('01-Dec-2021', '30-Apr-2021')]
The calendar module has some very useful features that you could utilise.
As a starting point you would benefit from having a function that takes the start month/year and end month/year.
Something like this:
from calendar import monthrange, month_abbr
def range_ok(start_month, start_year, end_month, end_year):
if start_month < 1 or start_month > 12 or end_month < 1 or end_month > 12:
return False
if start_year > end_year or (start_year == end_year and start_month > end_month):
return False
return True
def func(start_month, start_year, end_month, end_year):
result = []
while range_ok(start_month, start_year, end_month, end_year):
mn = month_abbr[start_month]
d1 = f'01-{mn}-{start_year}'
sd = monthrange(start_year, start_month)[1]
d2 = f'{sd}-{mn}-{start_year}'
result.append((d1, d2))
if (start_month := start_month + 1) > 12:
start_month = 1
start_year += 1
return result
print(func(12, 2021, 4, 2022))
Output:
[('01-Dec-2021', '31-Dec-2021'), ('01-Jan-2022', '31-Jan-2022'), ('01-Feb-2022', '28-Feb-2022'), ('01-Mar-2022', '31-Mar-2022'), ('01-Apr-2022', '30-Apr-2022')]
EDIT
As requested in the comments, in order to generate the date range between two dates, the solution can be adjusted like this:
import pandas as pd
import calendar
from datetime import date
start_date = '2021-12-01'
end_date = '2022-04-30'
date_range = pd.date_range(start_date,end_date,
freq='MS').map(lambda x: (x.year, x.month)).tolist()
def get_dates(year, month):
return (date(year, month, 1).strftime("%d-%b-%Y"),
date(year,
month,
calendar.monthrange(year, month)[1]
).strftime("%d-%b-%Y"))
[get_dates(year, month)
for year, month in date_range]
Original solution
Use calendar.monthrange(YEAR, MONTH) to get the last day of the month. It handles the leap years for you.
import calendar
from datetime import date
years = [2021,2022]
months = [range(12, 13), range(1,5)]
def get_dates(year, month):
return (date(year, month, 1).strftime("%d-%b-%Y"),
date(year,
month,
calendar.monthrange(year, month)[1]
).strftime("%d-%b-%Y"))
[get_dates(year, month)
for year, month_range in zip(years, months)
for month in month_range]
Output:
[('01-Dec-2021', '31-Dec-2021'),
('01-Jan-2022', '31-Jan-2022'),
('01-Feb-2022', '28-Feb-2022'),
('01-Mar-2022', '31-Mar-2022'),
('01-Apr-2022', '30-Apr-2022')]

How do I find what the date will be next Sunday 12 am from now and then add 10 hours to it

I have this code
today = datetime.now().date()
# prints: 2022/1/14
rd = REL.relativedelta(days=1, weekday=REL.SU)
nextSunday = today + rd
#prints : 2022/1/16
How do i add 10 hours to the date so i can get a variable nextSunday_10am that i can substract to the current time
difference = nextSunday_10am - today
and schedule what I need to do
You can do the same thing as suggested by #Dani3le_ more directly with the following:
def getSundayTime(tme: datetime.date) -> datetime:
nxt_sndy = tme + timedelta(days= 6 - tme.weekday())
return datetime.combine(nxt_sndy, datetime.strptime('10:00', '%H:%M').time())
This will compute calculate the next Sunday and set time to 10:00
You can add hours to a DateTime by using datetime.timedelta().
nextSunday += datetime.timedelta(hours=10)
For example:
import datetime
today = datetime.datetime.today()
print("Today is "+str(today))
while today.weekday()+1 != 6: #0 = "Monday", 1 = "Tuesday"...
today += datetime.timedelta(1)
nextSunday = today + datetime.timedelta(hours=10)
print("Next sunday +10hrs will be "+str(nextSunday))

Getting dates in python between a past datestamp and the present

Language Python
I am wondering if anyone can help me print out some dates.
i cam trying to create a loop in which i pass in a date say 01/1/2017 and the loop will then output the first and last day in every month between then and the present day.
Example
01/01/2017
31/01/2017
01/02/2017
28/02/2017
etc
Any help will be appreciated
Hope this will help,
Code:
from datetime import date
from dateutil.relativedelta import relativedelta
from calendar import monthrange
d1 = date(2018, 2, 26)
d2 = date.today()
def print_month_day_range(date):
first_day = date.replace(day = 1)
last_day = date.replace(day = monthrange(date.year, date.month)[1])
print (first_day.strftime("%d/%m/%Y"))
print (last_day.strftime("%d/%m/%Y"))
print_month_day_range(d1)
while (d1 < d2):
d1 = d1 + relativedelta(months=1)
print_month_day_range(d1)
Output:
01/02/2018
28/02/2018
01/03/2018
31/03/2018
...
01/07/2018
31/07/2018
you can use calendar module. Below is the code:
import datetime
from calendar import monthrange
strt_date = '01/1/2017'
iter_year = datetime.datetime.strptime(strt_date, '%m/%d/%Y').year
iter_month = datetime.datetime.strptime(strt_date, '%m/%d/%Y').month
cur_year = datetime.datetime.today().year
cur_month = datetime.datetime.today().month
while cur_year > iter_year or (cur_year == iter_year and iter_month <= cur_month):
number_of_days_in_month = monthrange(iter_year, iter_month)[1]
print '/'.join([str(iter_month) , '01', str(iter_year)])
print '/'.join([str(iter_month), str(number_of_days_in_month), str(iter_year)])
if iter_month == 12:
iter_year += 1
iter_month = 1
else:
iter_month += 1
this could work, as long as the first date you give is always the first of the month
from datetime import datetime
from datetime import timedelta
date_string = '01/01/2017'
date = datetime.strptime(date_string, '%d/%m/%Y').date()
today = datetime.now().date()
months = range(1,13)
years = range(date.year, today.year + 1)
for y in years:
for m in months:
new_date = date.replace(month=m, year=y)
last_day = new_date - timedelta(days=1)
if (date < new_date) & (new_date <= today):
print last_day.strftime('%d/%m/%Y')
print new_date.strftime('%d/%m/%Y')
elif (date <= new_date) & (new_date <= today):
print new_date.strftime('%d/%m/%Y')
This code would print the first and last days of all months in a year.
Maybe add some logic to iterate through the years
import datetime
def first_day_of_month(any_day):
first_month = any_day.replace(day=1)
return first_month
def last_day_of_month(any_day):
next_month = any_day.replace(day=28) + datetime.timedelta(days=4)
return next_month - datetime.timedelta(days=next_month.day)
for month in range(1, 13):
print first_day_of_month(datetime.date(2017, month, 1))
print last_day_of_month(datetime.date(2017, month, 1))

Count summer days between two dates

I want to count summer days between two dates. Summer is May first to August last.
This will count all days:
import datetime
startdate=datetime.datetime(2015,1,1)
enddate=datetime.datetime(2016,6,1)
delta=enddate-startdate
print delta.days
>>517
But how can only count the passed summer days?
You could define a generator to iterate over every date between startdate and enddate, define a function to check if a date represents a summer day and use sum to count the summer days:
import datetime
startdate = datetime.datetime(2015,1,1)
enddate = datetime.datetime(2016,6,1)
all_dates = (startdate + datetime.timedelta(days=x) for x in range(0, (enddate-startdate).days))
def is_summer_day(date):
return 5 <= date.month <= 8
print(sum(1 for date in all_dates if is_summer_day(date)))
# 154
Thanks to the generator, you don't need to create a huge list in memory with every day between startdate and enddate.
This iteration still considers every single day, even if it's not needed. For very large gaps, you could use the fact that every complete year has 123 summer days according to your definition.
You can create a few functions to count how many summer days you have between two days:
from datetime import date
def get_summer_start(year):
return date(year, 5, 1)
def get_summer_end(year):
return date(year, 8, 31)
def get_start_date(date, year):
return max(date, get_summer_start(year))
def get_end_date(date, year):
return min(date, get_summer_end(year))
def count_summer_days(date1, date2):
date1_year = date1.year
date2_year = date2.year
if date1_year == date2_year:
s = get_start_date(date1, date1_year)
e = get_end_date(date2, date1_year)
return (e - s).days
else:
s1 = max(date1, get_summer_start(date1_year))
e1 = get_summer_end(date1_year)
first_year = max(0,(e1 -s1).days)
s1 = get_summer_start(date2_year)
e1 = min(date2, get_summer_end(date2_year))
last_year = max(0,(e2 -s2).days)
other_years = date2_year - date1_year - 1
summer_days_per_year = (get_summer_end(date1_year) - get_summer_start(date1_year)).days
return first_year + last_year + (other_years * summer_days_per_year)
date1 = date(2015,1,1)
date2 = date(2016,6,1)
print count_summer_days(date1, date2)
Here is a better solution for large periods:
first_summer_day = (5,1)
last_summer_day = (8,31)
from datetime import date
startdate = date(2015,1,1)
enddate = date(2016,6,1)
# make sure that startdate > endate
if startdate > enddate:
startdate, endate = endate, startdate
def iter_yearly_summer_days(startdate, enddate):
for year in range(startdate.year, enddate.year+1):
start_period = startdate if year == startdate.year else date(year, 1, 1)
end_period = enddate if year == enddate.year else date(year, 12, 31)
year_first_summer_day = date(year, *first_summer_day)
year_last_summer_day = date(year, *last_summer_day)
summer_days_that_year = (min(year_last_summer_day, end_period) - max(year_first_summer_day, start_period)).days
print('year {} had {} days of summer'.format(year, summer_days_that_year))
yield summer_days_that_year
print(sum(iter_yearly_summer_days(startdate, enddate)))

Django built-in timesince filter to show only Days

I am using {{ prospect.date_1 }} - ({{ prospect.date_1|timesince }} ago) in my template to get time since the date.
The point is, date_1 is a date not datetime, so when i apply the filter it tells me like
July 18, 2014 - (11 hours, 39 minutes ago)
expected output
July 18, 2014 - (0 days ago)
taken from naturalday
#register.filter(expects_localtime=True)
def days_since(value, arg=None):
try:
tzinfo = getattr(value, 'tzinfo', None)
value = date(value.year, value.month, value.day)
except AttributeError:
# Passed value wasn't a date object
return value
except ValueError:
# Date arguments out of range
return value
today = datetime.now(tzinfo).date()
delta = value - today
if abs(delta.days) == 1:
day_str = _("day")
else:
day_str = _("days")
if delta.days < 1:
fa_str = _("ago")
else:
fa_str = _("from now")
return "%s %s %s" % (abs(delta.days), day_str, fa_str)
results
>>> days_since(datetime.now())
'0 days ago'
>>> days_since(date(2013, 5, 12))
'432 days ago'
>>> days_since(date(2014, 12, 12))
'147 days from now'
>>> days_since(date(2014, 7, 19))
'1 day from now'
#Jack, Have you tried to use in-built python:
Visit: https://docs.python.org/2/library/datetime.html#datetime.datetime.day
Also if this might help:
https://docs.djangoproject.com/en/1.6/ref/contrib/humanize/#naturaltime
Edit:
from datetime import date
from datetime import datetime
d = date.today()
datetime.combine(d, datetime.min.time())

Categories