Excel:Next year period - excel

How to get next year period based on current month and year, for example:
Jan 2014 - Dec 2014
Feb 2014 - Jan 2015
Mar 2014 - Feb 2015
Apr 2014 - Mar 2015
May 2014 - Apr 2015
Jun 2014 - May 2015
Jul 2014 - Jun 2015
Aug 2014 - Jul 2015
Sep 2014 - Aug 2015
Oct 2014 - Sep 2015
Nov 2014 - Oct 2015
Dec 2014 - Nov 2015
Next period
Jan 2015 - Dec 2015
Feb 2015 - Jan 2016
etc.
I have tried with the following formula:
=UPPER(TEXT(NOW();"MMM")) &" "& TEXT(NOW();"YY")-1
It works fine for Jan 2014 but can't figure out how to get Dec 2014; Feb 2014 - Jan 2015 and so on?

I think you need the EOMonth formula.
=EOMONTH(NOW(),-13) +1 and =EOMONTH(NOW(),-2) +1 should give give you JAN 2014 to DEC 2014
from the MS Excel documentation
Microsoft Excel stores dates as sequential serial numbers so they can
be used in calculations. By default, January 1, 1900 is serial number
1, and January 1, 2008 is serial number 39448 because it is 39,448
days after January 1, 1900.
To get the text formatting you are after, I would suggest that you stick with formatting the cell/column as #Makyen has suggested. Having said that this is the formula that you can use to format the text.
=UPPER(TEXT(EOMONTH(NOW(),-13) +1, "MMM YY"))

Assuming that the date (as a date serial number) for which you desire to find the year period is in cell A1, the following should provide the next year period starting from that day:
=EOMONTH(A1,11) +DAY(A1) -1
Examples:
Input Output
1/18/2014 1/17/2015
2/18/2014 2/17/2015
3/18/2014 3/17/2015
4/18/2014 4/17/2015
5/18/2014 5/17/2015
6/18/2014 6/17/2015
7/18/2014 7/17/2015
8/18/2014 8/17/2015
9/18/2014 9/17/2015
10/18/2014 10/17/2015
11/18/2014 11/17/2015
12/18/2014 12/17/2015
1/18/2015 1/17/2016
2/18/2015 2/17/2016
3/18/2015 3/17/2016
4/18/2015 4/17/2016
5/18/2015 5/17/2016
6/18/2015 6/17/2016
7/18/2015 7/17/2016
8/18/2015 8/17/2016
9/18/2015 9/17/2016
10/18/2015 10/17/2016
11/18/2015 11/17/2016
12/18/2015 12/17/2016
1/18/2016 1/17/2017
If you want the year period to start from the current day:
=EOMONTH(NOW(),11) + DAY(NOW()) -1
If you want the year period to start from the first day of the current month:
=EOMONTH(EOMONTH(NOW(),-1) + 1,11)
or
=EOMONTH(NOW() - DAY(NOW()) + 1,11)
The EOMONTH() function:
EOMONTH(start_date,months)
Returns the serial number for the last day of the month that is the
indicated number of months before or after start_date. Use EOMONTH to
calculate maturity dates or due dates that fall on the last day of the
month.
If this function is not available, and returns the #NAME? error,
install and load the Analysis ToolPak add-in.

Related

Web scraping a table from dynamic website (Python)

