2010-10-26 7 views
3

Dites que j'ai deux champs de date receiveDate et currentDate. Je veux vérifier si receiveDate était 5 jours avant currentDate. Ce que j'ai fait était de convertir les dates en millisecondes et ensuite comparer contre 5. Y at-il une meilleure façon de le faire? Si oui, comment et pourquoi le mien est-il moins meilleur? Merci.Comparaison des dates en millisecondes

méthode I écrit -

private static final double DAY_IN_MILLISECONDS = 86400000; 

// Param date is the receivedDate 
private long getDaysOld(final Date date) { 


    Calendar suppliedDate = Calendar.getInstance(); 
    suppliedDate.setTime(date); 
    Calendar today = Calendar.getInstance(); 
    today.setTime(currentDate); 

    double ageInMillis = (today.getTimeInMillis() - suppliedDate.getTimeInMillis()); 
    double tempDouble; 

    if(isEqual(ageInMillis, 0.00) || isGreaterThan(Math.abs(ageInMillis), DAY_IN_MILLISECONDS)) { 
     tempDouble = ageInMillis/DAY_IN_MILLISECONDS; 
    } else { 
     tempDouble = DAY_IN_MILLISECONDS/ageInMillis; 
    } 

    long ageInDays = Math.round(tempDouble); 

    return ageInDays; 


} 

Alors j'ai quelque chose comme-

long daysOld = getDaysOld(receivedDate) ; 
if(daysOld <= 5) { 
    .... some business code .... 
} 
+0

Vous souciez-vous des changements de temps en raison de l'heure d'été? Deux fois par an, si vous ne faites pas attention, votre durée sera réduite à 4 heures ou portée à 6. –

+0

En général, c'est une maxime utile à adopter: ne faites pas vos propres calculs de date/heure. –

+1

Votre code est absolument fou. Pourquoi utilisez-vous les instances de calendrier pour passer de Date à un nombre de millisecondes? Pourquoi ageInMillis est un double? Que diable fait le bloc d'ailleurs? –

Répondre

1

Il peut être raccourci beaucoup:

int daysOld = (System.currentTimeMillis() - date.getTime())/DAY_IN_MILLISECONDS; 
+0

C'est plus court, mais c'est aussi incorrect. Astuce:% n'est pas l'opérateur que vous recherchez. –

+1

Oui, c'est faux. – dogbane

2

donner un essai à joda-time. Calculs de temps avec l'API native est toujours au mieux. Le temps de Joda rend ce type de calcul MUUUCH plus simple et gérera assez bien les fuseaux horaires.

2
import java.util.Calendar; 
import java.util.Date; 
import java.util.GregorianCalendar; 


public class Test { 

    private static long DAY_IN_MILLISECONDS = 24 * 60 * 60 * 1000; 

    public static void main(String[] args) throws Exception { 
     // 
     Date currentDate = getGregorianDate(1990, Calendar.JANUARY, 20); 
     Date receiveDate = getGregorianDate(1990, Calendar.JANUARY, 23); 
     // 
     if (getDifferenceBetweenDates(receiveDate, currentDate) < 5 * DAY_IN_MILLISECONDS) { 
      System.out.println("Receive date is not so old."); 
     } 
     else { 
      System.out.println("Receive date is very old."); 
     } 
    } 

    private static long getDifferenceBetweenDates(Date date1, Date date2) { 
     return Math.abs(date1.getTime() - date2.getTime()); 
    } 

    private static Date getGregorianDate(int year, int month, int date) { 
     Calendar calendar = GregorianCalendar.getInstance(); 
     calendar.set(year, month, date); 
     return calendar.getTime(); 
    } 

} 
0

Vous ne pouvez pas simplement soustraire et diviser par 24 * 60 * 60 * 1000, en raison de l'heure d'été (où un jour pourrait avoir 23 ou 25 heures).

Par exemple, au Royaume-Uni, les horloges ont progressé d'une heure le 28/03/2010. La différence entre 27/03/2010 et 28/03/2010 devrait être 1 jour, mais si vous suivez cette approche, vous obtiendrez 0.

Vous devez prendre le décalage en compte:

