Noté que java.time.format.DateTimeFormatter
no puede analizarse como se esperaba. Vea abajo:
import java.time.LocalDate; import java.time.format.DateTimeFormatter; public class Play { public static void tryParse(String d,String f) { try { LocalDate.parse(d, DateTimeFormatter.ofPattern(f)); System.out.println("Pass"); } catch (Exception x) {System.out.println("Fail");} } public static void main(String[] args) { tryParse("26-may-2015","dd-L-yyyy"); tryParse("26-May-2015","dd-L-yyyy"); tryParse("26-may-2015","dd-LLL-yyyy"); tryParse("26-May-2015","dd-LLL-yyyy"); tryParse("26-may-2015","dd-M-yyyy"); tryParse("26-May-2015","dd-M-yyyy"); tryParse("26-may-2015","dd-MMM-yyyy"); tryParse("26-May-2015","dd-MMM-yyyy"); } }
Solo el último bash con tryParse("26-May-2015","dd-MMM-yyyy");
pasará”. Según la documentación, LLL
debería poder analizar el formato textual. Tampoco la sutil diferencia de la mayúscula ‘M’ frente a la minúscula ‘m’.
Esto es realmente molesto, ya que no puedo analizar las cadenas formateadas de forma predeterminada por Oracle DB
SELECT TO_DATE(SYSDATE,'DD-MON-YYYY') AS dt FROM DUAL;
Del mismo modo, para el siguiente progtwig:
import java.time.LocalDate; import java.time.format.DateTimeFormatter; public class Play { public static void output(String f) { LocalDate d = LocalDate.now(); Locale l = Locale.US; // Locale l = Locale.forLanguageTag("ru"); System.out.println(d.format(DateTimeFormatter.ofPattern(f,l))); } public static void main(String[] args) { output("dd-L-yyyy"); output("dd-LLL-yyyy"); output("dd-M-yyyy"); output("dd-MMM-yyyy"); } }
Me sale por debajo de la salida:
28-5-2015 28-5-2015 28-5-2015 28-May-2015
Claramente, el especificador de formato L
no trata nada textual, me parece numérico …
Sin embargo, si cambio la Locale.forLanguageTag("ru")
regional a Locale.forLanguageTag("ru")
, obtengo el siguiente resultado:
28-5-2015 28-Май-2015 28-5-2015 28-мая-2015
Todo realmente interesante, ¿no estás de acuerdo?
Las preguntas que tengo son:
L
? Citando una parte de la documentación que percibí como ‘es importante’:
Texto: el estilo de texto se determina en función del número de letras de patrón utilizadas. Menos de 4 letras de patrón usarán la forma corta. Exactamente 4 letras de patrón usarán la forma completa. Exactamente 5 letras de patrón usarán la forma estrecha. Las letras de patrón ‘L’, ‘c’ y ‘q’ especifican la forma independiente de los estilos de texto .
Número: si el recuento de letras es uno, el valor se genera usando la cantidad mínima de dígitos y sin relleno. De lo contrario, el recuento de dígitos se usa como el ancho del campo de salida, con el valor cero acolchado según sea necesario. Las siguientes letras de patrón tienen restricciones en el recuento de letras. Solo se puede especificar una letra de ‘c’ y ‘F’. Se pueden especificar hasta dos letras de ‘d’, ‘H’, ‘h’, ‘K’, ‘k’, ‘m’ y ‘s’. Se pueden especificar hasta tres letras de ‘D’.
Número / texto: si el recuento de letras de patrón es 3 o más, use las reglas de Texto arriba . De lo contrario, use las reglas numéricas de arriba.
ACTUALIZAR
He hecho dos presentaciones a Oracle:
Creo que “L” está destinado a los idiomas que usan una palabra diferente para el mes en sí contra la forma en que se usa en una fecha. Por ejemplo:
Locale russian = Locale.forLanguageTag("ru"); asList("MMMM", "LLLL").forEach(ptrn -> System.out.println(ptrn + ": " + ofPattern(ptrn, russian).format(Month.MARCH)) );
Salida:
MMMM: марта LLLL: Март
No debería haber ninguna razón para usar ‘L’ en lugar de ‘M’ al analizar una fecha.
Intenté lo siguiente para ver qué configuraciones regionales admiten el formato de nombre de mes independiente:
Arrays.stream(Locale.getAvailableLocales()) .collect(partitioningBy( loc -> "3".equals(Month.MARCH.getDisplayName(FULL_STANDALONE, loc)), mapping(Locale::getDisplayLanguage, toCollection(TreeSet::new)) )).entrySet().forEach(System.out::println);
Los siguientes idiomas obtienen un nombre de mes autónomo específico de la localidad de ‘LLLL’:
Catalán, chino, croata, checo, finlandés, griego, húngaro, italiano, lituano, noruego, polaco, rumano, ruso, eslovaco, turco, ucraniano
Todos los demás idiomas obtienen “3” como nombre independiente para marzo.
De acuerdo con los javadocs:
Las letras de patrón ‘L’, ‘c’ y ‘q’ especifican la forma independiente de los estilos de texto.
Sin embargo, no pude encontrar mucho sobre lo que se supone que es la forma “independiente”. Al mirar el código, veo que al usar ‘L’ selecciona TextStyle.SHORT_STANDALONE
y de acuerdo con ese javadoc:
Texto breve para uso independiente, generalmente una abreviatura. Por ejemplo, el lunes de día de la semana podría generar “Mon”.
Sin embargo, no es así como parece funcionar. Incluso con tres letras obtengo un resultado numérico de este código:
DateTimeFormatter pattern = DateTimeFormatter.ofPattern ("dd-LLL-yyyy"); System.out.println (pattern.format (LocalDate.now ()));
Editar
Tras una investigación más exhaustiva, parece (hasta donde puedo decir) que las versiones “autónomas” de estos códigos son para cuando desee cargar sus propios datos independientes de la configuración regional, presumiblemente utilizando DateTimeFormatterBuilder
. Como tal, por defecto DateTimeFormatter
no tiene entradas cargadas para TextStyle.SHORT_STANDALONE
.