Excel, 212 bytes
=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)
Si lo rompes en pedazos en cada ampersand, obtienes estas piezas:
ABS()
extrae el número del día de los últimos dos caracteres en la cadena. Como eso puede incluir un guión, lo ABS
convierte en positivo.
IF((ABS-12)<2,"th",SWITCH())
agrega el ordinal. El -12
bit es porque 11, 12 y 13 no siguen la regla normal y todos obtienen en th
lugar dest
, nd
, y rd
. Esto corrige por eso.
- Nota: La
SWITCH
función solo está disponible en Excel 2016 y versiones posteriores. ( Fuente ) Es más corto que CHOOSE
en este caso porque puede devolver un valor si no se encuentra una coincidencia, mientras que CHOOSE
requiere una entrada numérica y debe tener un retorno correspondiente para cada valor posible.
TEXT(MID()*30," mmmm ")
extrae el nombre del mes. MID()
extrae el número del mes como una cadena y multiplicando por 30 devuelve un número. Excel ve ese número como una fecha (1900-01-30, 1900-02-29, 1900-03-30, etc.) y lo TEXT()
formatea como un nombre de mes con un espacio en ambos extremos. 28 y 29 también habrían funcionado, pero 30 se ve "mejor".
LEFT()
extrae el número del año.
Ahora, dado todo eso, habría sido mucho más fácil si todos los casos de prueba estuvieran en un rango de fechas que Excel puede manejar como una fecha real: 1900-01-01 a 9999-12-31. La gran ventaja es que toda la fecha está formateada a la vez. Esa solución es 133 bytes :
=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")
El otro gran obstáculo era tener que incluir el ordinal. Sin eso, la solución es solo 34 bytes :
=TEXT(DATEVALUE(A1),"d mmmm yyyy")
03rd
lugar de3rd