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;
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?