public static long daysBetween(Date dateEarly, Date dateLater) { 
    Calendar cal1 = Calendar.getInstance(); 
    cal1.setTime(dateEarly); 
    Calendar cal2 = Calendar.getInstance(); 
    cal2.setTime(dateLater); 

    long endL = cal2.getTimeInMillis() + cal2.getTimeZone().getOffset(cal2.getTimeInMillis()); 
    long startL = cal1.getTimeInMillis() + cal1.getTimeZone().getOffset(cal1.getTimeInMillis()); 
    return (endL - startL)/(24 * 60 * 60 * 1000); 
} 

public static void main(String[] args) throws Exception { 

    TimeZone.setDefault(TimeZone.getTimeZone("Europe/London")); 

    Date foo = new Date(2010,02,27); 
    Date bar= new Date(2010,02,28); 

    System.out.println(daysBetween(foo,bar)); //prints 1 
} 
+0

Ce constructeur Date est obsolète, car Date n'est pas très bon pour gérer les dates (malgré le nom - je ne sais pas de qui il s'agissait). Cependant, vous pouvez faire à peu près la même chose avec Calendar. –

0

Tout dépend de ce que signifie "cinq jours". Si vous recevez quelque chose le lundi midi, alors le samedi après-midi, l'avez-vous reçu dans les cinq jours ou pas? Le temps écoulé est supérieur à cinq jours, mais le jour où vous l'avez reçu il y a cinq jours. Pensez à la façon dont vous répondriez à cette question; maintenant chose sur la façon dont votre mère répondrait à cette question. Ce n'est peut-être pas la même chose - je dirais que la plupart des gens, en particulier les non-programmeurs, comptent les jours qui passent en passant les midnights locales. Il est cinq heures du matin le mercredi après onze heures et demie du mardi soir, même si c'est moins d'un jour (moins d'un quart de journée!) Plus tard. Donc, je pense que ce que vous voulez faire est de comparer seulement les dates, pas les temps. Vous pouvez le faire avec Calendar en mettant à zéro tous les champs horaires. Étant donné un arrivedDate et un lieu (vous pouvez dire quand minuit est), je pense que cela est correct:

Calendar deadline = Calendar.getInstance(locale); 
    deadline.set(Calendar.HOUR_OF_DAY, 0); 
    deadline.set(Calendar.MINUTE, 0); 
    deadline.set(Calendar.SECOND, 0); 
    deadline.set(Calendar.MILLISECOND, 0); 
    deadline.add(Calendar.DAY_OF_MONTH, 5); 

    Calendar arrived = Calendar.getInstance(locale); 
    arrived.setTime(arrivedDate); 
    deadline.set(Calendar.HOUR_OF_DAY, 0); 
    deadline.set(Calendar.MINUTE, 0); 
    deadline.set(Calendar.SECOND, 0); 
    deadline.set(Calendar.MILLISECOND, 0); 

    boolean arrivedWithinDeadline = arrived.compareTo(deadline) <= 0; 

Vous devriez vérifier que bien avant de l'utiliser, cependant.

0

Ci-dessous est ma méthode qui me renvoie la différence exacte dans les jours,

/** 
* method to get difference of days between current date and user selected date 
* @param selectedDateTime: your date n time 
* @param isLocalTimeStamp: defines whether the timestamp d is in local or UTC format 
* @return days 
*/ 
public static long getDateDiff(long selectedDateTime, boolean isLocalTimeStamp) 
{ 
    long timeOne = Calendar.getInstance().getTime().getTime(); 
    long timeTwo = selectedDateTime; 
    if(!isLocalTimeStamp) 
     timeTwo += getLocalToUtcDelta(); 
    long delta = (timeOne - timeTwo)/ONE_DAY; 

    if(delta == 0 || delta == 1) { 
     Calendar cal1 = new GregorianCalendar(); 
     cal1.setTimeInMillis(timeOne); 
     Calendar cal2 = new GregorianCalendar(); 
     cal2.setTimeInMillis(timeTwo); 
     long dayDiff = cal1.get(Calendar.DAY_OF_MONTH) - cal2.get(Calendar.DAY_OF_MONTH); 
     return dayDiff; 
    } 

    return delta; 
} 
Questions connexes