Tout d'abord, vos chaînes par exemple ne sont pas compatibles: 8:30 pm
manque un rembourrage zéro. Je vais supposer que c'est une faute de frappe, et aurait dû être 08:30 pm
.
formats de chaîne
indésirables
Par ailleurs, ces formats de chaîne d'entrée ne sont pas souhaitables. - Un bien meilleur moyen est d'utiliser les formats standard ISO 8601. - Les horloges de 12 heures avec AM/PM sont problématiques.Les formats standard utilisent l'horloge 24 heures, avec les heures 0-23.
- La notation standard pour un intervalle est la paire de chaînes date-heure séparées par une barre oblique: 2008-01-01T13:00/2008-01-01T13:56
.
Vos chaînes d'entrée présentent un autre problème sérieux: Aucune indication de offset-from-UTC ou de fuseau horaire. Sans décalage ou fuseau horaire, nous devons revenir à l'hypothèse de jours génériques de 24 heures. Cela ne tient pas compte des anomalies telles que l'heure d'été (DST) qui peuvent entraîner des journées de 23 ou 25 heures.
Si vous connaissez le fuseau horaire prévu pour les chaînes entrantes, transmettez-le comme deuxième argument pour obtenir un résultat correct.
java.time
Cette question est assez ancienne. Depuis lors, Java a supplanté les vieilles classes de date-heure (Date
, Calendar
, etc.) avec les classes java.time modernes. Nous utilisons java.time dans le code ci-dessous.
Exemple classe
Voici une classe complète pour le traitement de ces chaînes comme indiqué dans votre question. Un Duration
est produit.
package javatimestuff;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.Locale;
/**
*
* @author Basil Bourque
*/
public class DurationProcessor {
static final int SHORT = 30;
static final int LONG = 41;
static final DateTimeFormatter FORMATTER_LOCALDATETIME = DateTimeFormatter.ofPattern ("uuuu-MM-dd hh:mm a");
static final DateTimeFormatter FORMATTER_LOCALTIME = DateTimeFormatter.ofPattern ("hh:mm a");
static public Duration process (String input) {
return DurationProcessor.process (input , ZoneOffset.UTC);
}
static public Duration process (String input , ZoneId zoneId) {
Duration d = Duration.ZERO; // Or maybe null. To be generated by the bottom of this code.
if (null == input) {
// …
System.out.println ("ERROR - Passed null argument.");
return d;
}
if (input.length() == 0) {
// …
System.out.println ("ERROR - Passed empty string as argument.");
return d;
}
String inputModified = input.toUpperCase (Locale.ENGLISH); // Change `am` `pm` to `AM` `PM` for parsing.
String[] parts = inputModified.split (" - ");
String inputStart = parts[ 0 ]; // A date-time sting.
String inputStop = parts[ 1 ]; // Either a date-time string or a time-only string (assume the same date).
ZonedDateTime start = null; // To be generated in this block of code.
try {
LocalDateTime ldt = LocalDateTime.parse (inputStart , DurationProcessor.FORMATTER_LOCALDATETIME);
start = ldt.atZone (zoneId);
} catch (DateTimeParseException e) {
// …
System.out.println ("ERROR - The start failed to parse. inputStart: " + inputStart);
return d;
}
ZonedDateTime stop = null; // To be generated in this block of code.
switch (input.length()) {
case DurationProcessor.SHORT: // Example: "2008-01-01 01:00 pm - 01:56 pm"
try {
LocalTime stopTime = LocalTime.parse (inputStop , DurationProcessor.FORMATTER_LOCALTIME);
stop = ZonedDateTime.of (start.toLocalDate() , stopTime , zoneId);
} catch (DateTimeParseException e) {
// …
System.out.println ("ERROR - The stop time failed to parse.");
return d;
}
break;
case DurationProcessor.LONG: // "2008-01-01 8:30 pm - 2008-01-02 09:30 am"
try {
LocalDateTime ldt = LocalDateTime.parse (inputStop , DurationProcessor.FORMATTER_LOCALDATETIME);
stop = ldt.atZone (zoneId);
} catch (DateTimeParseException e) {
// …
System.out.println ("ERROR - The stop date-time failed to parse.");
return d;
}
break;
default:
// …
System.out.println ("ERROR - Input string is of unexpected length: " + input.length());
break;
}
d = Duration.between (start , stop);
return d;
}
public static void main (String[] args) {
// Run with out time zone (assumes UTC).
Duration dShort = DurationProcessor.process ("2008-01-01 01:00 pm - 01:56 pm");
System.out.println ("dShort: " + dShort);
Duration dLong = DurationProcessor.process ("2008-01-01 08:30 pm - 2008-01-02 09:30 am");
System.out.println ("dLong: " + dLong);
// Run with specified time zone.
ZoneId z = ZoneId.of ("America/Montreal");
Duration dShortZoned = DurationProcessor.process ("2008-01-01 01:00 pm - 01:56 pm" , z);
System.out.println ("dShortZoned: " + dShortZoned);
Duration dLongZoned = DurationProcessor.process ("2008-01-01 08:30 pm - 2008-01-02 09:30 am" , z);
System.out.println ("dLongZoned: " + dLongZoned);
}
}
Notez la méthode main
dans la classe pour des usages par exemple.
D'abord une paire d'appels sans spécifier de fuseau horaire. Donc UTC et les jours de 24 heures seront utilisés.
Duration dShort = DurationProcessor.process ("2008-01-01 01:00 pm - 01:56 pm");
System.out.println ("dShort: " + dShort);
Duration dLong = DurationProcessor.process ("2008-01-01 08:30 pm - 2008-01-02 09:30 am");
System.out.println ("dLong: " + dLong);
Une autre paire d'appels où nous spécifions le fuseau horaire prévu.
ZoneId z = ZoneId.of ("America/Montreal");
Duration dShortZoned = DurationProcessor.process ("2008-01-01 01:00 pm - 01:56 pm" , z);
System.out.println ("dShortZoned: " + dShortZoned);
Duration dLongZoned = DurationProcessor.process ("2008-01-01 08:30 pm - 2008-01-02 09:30 am" , z);
System.out.println ("dLongZoned: " + dLongZoned);
Code en direct
Voir cette course de classe live code in IdeOne.com.
DSHORT: PT56M
Dlong: PT13H
dShortZoned: PT56M
dLongZoned: PT13H
Comme indiqué ailleurs sur cette page, le format de sortie en utilisant le temps de style de jour tel que 00:56
est ambigu et confus, et devrait être évité. La classe Duration
utilise à la place la norme ISO 8601 format for durations. Ci-dessus, nous voyons des résultats de cinquante-six minutes et treize minutes.
A propos java.time
Le cadre java.time est construit en Java 8 et versions ultérieures. Ces classes supplantent les vieilles classes de date-heure legacy gênantes telles que java.util.Date
, Calendar
, & SimpleDateFormat
.Le projet Joda-Time, maintenant en maintenance mode, conseille la migration vers les classes java.time.
Pour en savoir plus, voir le Oracle Tutorial. Et recherchez Stack Overflow pour de nombreux exemples et explications. La spécification est JSR 310.
Où obtenir les classes java.time?
- Java SE 8 et SE 9 et plus tard
- intégré.
- Partie de l'API Java standard avec une implémentation groupée.
- Java 9 ajoute quelques fonctionnalités et corrections mineures.
- Java SE 6 et SE 7
- Une grande partie de la fonctionnalité de java.time est de retour à Java 6 Ported .
- Android
Le projet ThreeTen-Extra java.time étend avec des classes supplémentaires. Ce projet est un terrain d'essai pour d'éventuels ajouts futurs à java.time. Vous pouvez trouver ici des classes utiles telles que Interval
, YearWeek
, YearQuarter
et more.
Les entrées sont incohérentes. La plupart des valeurs de l'heure ont un zéro de remplissage, mais '20:30' omet ceci. –