g | x | w | all
Bytes Lang Time Link
075Ruby250531T085148ZValue In
280Python3250528T153943ZAjax1234
11605AB1E250528T141955ZKevin Cr
181Bash with GNU date250527T145032ZToby Spe
095JavaScript Node.js250527T124803Zl4m2

Ruby, 137 97 75 bytes

Uses the -rdate flag to auto-import the Date library. Input is a Date object, output is a string Date object representing the day of the party. Assumes your coworker doesn't need to wait a year to throw a party. Assumes input date has a positive year (aka not BC/BCE) because the Gregorian calendar wasn't adopted until 1582. Takes a while to run for two reasons:

  1. In order to ensure 2/29 is accounted for, I check every date from the input to 3000 days in the future (since leap years are every 4 years but skipped every 100 years, I figure you should definitely get one within \$365*8=2920\$ days) because it saves bytes over a sane option like (D.new(4)..D.new(5)) that covers only 366 days.
  2. The shortest way to grab the latest future date is to simply check every year ever starting from year 1 and stopping at the first one whose relevant date is after the input and on a weekday. (d.year..) would be more sane but that's five whole bytes wasted. This is repeated for all 3000 dates checked.

-40 bytes (!!) by figuring out I can apply a block to uniq to make it remove duplicated valid dates, eliminating my insane weird method of looking at 3k dates just for their month and day just to make sure February 29 is included, then finding the first valid year for that date, even though most of the month/day combinations would be redundantly checked many, many times and running thousands of unnecessary calculations in the name of saving bytes.

-7 bytes by realizing I no longer need D=Date; as I am no longer creating fresh Date objects in my code.

-15 bytes by leveraging the flexible output requirements that state that any date can be returned as long as the month/date are correct.

->d{(d..d+9e3).select{(1..5)===_1.wday}.uniq{[_1.mon,_1.day]}.max_by{_1-d}}

Attempt This Online!

Python3, 280 bytes

Assumes that worker 1 must wait at least 1 year before throwing a party.

import datetime as D
def f(n):
 d,v=D.date(*n),[]
 for i in range(1,13):
  for I in range(1,[[32,31][i in[4,6,9,11]],30][i==2]):
   Y=n[0]
   while 1:
    try:
     if(L:=D.date(Y:=Y+1,i,I)).weekday()<5:v+=[L];break
    except:1
 return(M:=max(v,key=lambda x:x-d)).month,M.day,M-d

Try it online!

05AB1E, 116 bytes

V[¯Ùg366Q#Y`т‰0Kθ4ÖUD<i\28X+ë<7%É31α}‹iY¬>0ëY1¾ǝDÅsD12‹i>1ë\1Dǝ¤>2}}ǝVY`UD3‹©12*+>₂*T÷®Xα©т%D4÷®т÷©4÷®·(O7%2@iY¨ˆ]¯θ

Port of the approach used in @l4m2's JavaScript answer, so make sure to upvote that answer as well!

Input as a triplet \$[dd,MM,yyyy]\$; output as a pair \$[dd,MM]\$.

No TIO, since it'll time-out.
I've ran the test cases locally on my PC, and the first test case still doesn't have a result after 30 minutes (likely because of the 4k+ items in the global array that will be uniquified every iteration). The other three test cases take about 5 minutes each, so here is a screenshot of those:

enter image description here

Explanation:

V          # Store the (implicit) input-triplet in variable `Y`
[          # Start an infinite list:
 ¯         #  Push the global array (initially empty)
  Ù        #  Uniquify it
   g       #  Pop and push its length, to get the amount of distinct items
    366Q   #  If this length equal 366:
        #  #   Stop the infinite loop
 Y`т‰0Kθ4ÖUD<i\28X+ë<7%É31α}‹iY¬>0ëY1¾ǝDÅsD12‹i>1ë\1Dǝ¤>2}}ǝV
           #  Change `Y` to the next day
 Y`UD3‹©12*+>₂*T÷®Xα©т%D4÷®т÷©4÷®·(O7%2@
           #  Check if date `Y` is a weekday
   i       #  Pop this check, and if it's truthy:
    Y      #   Push date `Y`
     ¨     #   Remove its trailing year
       ˆ   #   Pop and add this [dd,MM]-pair to the global array
]          # Close both the if-statement and infinite loop
 ¯θ        # Push the last [dd,MM]-pair of the global array
           # (which is output implicitly as result)

Both going to the next day Y`т‰0Kθ4ÖUD<i\28X+ë<7%É31α}‹iY¬>0ëY1¾ǝDÅsD12‹i>1ë\1Dǝ¤>2}}ǝV and the weekday check Y`UD3‹©12*+>₂*T÷®Xα©т%D4÷®т÷©4÷®·(O7%2@ are taken from my 05AB1E answer for The Work Day Countdown challenge. A full explanation of these code-snippets can be found in that answer.

Bash with GNU date, 181 bytes

Requires an English locale (or indeed any locale where Saturday and Sunday but no others begin with S). Input is any date date (e.g. today)

a(){ date -f- +%F\ %a|sed /S/d\;q;}
(printf "$1+%dyear+307day\n" {0..12}|date -f- +%Y-02-29|a
for i in {1..7}day
do printf "$1-$i+%dyear\n" {1..3}|a
done)2>/dev/null|sort|sed '$!d'

The function a selects the first non-weekend date from its input stream. We apply this to the next three leap days and the next three of each day of the preceding week (which may include a leap day), and choose the latest from these.

Demo

Using examples from the question:

$ for i in '1 Mar 1892' '2/28/24' 'May 26, 2025' '2100-02-25'; do ./282005.sh "$i"; done
1904-02-29 Mon
2027-02-22 Mon
2028-05-23 Tue
2104-02-29 Fri

JavaScript (Node.js), 95 bytes

x=>{for(e=new Set;e.size<366;t[0]!='S'&&e.add(t.slice(4,10)))x=new Date(+x+8e7),t=x+0;return x}

Try it online!

JavaScript (Node.js), 91 bytes, need stack expand

f=(x,e=new Set)=>e.size<366?f(x=new Date(+x+8e7),e,t=x+0,t[0]!='S'&&e.add(t.slice(4,10))):x

Try it online!

Find the last day which can't claim still not birthday as every possible day has been seen