I am fairly new to web scraping and decided to dive straight into the deep end. I want select any product and "all months" in a dropdown above the table from https://www.cmegroup.com/tools-information/quikstrike/options-calendar.html and extract the table data into a scv file. The problem araises because the website is dynamic (not all HTML code is displayed when clicking inspect sourse in browser) and generates the table in css (from what i managed to understand). I tried using Selenium to load the webpage, but I am getting an error.
[12508:8412:0216/220631.827:ERROR:ssl_client_socket_impl.cc(985)] handshake failed; returned -1, SSL error code 1, net_error -101
I am assuming this has to do with the webdriver initialisation and I need to give it some settings, just not sure which ones.
Here is the code:
from selenium import webdriver
from bs4 import BeautifulSoup
# Set up the Selenium driver
driver = webdriver.Chrome()
# Open the webpage
url = 'https://www.cmegroup.com/tools-information/quikstrike/options-calendar.html'
driver.get(url)
# Render the page and extract the HTML code
html = driver.page_source
# Parse the HTML using BeautifulSoup
soup = BeautifulSoup(html, 'html.parser')
# Extract the data you want from the soup object
tables = soup.findAll("table")
print(tables)
# Close the Selenium driver
driver.quit()
I have tried going the short route and reproducing the requests made by the browser and catching the response with the HTML code (yes the request only returns HTML, not JSON), but this backfired as I couldnt reproduce payload. How do I get the data from the calendar?
The <table> element is within an <iframe> so to access/print the <table> contents you have to:
Induce WebDriverWait for the desired frame to be available and switch to it.
Induce WebDriverWait for the visibility_of_element_located.
You can use either of the following locator strategies:
driver.get('https://www.cmegroup.com/tools-information/quikstrike/options-calendar.html')
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button#onetrust-accept-btn-handler"))).click()
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"//iframe[#class='cmeIframe']")))
print(WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.XPATH, "//div[#class='ui-widget-info clearfix']/table//tbody[not(#class)][.//tr[#class='group compact']]"))).text)
Console output:
FEBRUARY 2023
FIRST AVAIL DATE OPTION EXPIRATION DTE PRODUCT OPTION FUTURE FUTURE EXPIRATION DTE
20 Jan 2023 - Fri 17 Feb 2023 - Fri 1 Natural Gas Weekly Financial Option Week 3 LN3G3 NGH3 24 Feb 2023 - Fri 8
24 Nov 2010 - Wed 23 Feb 2023 - Thu 7 Natural Gas Option (European) LNEH3 NGH3 24 Feb 2023 - Fri 8
27 Jan 2023 - Fri 24 Feb 2023 - Fri 8 Natural Gas Weekly Financial Option Week 4 LN4G3 NGJ3 29 Mar 2023 - Wed 41
MARCH 2023
FIRST AVAIL DATE OPTION EXPIRATION DTE PRODUCT OPTION FUTURE FUTURE EXPIRATION DTE
03 Feb 2023 - Fri 03 Mar 2023 - Fri 15 Natural Gas Weekly Financial Option Week 1 LN1H3 NGJ3 29 Mar 2023 - Wed 41
10 Feb 2023 - Fri 10 Mar 2023 - Fri 22 Natural Gas Weekly Financial Option Week 2 LN2H3 NGJ3 29 Mar 2023 - Wed 41
21 Feb 2023 - Tue 17 Mar 2023 - Fri 29 Natural Gas Weekly Financial Option Week 3 LN3H3 NGJ3 29 Mar 2023 - Wed 41
27 Feb 2023 - Mon 24 Mar 2023 - Fri 36 Natural Gas Weekly Financial Option Week 4 LN4H3 NGJ3 29 Mar 2023 - Wed 41
24 Nov 2010 - Wed 28 Mar 2023 - Tue 40 Natural Gas Option (European) LNEJ3 NGJ3 29 Mar 2023 - Wed 41
06 Mar 2023 - Mon 31 Mar 2023 - Fri 43 Natural Gas Weekly Financial Option Week 5 LN5H3 NGK3 26 Apr 2023 - Wed 69
APRIL 2023
FIRST AVAIL DATE OPTION EXPIRATION DTE PRODUCT OPTION FUTURE FUTURE EXPIRATION DTE
13 Mar 2023 - Mon 06 Apr 2023 - Thu 49 Natural Gas Weekly Financial Option Week 1 LN1J3 NGK3 26 Apr 2023 - Wed 69
20 Mar 2023 - Mon 14 Apr 2023 - Fri 57 Natural Gas Weekly Financial Option Week 2 LN2J3 NGK3 26 Apr 2023 - Wed 69
27 Mar 2023 - Mon 21 Apr 2023 - Fri 64 Natural Gas Weekly Financial Option Week 3 LN3J3 NGK3 26 Apr 2023 - Wed 69
24 Nov 2010 - Wed 25 Apr 2023 - Tue 68 Natural Gas Option (European) LNEK3 NGK3 26 Apr 2023 - Wed 69
03 Apr 2023 - Mon 28 Apr 2023 - Fri 71 Natural Gas Weekly Financial Option Week 4 LN4J3 NGM3 26 May 2023 - Fri 99
Note : You have to add the following imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
Reference
You can find a couple of relevant discussions in:
Switch to an iframe through Selenium and python
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element while trying to click Next button with selenium
selenium in python : NoSuchElementException: Message: no such element: Unable to locate element

Splitting datetime value out of text string with uneven length

