How would I parse date based on the date format

How would I parse date depending on what the date time format used, so that:
01/02/03 (M/d/y)DateTime.new(3, 1, 2)
01/02/03 (d/M/y)DateTime.new(3, 2, 1)
01/02/03 (y/M/d)DateTime.new(1, 2, 3)
01/02/03 (y/d/M)DateTime.new(1, 3, 2)
01/02/03 (M/y/d)DateTime.new(2, 1, 3)
01/02/03 (d/y/M)DateTime.new(2, 3, 1)
5 Apr 1999 (d MMM y, en_GB)DateTime.new(1999, 4, 5)
14. Mai 2003 (d MMM y, de_DE)DateTime.new(2003, 5, 14)
2020年12月23日 (yyyy年M月d日, ja_JP)DateTime.new(2020, 12, 23)
01.02.03 (d/M/y)DateTime.new(3, 2, 1)
2020-03-24 15:16:17 (y/M/d)DateTime.new(2020, 3, 24, 15, 16, 17)
September 9, 1982 1:34:56 PM (en_US)DateTime.new(1982, 9, 9, 13, 34, 56)

This is harder than I think espacially parsing the month names and time periods

Maybe this thread could help you:

Nope, that’s the module I’ve made, it doesn’t have the parsing feature, which is rather hard to do (espacailly with month names and time periods)

Oh wow, now I feel dumb. I didn’t mention this. Haha.

Anyone?
I know first, I need to convert month and day period names to numbers, then re-order them to year-month-day hour.minute.second pattern, but how would I reorder it?

Also if the input is unambiguous but on the wrong date format (e.g. 1 Feb 2034 on MMMM d, yyyy date format). assume the person meant the unambiguous date order.

Found this on my untested module CLDRTools. Now I need a solution for parsing where the date format is unambiguous but different (e.g. user inputs 1 Feb 2003 when the date format is MMM d, y)

local _PATTERN_CHAR_ORDER = "GyYuUQqMLlwWdDFgEecabBChHKkjJmsSAzZOvVXx";
function d.ParseDateTime(locale, str, format, strict)
	local comb = locale.dates.calendars.gregorian.dateTimeFormat;
	local pattern = (comb["full"]:gsub("{0}", locale.StandardDateFormats["full"]):gsub("{1}", locale.StandardTimeFormats["full"]));
	
	local index = { };
	for i = 1, #_PATTERN_CHAR_ORDER do
		local c = _PATTERN_CHAR_ORDER:sub(i, i);
		local r = (pattern:find(c));
		if r then
			table.insert(index, {r, c});
		end;
	end;
	table.sort(index, function(a, b) return a[1] < b[1] end);

	local numbers = { };
	for i in str:gsub("(%D+)", " %1 "):gmatch("%w+") do
		table.insert(numbers, i);
	end;
	
	local indexes = { };
	local idx_m = 0;
	for idx, item in pairs(index) do
		local r = numbers[idx - idx_m];
		if item[2]:match('E') then
			idx_m = idx_m + 1;
		elseif tonumber(r) then
			indexes[item[2]] = r;
		else
			if item[2]:match('a') then
				if r == locale.dates.calendars.gregorian.dayPeriods.format.abbreviated.am then
					indexes[item[2]] = 0;
				elseif r == locale.dates.calendars.gregorian.dayPeriods.format.abbreviated.pm then
					indexes[item[2]] = 12;
				end;
			elseif item[2]:match('M') then
				for _, format_n in next, locale.MonthNames do
					for i, mn in next, format_n.format do
						if mn == r then
							indexes['M'] = i;
						end;
					end;
				end;
			end;
		end;
	end;
	
	local y, M, d = tonumber(indexes.y), tonumber(indexes.M), tonumber(indexes.d);
	local h, m, s = tonumber(indexes.H) or (indexes.a or 0) + (tonumber(indexes.h) % 12), tonumber(indexes.m), tonumber(indexes.s);
	return DateTime.new(y or DateTime.Now().Year, M or 1, d or 1, h, m, s);
end;

you can use string.split(day,“:”)

Considering both the input and the date format is arbitary, string.split is not going to work. Read the problem closely, the symbols inputted are unpredictiable so using a symbol to split isn’t also going to work.
Can you give me an example how would this work for use cases like this?