Excel, 212 байт
=ABS(RIGHT(A1,2))&IF(ABS(ABS(RIGHT(A1,2))-12)<2,"th",SWITCH(RIGHT(A1,1),"1","st","2","nd","3","rd","th"))&TEXT(MID(A1,FIND("-",A1)+1,FIND("-",REPLACE(A1,1,FIND("-",A1),""))-1)*30," mmmm ")&LEFT(A1,FIND("-",A1)-1)
Если вы разбиваете его на куски на каждом амперсанде, вы получаете эти кусочки:
ABS()извлекает номер дня из двух последних символов в строке. Поскольку это может включать дефис, ABSпреобразует его в положительный.
IF((ABS-12)<2,"th",SWITCH())добавляет порядковый номер. -12Бит , потому что 11, 12 и 13 не следуют нормальному правилу , и все они получают thвместо st, ndи rd. Это исправляет для этого.
- Примечание.
SWITCHФункция доступна только в Excel 2016 и более поздних версиях. ( Источник ) Он короче, чем CHOOSEв этом случае, потому что он может возвращать значение, если совпадение не найдено, тогда как CHOOSEтребует числового ввода и должен иметь соответствующий возврат для каждого возможного значения.
TEXT(MID()*30," mmmm ")извлекает название месяца. MID()вытаскивает номер месяца в виде строки, а умножение на 30 возвращает число. Excel видит это число как дату (1900-01-30, 1900-02-29, 1900-03-30 и т. Д.) ИTEXT() форматирует его как название месяца с пробелом на обоих концах. 28 и 29 тоже бы работали, но 30 выглядит "лучше".
LEFT() извлекает номер года.
Теперь, учитывая все это, было бы намного проще, если бы все контрольные примеры были в диапазоне дат, который Excel может обработать как фактическую дату: с 1900-01-01 по 9999-12-31. Большим преимуществом является то, что вся дата форматируется сразу. Это решение составляет 133 байта :
=TEXT(DATEVALUE(A1),"d""" & IF(ABS(ABS(RIGHT(A1,2))-12)<2,"th",SWITCH(RIGHT(A1,1),"1","st","2","nd","3","rd","th")) & """ mmmm yyyy")
Другим большим препятствием было включение порядкового номера. Без этого решение будет всего 34 байта :
=TEXT(DATEVALUE(A1),"d mmmm yyyy")
03rdвместо3rd