1
votes

SimpleDateFormat affichant des résultats incohérents

/*Note the 11 instead of 10*/
    val dateStr = "2020 11 12 23 12 13"
    val dateFormat = "yyyyMMddHHmmss"
    import java.util.Date
    val sdf = new SimpleDateFormat(dateFormat)
    sdf.setLenient(false)
    val res = sdf.parse(dateStr)
    println("res = "+res)
    
    
    scala> val res = sdf.parse(dateStr)
    res: java.util.Date = Wed Jan 01 01:02:23 PST 2020

1 commentaires

Envisagez de passer à l ' API de date-heure moderne .


3 Réponses :


0
votes

Bonjour, je pense que le problème est le format de la date:

    val dateFormat = "yyyy MM dd HH mm ss"

Et devrait être

    val dateFormat = "yyyyMMddHHmmss"

Parce que votre dateStr contient de l'espace qui joue une partie importante du format

Mais si vous voulez échouer au cas où vous auriez de l'espace ou autre chose indésirable dans la date, peut-être qu'une regex est la meilleure réponse?


1 commentaires

Oui, je veux qu'il lance une exception parseException lorsqu'il n'est pas en mesure d'analyser mon format donné "aaaaMMjjHHmmss". Je veux dire que c'est ce que la fonction d'analyse est censée faire



2
votes

La réponse de Ruokki est correcte, votre modèle de mise en forme ne correspond pas à vos données d'entrée.

java.time

Plus important encore, vous utilisez les mauvaises classes. Les classes date-heure fournies avec les premières versions de Java sont terribles. Il y a des années, elles ont été supplantées par les classes modernes java.time définies dans JSR 310.

try
{
    LocalDateTime ldt = LocalDateTime.parse( input , f ) ;
}
catch ( DateTimeParseException e ) 
{
    …
}

Pour détecter les entrées défectueuses, trappez le DateTimeParseException .

DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuu MM dd HH mm ss" ) ;
LocalDateTime ldt = LocalDateTime.parse( input , f ) ;

ResolverStyle

Le DateTimeFormatter utilise l'un des trois approches différentes de l'analyse syntaxique: stricte, intelligente et indulgente. Ceux-ci sont représentés par ResolverStyle enum. SMART est utilisé par défaut, mais vous pouvez spécifier STRICT si cela répond mieux à vos besoins.

ISO 8601

Je suggère vous informez l'éditeur de vos données d'entrée sur ISO 8601 . Cette norme définit les formats d'échange de valeurs date-heure textuellement.

Les classes java.time utilisent ISO 8601 par défaut lors de l'analyse / génération de chaînes. Il n'est donc pas nécessaire de définir un modèle de mise en forme pour les entrées conformes.


0 commentaires

2
votes

SimpleDateFormat est tout simplement trop indulgent pour ce que vous voulez. Il analyse votre date comme suit:

val formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
val date = LocalDateTime.parse(dateStr, formatter);
println("date="+date);

Je pense donc que la meilleure solution pour vous serait de mordre la balle et d'interdire les espaces.

Alors essayez quelque chose comme couper le chaîne, puis recherchez des espaces au milieu. Si vous trouvez des espaces, lancez une exception.

Mais en fin de compte, il est probablement préférable de supprimer SimpleDateFormat et d'utiliser les nouveaux éléments. Je pense que la nouvelle classe DateTimeFormatter vous servira mieux:

// In Java
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
LocalDateTime date = LocalDateTime.parse(dateStr, formatter);
System.out.println("date="+date);

Cela lance et exception.

Dans Scala:

2020 yyyy
_1   MM (where _ represents a space)
1    dd
_1   HH
2    mm
23   seconds
12 13 ignored


2 commentaires

Analyse impressionnante. Et pour moi, cela sous-tend fortement votre dernière suggestion: abandonnez SimpleDateFormat et utilisez java.time, l'API Java de date et d'heure moderne.


Ouais .. il semble que le DateTimeFormatter soit bien "meilleur" pour cela. Il ne fait pas d'hypothèses étranges lors de l'analyse.