2010-08-23 6 views
3

J'ai deux dates - un début et une fin. Je voudrais les mettre en forme de sorte que si les mois correspondent, ils se réduisent à quelque chose comme "20-23 AUG" et continuent à se formater correctement s'ils se cassent à la fin du mois, comme "20 SEP - 1 OCT". Existe-t-il des bibliothèques pour accomplir cela, ou devrais-je appliquer des règles de codage pour afficher des plages de dates à l'aide de DateFormats individuels?Comment formater une plage de dates en Java?

+1

Qu'en est-il de l'année? Qu'en est-il par exemple? Du 20 août 2010 au 23 août 2011? Qu'en est-il du 31 décembre 2010 au 1er janvier 2011? 1 JAN 2012? – polygenelubricants

Répondre

3

J'ai été déçu par les autres réponses. L'heure de Joda ne fonctionnait pas dans GWT et SimpleDateFormat non plus. Quoi qu'il en soit, je connaissais déjà DateTimeFormat dans GWT. Le problème principal est que la fonction getMonth() des objets date est obsolète, et il ne semble pas y avoir de bonne façon de comparer les mois et/ou les années. Cette solution n'inclut pas la vérification annuelle (qui pourrait être facilement ajoutée en changeant le monthFormatter), mais ce n'est pas important pour mon cas.

public final class DateUtility 
{ 
    public static final DateTimeFormat MONTH_FORMAT = DateTimeFormat.getFormat("MMM"); 
    public static final DateTimeFormat DAY_FORMAT = DateTimeFormat.getFormat("dd"); 
    public static final DateTimeFormat DAY_MONTH_FORMAT = DateTimeFormat.getFormat("dd MMM"); 

    public static final String DASH = " - "; 

    /** 
    * Returns a "collapsed" date range String representing the period of time 
    * between two Date parameters. Example: August 19 as a {@code startDate} 
    * and August 30 as an {@code endDate} will return "19 - 30 AUG", August 28 
    * as a {@code startDate} and September 7 as an {@code endDate} will return 
    * "28 AUG - 07 SEP". This means if you pass this two dates which cannot 
    * collapse into a shorter form, then the longer form is returned. Years 
    * are ignored, and the start and end dates are not checked to ensure we 
    * are not going backwards in time (Aug 10 - July 04 is not checked). 
    * 
    * @param startDate 
    *   the start Date in the range. 
    * @param endDate 
    *   the end Date in the range. 
    * @return a String representation of the range between the two dates given. 
    */ 
    public static String collapseDate(Date startDate, Date endDate) { 
     String formattedDateRange; 

     // Get a comparison result to determine if the Months are the same 
     String startDateMonth = MONTH_FORMAT.format(startDate); 
     String endDateMonth = MONTH_FORMAT.format(endDate); 

     if (startDateMonth.equals(endDateMonth)) 
     { 
      formattedDateRange = DAY_FORMAT.format(startDate) + DASH 
        + DAY_MONTH_FORMAT.format(endDate).toUpperCase(); 
     } 
     else 
     { 
      // Months don't match, split the string across both months 
      formattedDateRange = DAY_MONTH_FORMAT.format(startDate).toUpperCase() 
        + DASH + DAY_MONTH_FORMAT.format(endDate).toUpperCase(); 
     } 
     return formattedDateRange; 
    } 
} 
3

Commander la classe SimpleDateFormat de java. Vous pouvez construire un SimpleDateFormat en passant votre modèle de date en tant que chaîne.

+3

Tout d'abord, cette classe peut formater * one * Date mais pas une plage et, en second lieu, le formateur est assez statique, il ne peut pas modifier la mise en forme en fonction de l'entrée. –

1

Pour ajouter à la réponse de Jeroen, vous allez utiliser SimpleDateFormat deux fois, une fois pour chaque extrémité de la plage.

+0

Et l'OP pourrait utiliser une simple regex pour vérifier si les mois correspondent et couper en conséquence. –

0

Il n'existe pas de type de plage de jours en Java par défaut, donc aucun des DateFormats ne s'applique à la représentation sous forme de chaîne de ce cas.

Le meilleur à mon avis, bien être la création de type TimeSpan ou TimeDiff et remplacer la méthode à la chaîne. Ou comme vous avez suggéré créer un DateFormmater si vous avez besoin de deux également l'analyse.

7

Voici une solution utilisant JodaTime, la meilleure bibliothèque pour traiter les dates en Java (la dernière fois que j'ai vérifié). La mise en forme est simple et pourrait sans doute être améliorée en utilisant des implémentations personnalisées DateFormatter. Cela vérifie également que l'année est la même, mais ne produit pas l'année, ce qui pourrait être déroutant.

import org.joda.time.DateTime; 

public class DateFormatterTest { 

    public static void main(String[] args) { 

     DateTime august23rd = new DateTime(2010, 8, 23, 0, 0, 0, 0); 
     DateTime august25th = new DateTime(2010, 8, 25, 0, 0, 0, 0); 
     DateTime september5th = new DateTime(2010, 9, 5, 0, 0, 0, 0); 

     DateFormatterTest tester = new DateFormatterTest(); 
     tester.outputDate(august23rd, august25th); 
     tester.outputDate(august23rd, september5th); 

    } 

    private void outputDate(DateTime firstDate, DateTime secondDate) { 
     if ((firstDate.getMonthOfYear() == secondDate.getMonthOfYear()) && (firstDate.getYear() == secondDate.getYear())) { 
      System.out.println(firstDate.getDayOfMonth() + " - " + secondDate.getDayOfMonth() + " " + firstDate.monthOfYear().getAsShortText()); 
     } else { 
      System.out.println(firstDate.getDayOfMonth() + " " + firstDate.monthOfYear().getAsShortText() + " - " + secondDate.getDayOfMonth() + " " + secondDate.monthOfYear().getAsShortText()); 
     } 
    } 
} 

Sortie:

23 au 25 août

23 août à 5 sept

+0

+1 - J'écrivais juste ma recommandation d'utiliser [joda time] (http://joda-time.sourceforge.net/index.html). Maintenant, vous obtenez mon upvote à la place :) –

+3

JodaTime fonctionnera-t-il dans GWT? – SorcyCat

+0

@SorcyCat - Selon [ce fil] (http://sourceforge.net/projects/joda-time/forums/forum/337835/topic/3460297) je dirais que cela fonctionne. S'ils se contentent de commenter 2 lignes dans les tests pour rendre le test compatible avec gwt, alors je pense que ça vaut la peine d'essayer. –