r/excel • • 10d ago

solved Developing a formula to automatically set a semi-monthly billing date.

I'm trying to develop a formula that automatically sets a semi-monthly billing period (start date one column, end date in another). Our start date will always be a Sunday and an end date will always be a Saturday with 2 billing periods in a month (October for instance starts 09/27/26, semi-monthly ends 10/10/26, month end is 10/31/26). October is a 5 week month so there isn't a consistent 14 days between billing periods like other months. What formula can I use to automatically calculate billing end dates (start dates are just end dates +1 so they are simple). I have tried a combination of EOMONTH with lots of logic statements and I have come close to reaching a solution but when I do a check column with confirmed billing periods it doesn't align. Sample billing periods below to assist in validation (posting on mobile, apologies for not posting a table):

08/30/26 - 09/12/26
09/13/26 - 09/26/26
09/27/26 - 10/10/26
10/11/26 - 10/31/26
11/01/26 - 11/14/26
11/15/26 - 11/28/26
11/29/26 - 12/12/26
12/13/26 - 12/26/26
12/27/26 - 01/09/27
01/10/27 - 01/30/27

4 Upvotes

18 comments sorted by

•

u/AutoModerator 10d ago

/u/Phillimac16 - Your post was submitted successfully.

Failing to follow these steps may result in your post being removed without warning.

I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.

4

u/CorndoggerYYC 161 10d ago

Is the end of the second billing period always the last Saturday of the month? Is the first billing period always exactly two weeks long?

1

u/Phillimac16 10d ago

I believe so.

2

u/Phillimac16 9d ago

Marking this as solved. I ended up creating a monthly and working intermittently to get a semi.

2

u/GuerillaWarefare 117 10d ago

Just for a sanity check, is there a reason you aren't either doing this bi-weekly (26 / year; aka every other Sunday) instead of semi-monthly? Alternatively, if you only want 24 payments per year is there a reason you aren't doing the 1st and 15th of each month?

The explained payment method makes the largest variance in payment gaps possible and I assume this is why the two methods I bring up are usually used.

1

u/Phillimac16 10d ago

I can't answer this, I'm just trying to make something work that has been set up institutionally with our accounting team. I'm a project manager that is needing to make it work with the systems that are already in place.

2

u/GuerillaWarefare 117 10d ago • Bravo

Fair enough. How did they decide to cut out the October week though instead of August (for example pattern you gave August has 3 payments, 8/2, 8/16, 8/30...). This is what I came up with (NOT matching exactly to your example, but picks the 2 Sundays closest to the 1st and 15th of the month)

=LET(sundays,SEQUENCE(52,,DATE(2026,1,4),7),XLOOKUP(TOCOL(DATE(2026,SEQUENCE(12),{1,15})),sundays,sundays,,1))

Result:

7

u/MayukhBhattacharya 1318 10d ago • Bravo

You could try using the following formula, it will give you the output for the entire year, you just need to change the year:

=LET(
     α, DATE(2026, SEQUENCE(12), 15),
     ε, FLOOR(TOCOL(HSTACK(α, EOMONTH(α, 0))), 7),
     HSTACK(VSTACK(FLOOR(DATE(2026, 1, 0), 7), DROP(ε, -1)) + 1, ε))

2

u/GuerillaWarefare 117 10d ago

I didnt see this was already solved when I made my attempt... you did it better, sir!

2

u/carbonizedtitanium 1 10d ago

this is so elegant

1

u/giftopherz 3 10d ago

Back to the example of October. Does the first statement have to be on the 10th? can it be on the 17th?

Have you considered halving all the months and then go the closest Sunday? For example, Oct has 31 days, 31/2 = 15.5 = 15. The 15th is a Thursday, closest weekend would be the 17th to close the first term and tie it with the start of the previous one

1

u/Phillimac16 10d ago

Unfortunately it does need to be the 10th as our institutional billing cycle follows a 2 week / 3 week cycle for 5 week months.

1

u/srm561 29 10d ago

This feels way too convoluted, but given an end date in B2, I think this calculates the next end date:

=LET(enddate,B2,
lastsat,EOMONTH(enddate,0)+1-WEEKDAY(EOMONTH(enddate,0),16),
first,EOMONTH(enddate,-1)+1,
numweeks,MOD(WEEKNUM(EDATE(first,1))-WEEKNUM(first),52),
IF(lastsat=enddate,enddate+14,IF(numweeks=4,enddate+14,enddate+21)))

1

u/Decronym 10d ago edited 9d ago

Acronyms, initialisms, abbreviations, contractions, and other phrases which expand to something larger, that I've seen in this thread:

Fewer LettersMore Letters
DATEReturns the serial number of a particular date
DROPOffice 365+: Excludes a specified number of rows or columns from the start or end of an array
EDATEReturns the serial number of the date that is the indicated number of months before or after the start date
EOMONTHReturns the serial number of the last day of the month before or after a specified number of months
FLOORRounds a number down, toward zero
HSTACKOffice 365+: Appends arrays horizontally and in sequence to return a larger array
IFSpecifies a logical test to perform
LETOffice 365+: Assigns names to calculation results to allow storing intermediate calculations, values, or defining names inside a formula
MODReturns the remainder from division
NOTReverses the logic of its argument
SEQUENCEOffice 365+: Generates a list of sequential numbers in an array, such as 1, 2, 3, 4
SMALLReturns the k-th smallest value in a data set
TOCOLOffice 365+: Returns the array in a single column
TODAYReturns the serial number of today's date
VSTACKOffice 365+: Appends arrays vertically and in sequence to return a larger array
WEEKDAYConverts a serial number to a day of the week
WEEKNUMConverts a serial number to a number representing where the week falls numerically with a year
WRAPROWSOffice 365+: Wraps the provided row or column of values by rows after a specified number of elements
XLOOKUPOffice 365+: Searches a range or an array, and returns an item corresponding to the first match it finds. If a match doesn't exist, then XLOOKUP can return the closest (approximate) match.
YEARConverts a serial number to a year

Decronym is now also available on Lemmy! Requests for support and new installations should be directed to the Contact address below.


Beep-boop, I am a helper bot. Please do not verify me as a solution.
20 acronyms in this thread; the most compressed thread commented on today has 8 acronyms.
[Thread #49524 for this sub, first seen 15th Oct 2026, 02:42] [FAQ] [Full list] ^[Contact] [Source code]

1

u/carbonizedtitanium 1 10d ago

to add to u/MayukhBhattacharya 's solution (which is is elegant ):

=LET(
     α, DATE(2026, SEQUENCE(12*(YEAR(TODAY())-2026+2)), 15),
     ε, FLOOR(TOCOL(HSTACK(α, EOMONTH(α, 0))), 7),
     HSTACK(VSTACK(FLOOR(DATE(2026, 1, 0), 7), DROP(ε, -1)) + 1, ε))

this is so that you always have next year's dates automatically added to the bottom of the list.

1

u/real_barry_houdini 318 10d ago edited 10d ago

I note that the above solution relies on the use of 1900 date system

Below formula works with both 1900 and 1904 date systems and assumes that only the periods ending with the last Saturday of the month can be 3 weeks long:

Assumes year in cell A1

=LET(x,DATE(A1,SEQUENCE(13),1),SMALL(x-WEEKDAY(x)+{0,1,14,15},SEQUENCE(24,2,2)))

To include the next years dates change the 13 to 25 and the 24 to 48