2015-11-04 1 views
1

J'ai un objet Tâche qui a un nom et une date. La valeur de la date doit être String. Un exemple est 11/9/2015 23:00 à comparer à 11/24/2015 12:00. J'ai besoin d'aide pour écrire un compareTo() afin que la tâche ayant la date la plus proche s'affiche en premier. Ce que j'ai est incorrect car il ne se compare pas correctement. Je sais qu'il existe des alternatives mais il faut que je le fasse avec String. J'ai envisagé d'utiliser .split() pour diviser mm/jj/aaaa par "/" mais je ne sais pas comment le faire.Comparaison d'une date de type Chaîne

public class Task implements Comparable<Task> { 
    /** Task name. */ 
    private String name; 
    /** Task due date. */ 
    private String dueDate; 

    /** 
    * Initializes a tasks name and due date. 
    * @param n Name 
    * @param d due date 
    */ 
    public Task(String n, String d) { 
     name = n; 
     dueDate = d; 
    } 

    /** 
    * Accessor for task name. 
    * @return Task name. 
    */ 
    public String getName() { 
     return name; 
    } 

    /** 
    * Accessor for task due date. 
    * @return Task due date. 
    */ 
    public String getDueDate() { 
     return dueDate; 
    } 

    /** 
    * Compares the due dates of the tasks to get the soonest to the front of the list. 
    * @param t The task to compare. 
    * @return The tasks in chronological order. 
    */ 
    @Override 
    public int compareTo(Task t) { //Need help here. 
     int val = dueDate.compareTo(t.getDueDate()); 

     if(val == 0) { 
      val = name.compareTo(t.getName()); 
     } 
     if(dueDate.compareTo(t.getDueDate()) > 0) { 
      val = -1; 
     } 
     if(dueDate.compareTo(t.getDueDate()) < 0) { 
      val = 1; 
     } 
     return val; 
    } 
+0

pouvez-vous convertir en un objet Date, puis comparer? – AbtPst

+0

Copie possible de [Comparaison des chaînes de date en Java] (http: // stackoverflow.com/questions/10609596/comparaison-date-cordes-en-java) –

+0

@AbtPst Non je dois juste utiliser 'String' – JCCS

Répondre

2

Le fait que vous devez avoir la date en tant que chaîne ne signifie pas que vous ne pouvez pas le convertir en un Date et d'utiliser cette classe ordre naturel:

@Override 
public int compareTo(Task t) { 
    // Handling ParseExceptions omitted for bravity's sake 
    SimpleDateFormat df = new SimpleDateFormat("MM/dd/yyyy HH:mm"); 
    Date d1 = df.parse(dueDate); 
    Date d2 = df.parse(t.getDueDate()); 

    int val = d1.compareTo(d2); 

    if(val != 0) { 
     return val;  
    } 
    return name.compareTo(t.getName()); 
} 
1

Date-Time Objets

Je vous suggère d'utiliser des objets date-heure plutôt que des chaînes comme membres de votre classe. Java 8 et versions ultérieures inclut le framework java.time très utile. Utilisez ces nouvelles classes (inspirées par Joda-Time) plutôt que les anciennes classes notoirement gênantes, java.util.Date/.Calendar.

Pas besoin d'analyser les chaînes d'entrée date-heure. Le framework java.time analyse par défaut toute chaîne au format ISO 8601. Pour les autres formats, définissez un modèle de formatage de vos entrées attendues et laissez java.time faire le travail.

Time Zone

Vous ne pouvez pas comparer les chaînes de date-heure que la vôtre sans connaître leur fuseau horaire. Peut-être que c'est UTC? Ou supposez-vous que toutes vos données se réfèrent à un fuseau horaire précis?

Dans l'exemple ci-dessous, je suppose arbitrairement un fuseau horaire de America/Los_Angeles.

Exemple de code.

Cet exemple de code dans Java 8 utilise le package java.time.format pour analyser votre chaîne pour l'entrée dans le constructeur et générer à nouveau une représentation String dans la méthode dueDateTimeAsAmericaLosAngeles.

Il est généralement préférable de conserver les valeurs de date et d'heure dans le fuseau horaire UTC. Puis ajustez à un fuseau horaire lorsque prévu par l'utilisateur ou par un autre logiciel. Donc, nous stockons un Instant sur la classe, un moment sur la ligne du temps en UTC. Pour des fuseaux horaires spécifiques, créez un objet ZonedDateTime. Si, contre mon avis, vous insistez pour stocker la valeur date-heure sous forme de chaîne, vous pouvez modifier ce code en vous déplaçant où se trouve la chaîne parsing-to-Instant.

package timestuff; 

import java.time.Instant; 
import java.time.ZoneId; 
import java.time.ZonedDateTime; 
import java.time.format.DateTimeFormatter; 

public class Task implements Comparable<Task> { 

    String title; 
    Instant due; 

    public Task (String title , String dateTimeAssumedToBeAmericaLosAngles) { 
     this.title = title; 
     ZoneId zoneId = ZoneId.of ("America/Los_Angeles"); 
     DateTimeFormatter formatter = DateTimeFormatter.ofPattern ("M/d/yyyy HH:mm").withZone (zoneId); // Example data: 11/24/2015 12:00 
     this.due = formatter.parse (dateTimeAssumedToBeAmericaLosAngles , Instant :: from); 
    } 

    @Override 
    public String toString() { 
     return "Task{ " + "title=" + title + " | instant=" + due + " }"; 
    } 

    @Override 
    public int compareTo (Task t) { 
     // Sort by the date-time of when this task is due. 
     int result = this.due.compareTo (t.due); 
     return result; 
    } 

    String dueDateTimeAsAmericaLosAngeles() { 
     ZoneId zoneId = ZoneId.of ("America/Los_Angeles"); 
     DateTimeFormatter formatter = DateTimeFormatter.ofPattern ("M/d/yyyy HH:mm").withZone (zoneId); // Example data: 11/24/2015 12:00 
     ZonedDateTime zdt = ZonedDateTime.ofInstant (this.due , zoneId); 
     String output = zdt.format (formatter); 
     return output; 
    } 

    public static void main (String[] args) { 
     Task t1 = new Task ("x" , "11/9/2015 23:00"); 
     Task t2 = new Task ("y" , "11/24/2015 12:00"); 
     int compared = t1.compareTo (t2); 
     System.out.println ("t1: " + t1 + " & t2: " + t2 + " compared: " + compared); 
    } 

} 

Quand course:

t1: Tâche {title = x | instant = 2015-11-10T07: 00: 00Z} & t2: Tâche {title = y | instant = 2015-11-24T20: 00: 00Z} a comparé: -1