Best way to convert month int in month string + year - python

I'm trying to convert month int (1,2,...) into month string + year ("Jan 2020", "Feb 2020,...). So far, everything's going well. However, when I'm reaching 13, I would like to convert it to something like "Jan 2021"
Here is an example of what I'm trying to do (hard-coded)
I've tried to find the solution by myself but I think it's time to ask for help.
Is there a clean way to do it ? Thanks in advance !

You can use datetime module.
import datetime
def formated(year, month):
# datetime.date - class for date storing. It has useful method `strftime` for dates formating.
return datetime.date(year + (month - 1) // 12, (month - 1) % 12 + 1, 1).strftime("%b %Y")
print(formated(2020, 12))
# Dec 2020
print(formated(2020, 13))
# Jan 2021
print(formated(2020, 25))
# Jan 2022

import datetime
from dateutil import relativedelta
[datetime.datetime.strftime(datetime.date.today()+ relativedelta.relativedelta(months=i), "%b %Y") for i in range(13)]
Output:
['Feb 2021',
'Mar 2021',
'Apr 2021',
'May 2021',
'Jun 2021',
'Jul 2021',
'Aug 2021',
'Sep 2021',
'Oct 2021',
'Nov 2021',
'Dec 2021',
'Jan 2022',
'Feb 2022']
For the sake of simplicity I've taken datetime.date.today(). The dateutil module deals with months beyond 12

divmod can split a month into a year component (offset from 20200 and a month component. Since m == 1 should be January 2020, we'll subtract 1 from m, divide by 12, then add 1 back to the month. From this, we can create a datetime object whose strftime method can produce the desired string.
>>> from datetime import datetime
>>> m = 13 # Jan 2021
>>> year_offset, month = divmod(m-1, 12)
>>> datetime(2020 + year_offset, month + 1, 1).strftime("%b %Y")
'Jan 2021'
Note that the day argument doesn't really matter; it just has to be something valid for any month.
You can also add the "magic constant" 2019*12-1 to the month so that divmod returns the correct year immediately.
>>> m = 13 + 2019*12 - 1
>>> divmod(m, 12)
(2020, 0)
You still need to add one to the month.

Here is your solution:
month_names = [
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec",
]
number = int(input("Enter number: "))
if number != 0:
month = month_names[(number + 1) % 12]
year = number // 12 + 2020
print(month, year)
else:
print("Number can't be 0!")

Related

Converting a string month day, year to mm/dd/yyyy

I need to covert a string which contains date information (e.g., November 3, 2020) into date format (i.e., 11/03/2020).
I wrote
df['Date']=pd.to_datetime(df['Date']).map(lambda x: x.strftime('%m/%d/%y'))
where Date is
November 3, 2020
June 26, 2002
July 02, 2010
and many other dates, but I found the error ValueError: NaTType does not support strftime.
You can use pandas.Series.dt.strftime, which handles the NaT:
import pandas as pd
dates = ['November 3, 2020',
'June 26, 2002',
'July 02, 2010',
'NaT']
dates = pd.to_datetime(dates)
df = pd.DataFrame(dates, columns=['Date'])
df['Date'] = df['Date'].dt.strftime('%m/%d/%y')
Output:
Date
0 11/03/20
1 06/26/02
2 07/02/10
3 NaN

Python3: Convert arbitrary date to day of the week

I am trying to convert dates of the following format:
2007-10-18 11:31:46 -0400 (Thu, 18 Oct 2007)
or
Thu, 18 Oct 2007 11:31:49 -0400
to the day of the week. Even though the day is given in the above dates, but how can I extract the only day of the week from the above dates?
Is this too simple:
days = {
'mon': 'Monday',
'thu': 'Thursday',
# and the others
}
haystack = '2007-10-18 11:31:46 -0400 (Thu, 18 Oct 2007)'
for acronym, full_name in days.items():
if acronym in haystack.lower():
print(f"Found {full_name}")
days = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
date = "2007-10-18 11:31:46 -0400 (Thu, 18 Oct 2007)"
for d in days:
if d in date:
print(d)
You can use dateutil.parser to get a datetime object from a string:
from dateutil import parser
dt = parser.parse("2007-10-18 11:31:46 -0400")
# dt = datetime.datetime(2007, 10, 18, 11, 31, 46, tzinfo=tzoffset(None, -14400))
Then just use datetime.weekday. This will give you a number from 0 to 6, where 0 is the first day of the week relatively to your timezone, Monday by default.
dt.weekday
# 3, starting from 0 so it's Thursday

Print specific date in python

I want to create a function that will return a date depending on each month. More specific I want it to return to me the 23d day of each month in the example format (YYYY, MM, DD):
2018, 1, 23 .
except for the occasion that this date coincides with a weekend, in which I want it to return the exact previous working day. For example for December 2017 the 23d was Saturday, so in this case I want my function to return to me
2017, 12, 22.
Right now I use:
import datetime
someday = datetime.date(2018, 1, 23)
print(someday)
with which in the someday variable I define the desired date manually for each month.
In short for the next seven months of 2018 (January, February, March, April, May, June, July), I want my function to return to me :
2018, 1, 23
2018, 2, 23
2018, 3, 23
2018, 4, 23
2018, 5, 23
2018, 6, 22
2018, 7, 23
and so on and so forth for the next months.
You can achieve this with weekday(), timedelta() and while loop:
from datetime import date, timedelta
def last_workday(somedate):
while somedate.weekday() > 4: #weekday returns values 0-6 (Mon-Sun)
somedate -= timedelta(days=1) #timedelta returns 1 day which you subtract from your date
return somedate
y = 2018
d = 23
for m in range(1,13):
print(last_workday(date(y, m, d)))
I wrote a small python script on how you could do it.
Use toordinal to check for the day of the week and if it's Saturday or Sunday, subtract 1 or 2 by using timedelta
import datetime
# Yes, from 1,13 because 13 is exclusive (Goes only to 12)
days_month = datetime.monthrange(2018,x)
for x in range(days_month[0],days_month[1]+1):
for x in range(1, monthrange):
someday = datetime.date(2018, x, 23) # Loop over every month
weekday = someday.weekday() # 0 = Monday, 6 = Sunday
if(weekday > 5 ): # If it's "more" than Friday
jumpback_days = weekday - 4; # Subtract 4 from the current weekday to get 1 for Saturday and 2 for Sunday
print(someday - datetime.timedelta(days=jumpback_days)) # Subtract days and print
else:
# Print without subtracting anything
print(someday)
Note: If you are using Python2, please replace range with xrange for it to work.
EDIT: If you want to print only and all workdays in a specific year, you can do it this way:
import datetime
from calendar import monthrange
year = 2018
for month in range(1, 13): # Yes, from 1,13 because 13 is exclusive (Goes only to 12)
days_month = monthrange(year, month) # Request the amount of days in that month
for day in range(1, days_month[1] + 1): # Iterate through all days of that month (+1 because it's exclusive)
someday = datetime.date(year, month, day) # Loop over every month
weekday = someday.weekday() # 0 = Monday, 6 = Sunday
if(weekday < 5 ): # If it's "less" than Saturday
# Print because if it's "less" than Saturday, then it's a workday
print(someday)

convert element and next element in list of strings to date in python

I am new to Python and am having trouble with the following string:
Order now for free delivery loose on Tuesday, April 25 or set in
jewelry on Tuesday, April 29.
I have converted it to a list of strings with .split(). However, I cannot figure out how to iterate through the list to pull out the dates such as April 25 and April 29. Once I pull these strings out, I know I can convert them to a date format with datetime.strptime(string, '%B %d') with string being "April 25" and "April 29" and can apply a date-diff function.
I think I need to pull both list elements that contain month names as strings and the next element with the day of the month to combine them in order to convert them to date format.
Any assistance would be much appreciated. Thank you in advance.
Praise the power of regular expressions here:
import re
from datetime import datetime
s = "Order now for free delivery loose on Tuesday, April 25 or set in jewelry on Tuesday, April 29."
# regex looking for dates in the given format
rx = re.compile(r'''
(?:(?:Mon|Tues|Wednes|Thurs|Fri|Satur|Sun)day),\s+
(?:January|February|March|April|May|June|July|August|September|October|November|December)\s+
\d+
''', re.VERBOSE)
dates = [datetime.strptime("{} #{}".format(m.group(0), "2017"), '%A, %B %d #%Y')
for m in rx.finditer(s)]
print(dates)
# [datetime.datetime(2017, 4, 25, 0, 0), datetime.datetime(2017, 4, 29, 0, 0)]
If it's intended for the current 2017 year, the solution using calendar.day_name (the days of the week), calendar.month_name (the months of the year) and datetime.strptime() function:
import calendar, datetime
s = 'Order now for free delivery loose on Tuesday, April 25 or set in jewelry on Tuesday, April 29'
day_names = '|'.join(list(calendar.day_name)) # Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday
month_names = '|'.join(list(calendar.month_name[1:]))
dates = re.findall(r'((' + day_names + '), (' + month_names + ') \d{1,2})', s)
datetimes = [datetime.datetime.strptime(d[0] + ' 2017', '%A, %B %d %Y') for d in dates]
print(datetimes)
The output:
[datetime.datetime(2017, 4, 25, 0, 0), datetime.datetime(2017, 4, 29, 0, 0)]

Convert integer to dates in python

Is there aby way of converting integers of range(0,365) to dates (dtype='datetime64[D]')?
Eg:
0 -> 1 jan
1 -> 2 jan
.
.
31 -> 1 feb
.
.
364-> 31 dec
P.S: I don't need the year. Only date and month for a non-leap year.
As you have mentioned that you need the resultset for a non-leap year so create the datetime object with a non-leap year such as '2015'
from datetime import datetime, timedelta
for day_count in range(0, 365) :
curr_date_object = datetime.strptime('2015-01-01', '%Y-%m-%d') + timedelta(days=day_count)
print(curr_date_object.strftime("%d %b"))
This will return your desired result.
01 Jan
02 Jan
03 Jan
04 Jan
05 Jan
...
If you want the mapping to be in a dictionary, this is how it would look:
import datetime
In [35]: days = {}
In [36]: for i in range(0, 365):
...: days[i] = (datetime.datetime(2017, 1, 1) + datetime.timedelta(days=i)).strftime("%d %b")
...:
You'll get this:
In [37]: days
Out[37]:
{0: '01 Jan',
1: '02 Jan',
2: '03 Jan',
3: '04 Jan',
...

Categories

Resources