System: WIN10
IDE: MS Visual Studio COde
Language: Python version 3.7.3
Library: pandas version 1.0.1
Data source: supplied in the example below
Dataset: supplied in the example below
Ask:
I need to split the date and time string out of a column from a data frame that has rows of uneven delimiters i.e. some with three and some with four commas.
I am trying to figure out how to strip the date and time values: 'Nov 11 2013 12:00AM', and 'Apr 11 2013 12:00AM' respectively off the back of these two records in one column into a new column given the second row in the example below has fewer commas.
Code:
df['sample field'].head(2) 
4457-I need, this, date, Nov 11 2013 12:00AM ,
2359-I need this, date, Apr 11 2013 12:00AM , 
While the below method expands the data into different columns and staggers which column houses the date, this does not work. I need the date and time (or even just date) information in one column so that I can use the date values in further analysis (for example time-series).
Code:
df['sample field'].str.split(",", expand=True)
Data
df=pd.DataFrame({'Text':['4457-I need, this, date, Nov 11 2013 12:00AM ,','2359-I need this, date, Apr 11 2013 12:00AM ,']})
df
Use df.extract with a regex epression
df['Date']= df.Text.str.extract('([A-Za-z]+\s+\d+\s+\d+\s+\d+:[0-9A-Z]+(?=\s+\,+))')
df
#df.Date=pd.to_datetime(df.Date).dt.strftime('%b %d %Y %H:%M%p')
#df['date'] = pd.to_datetime(df['date'] ,format='%b %d %Y %H:%M%p')
df['Date']=pd.to_datetime(df['Date'])#This or even df['Date']=pd.to_datetime(df['Date'], format=('%b %d %Y %I:%M%p')) could work. Just remmeber because your time is 12AM use 12 clock hour system %I not %H and also hour 00.00 likely to be trncated, If have say11.00AM, the time will appear
IIUC you need str.extract with a regular expression.
Regex Demo Here
print(df)
0
0 4457-I need, this, date, Nov 11 2013 12:00AM
1 2359-I need this, date, Apr 11 2013 12:00AM
df['date'] = df[0].str.extract('(\w{3}\s\d.*\d{4}\s\d{2}:\d{2}\w{2})')
df['date'] = pd.to_datetime(df['date'] ,format='%b %d %Y %H:%M%p')
print(df)
0 date
0 4457-I need, this, date, Nov 11 2013 12:00AM 2013-11-11 12:00:00
1 2359-I need this, date, Apr 11 2013 12:00AM 2013-04-11 12:00:00
I'll use #wwnde's data :
df=pd.DataFrame({'Text':['4457-I need, this, date, Nov 11 2013 12:00AM ,','2359-I need this, date, Apr 11 2013 12:00AM ,']})
df['Date'] = df.Text.str.strip(',').str.split(',').str[-1].str.strip()
df['Date_formatted'] = pd.to_datetime(df.Date, format = '%b %d %Y %H:%M%p')
Text Date Date_formatted
0 4457-I need, this, date, Nov 11 2013 12:00AM , Nov 11 2013 12:00AM 2013-11-11 12:00:00
1 2359-I need this, date, Apr 11 2013 12:00AM , Apr 11 2013 12:00AM 2013-04-11 12:00:00

Is it possible to convert date/time in Excel such as "Mon Nov 11 2019 22:12:22"?

Is it possible to convert a date/time in Excel such as Mon Nov 11 2019 22:12:22 UTC time to and EST date/time value? Essentially subtract 5 hours from it? Some of the formulas I've been playing with are:
=C2-5/24
=(SUBSTITUTE(LEFT(A1,27),"T"," "))+(MID(A1,28,3)/24)

How take from string the words I need?

I have many strings like these.
Roliffe (Day) - Thursday, 15 June 2019
Tadcorp Pk Munangle (Day) - Tuesday, 10 July 2019
Gecester Park (Night) - Friday, 26 June 2019
I need to take names for example Roliffe, Tadcorp Pk Munangle, Gecester Park
And dates 15 June 2019, 10 July 2019, 26 June 2019
How can I make it?
I would use regular expressions like this:
import re
string = """Roliffe (Day) - Thursday, 15 June 2019
Tadcorp Pk Munangle (Day) - Tuesday, 10 July 2019
Gecester Park (Night) - Friday, 26 June 2019"""
places = re.findall(r'([\w ]*) \(.*\)', string)
dates = re.findall(r'\d{2} \w* \d{4}', string)
print(', '.join(places))
print(', '.join(dates))
Output
Roliffe, Tadcorp Pk Munangle, Gecester Park
15 June 2019, 10 July 2019, 26 June 2019
If the data follows the same pattern.
This will not be an efficient one but will work.
s = 'Roliffe (Day) - Thursday, 15 June 2019';
firstSplit = s.split('(');
name = firstSplit[0].trim();
date = firstSplit[1].split(',')[1].trim();

Why Sorting the timestamp using sort_values is not working?

I have a column of timestamp converted to human readable form.
I have tried to sort it from epochtime as well as after converting. It's giving me
Fri, 08 Feb 2019 17:24:16 IST
Mon, 11 Feb 2019 02:19:40 IST
Sat, 09 Feb 2019 00:22:43 IST
which is not sorted.
I have used sort_values()
each_tracker_df = each_tracker_df.sort_values(["timestamp"],ascending=True)
why it isn't working??
Since all the time is in IST. Replace the string IST with NULL.
>>import datetime
>>times=['Fri, 10 Feb 2010 17:24:16','Fri, 11 Feb 2010 17:24:16','Fri, 11 Feb 2019 17:24:16']
>>change_format=[]
>> for time in times:
change_format.append(datetime.datetime.strptime(time, '%a, %d %b %Y %H:%M:%S'))
>>change_format.sort()

Resources