Domanda

sto usando classe java.util.Date di Java a Scala e si vuole confrontare un oggetto Date e l'ora corrente. So di poter calcolare il delta utilizzando getTime ():

(new java.util.Date()).getTime() - oldDate.getTime()

Tuttavia, questo mi lascia con un long che rappresenta millisecondi. C'è un modo più semplice più bello per avere un delta di tempo?

È stato utile?

Soluzione

Il Date API JDK è orribilmente rotto purtroppo. Mi consiglia di utilizzare Joda Tempo biblioteca .

Joda tempo ha un concetto di tempo Intervallo :

Interval interval = new Interval(oldTime, new Instant());

EDIT: A proposito, Joda ha due concetti: Interval per rappresentare un intervallo di tempo tra due istanti (rappresentare il tempo 08:00-10:00), e un Duration che rappresenta un periodo di tempo senza limiti di tempo reale (es rappresentano due ore!)

Se vi interessa soltanto comparazioni di tempo, la maggior parte delle implementazioni Date (compreso il JDK uno) implementa un'interfaccia Comparable, che consente di utilizzare il Comparable.compareTo()

Altri suggerimenti

diff semplice (senza lib)

/**
 * Get a diff between two dates
 * @param date1 the oldest date
 * @param date2 the newest date
 * @param timeUnit the unit in which you want the diff
 * @return the diff value, in the provided unit
 */
public static long getDateDiff(Date date1, Date date2, TimeUnit timeUnit) {
    long diffInMillies = date2.getTime() - date1.getTime();
    return timeUnit.convert(diffInMillies,TimeUnit.MILLISECONDS);
}

E poi si può chiamare:

getDateDiff(date1,date2,TimeUnit.MINUTES);

per ottenere il diff dei 2 date in unità di minuti.

TimeUnit è java.util.concurrent.TimeUnit, un enum Java standard di andare dal Nanos al giorno.


diff di interpretazione (senza lib)

public static Map<TimeUnit,Long> computeDiff(Date date1, Date date2) {

    long diffInMillies = date2.getTime() - date1.getTime();

    //create the list
    List<TimeUnit> units = new ArrayList<TimeUnit>(EnumSet.allOf(TimeUnit.class));
    Collections.reverse(units);

    //create the result map of TimeUnit and difference
    Map<TimeUnit,Long> result = new LinkedHashMap<TimeUnit,Long>();
    long milliesRest = diffInMillies;

    for ( TimeUnit unit : units ) {

        //calculate difference in millisecond 
        long diff = unit.convert(milliesRest,TimeUnit.MILLISECONDS);
        long diffInMilliesForUnit = unit.toMillis(diff);
        milliesRest = milliesRest - diffInMilliesForUnit;

        //put the result in the map
        result.put(unit,diff);
    }

    return result;
}

http://ideone.com/5dXeu6

L'output è qualcosa di simile Map:{DAYS=1, HOURS=3, MINUTES=46, SECONDS=40, MILLISECONDS=0, MICROSECONDS=0, NANOSECONDS=0}, con le unità ordinate.

Basta convertire tale mappa per una stringa user-friendly.


Attenzione

I frammenti di codice sopra calcolano un semplice diff tra 2 istanti. Può causare problemi durante un interruttore legale, come spiegato in questo post . Questo significa che se si calcola la diff tra le date con il tempo si può avere un mancante giorno / ora.

A mio parere la data di diff è una specie di soggettivo, soprattutto nei giorni. È possibile:

  • contare il numero di 24 ore il tempo trascorso: giorno + 1 - giorno = 1 giorno = 24 ore

  • contare il numero di tempo trascorso, curando legale: giorno + 1 - giorno = 1 = 24h (ma usando il tempo mezzanotte e legale potrebbe essere 0 giorni e 23h)

  • contare il numero di day switches, il che significa giorno + 1 01:00 - giorno 11:00 = 1 giorno, anche se il tempo trascorso è solo 2 ore (o 1h se c'è il salvataggio di una luce del giorno: p)

La mia risposta è valida se la tua definizione di data di diff nei giorni delle partite il 1 ° caso

Con JodaTime

Se si utilizza JodaTime si può ottenere il diff per 2 istanti (millies sostenuti ReadableInstant) date con:

Interval interval = new Interval(oldInstant, new Instant());

Ma è anche possibile ottenere il diff per le date locali / orari:

// returns 4 because of the leap year of 366 days
new Period(LocalDate.now(), LocalDate.now().plusDays(365*5), PeriodType.years()).getYears() 

// this time it returns 5
new Period(LocalDate.now(), LocalDate.now().plusDays(365*5+1), PeriodType.years()).getYears() 

// And you can also use these static methods
Years.yearsBetween(LocalDate.now(), LocalDate.now().plusDays(365*5)).getYears()
int diffInDays = (int)( (newerDate.getTime() - olderDate.getTime()) 
                 / (1000 * 60 * 60 * 24) )

Si noti che questo funziona con date UTC, quindi la differenza può essere un giorno di riposo, se si guardano le date locali. E a farla funzionare correttamente con le date locali richiede un approccio completamente diverso a causa di ora legale.

È necessario definire il problema in modo più chiaro. potrebbero basta prendere il numero di millisecondi tra i due oggetti Date e dividere per il numero di millisecondi in 24 ore, per esempio ... ma:

  • Questo non avrà fusi orari in considerazione - Date è sempre in UTC
  • Non ci vorrà ora legale in considerazione (dove ci possono essere giorni che sono lunghe solo 23 ore per esempio)
  • Anche all'interno UTC, quanti giorni ci sono in 16 Agosto 23:00 al 18 agosto 02:00? E 'solo 27 ore, in modo vuol dire un giorno? O dovrebbe essere di tre giorni perché copre tre date?

Uso della java.time quadro integrato in Java 8 +:

ZonedDateTime now = ZonedDateTime.now();
ZonedDateTime oldDate = now.minusDays(1).minusMinutes(10);
Duration duration = Duration.between(oldDate, now);
System.out.println("ISO-8601: " + duration);
System.out.println("Minutes: " + duration.toMinutes());

Output:

  

ISO-8601: PT24H10M

     

Minuti: 1450

Per ulteriori informazioni, consultare la Oracle Tutorial e la ISO 8601 standard.

tl; dr

Converti i tuoi oggetti java.util.Date obsoleti alla loro sostituzione, java.time.Instant. Quindi calcolare il tempo trascorso come un Duration.

Duration d = 
    Duration.between(                   // Calculate the span of time between two moments as a number of hours, minutes, and seconds.
        myJavaUtilDate.toInstant() ,    // Convert legacy class to modern class by calling new method added to the old class.
        Instant.now()                   // Capture the current moment in UTC. About two and a half hours later in this example.
    )
;
  

d.toString (): PT2H34M56S

     

d.toMinutes (): 154

     

d.toMinutesPart (): 34

ISO 8601 Formato: PnYnMnDTnHnMnS

La ragionevole standard di ISO 8601 definisce una rappresentazione testuale concisa di un arco di tempo come un numero di anni, mesi, giorni, ore, ecc Le chiamate standard come tale campata un . Il formato è PnYnMnDTnHnMnS dove il P significa "Periodo", il T separa la porzione data dalla porzione di tempo, e in mezzo sono numeri seguiti da una lettera.

Esempi:

  • P3Y6M4DT12H30M5S
    tre anni, sei mesi, quattro giorni, dodici ore, trenta minuti e cinque secondi
  • PT4H30M
    Quattro ore e mezzo

java.time

Il java.time framework integrato in Java 8 e versioni successive soppianta le classi fastidiosi vecchi java.util.Date / java.util.Calendar. Le nuove classi sono ispirati al grande successo Joda Time quadro, inteso come il suo successore, simile nel concetto ma riprogettato. Definito da JSR 310 . Estesa dal ThreeTen-Extra progetto . Vedere la Tutorial .

Momento

Il Instant classe rappresenta un momento sulla timeline in UTC con una risoluzione di nanosecondi (fino a nove (9) cifre di una frazione decimale).

Instant instant = Instant.now() ;  // Capture current moment in UTC.

Meglio evitare le classi legacy come Date / Calendar. Ma se si deve inter-operare con il vecchio codice non ancora aggiornato a java.time , convertire avanti e indietro. Chiamare nuovi metodi di conversione aggiunti alle vecchie classi. Per passare da un java.util.Date a un Instant , chiamata Date::toInstant .

Instant instant = myJavaUtilDate.toInstant() ;  // Convert from legacy `java.util.Date` class to modern `java.time.Instant` class.

lasso di tempo

Le classi java.time hanno diviso questa idea di rappresentare un arco di tempo come un certo numero di anni, mesi, giorni, ore, minuti, secondi in due parti:

Ecco un esempio.

ZoneId zoneId = ZoneId.of ( "America/Montreal" );
ZonedDateTime now = ZonedDateTime.now ( zoneId );
ZonedDateTime future = now.plusMinutes ( 63 );
Duration duration = Duration.between ( now , future );

Dump per consolare.

Sia Period e Duration usa il standard ISO 8601 per generare una rappresentazione stringa di loro valore.

System.out.println ( "now: " + now + " to future: " + now + " = " + duration );
  

ora: 2015-11-26T00: 46: 48,016-05: 00 [America / Montreal] per il futuro: 2015/11/26T00: 46: 48,016-05: 00 [America / Montreal] = PT1H3M

Java 9 aggiunge metodi per Duration per ottenere la parte giorni, ore parte, minuti parte, e secondi parte.

È possibile ottenere il numero totale di giorni o di ore o minuti o secondi o millisecondi o nanosecondi in tutta la durata.

long totalHours = duration.toHours();

In Java 9 classe Duration ottiene il nuovo metodi per restituire le varie parti di giorni, ore, minuti, secondi, millisecondi / nanosecondi. Chiamare i metodi to…Part:. toDaysPart(), toHoursPart(), e così via

ChronoUnit

Se vi interessa soltanto una semplice grande granularità di tempo, come ad esempio “il numero di giorni trascorsi”, utilizzare il ChronoUnit enum.

long daysElapsed = ChronoUnit.DAYS.between( earlier , later );

Un altro esempio.

Instant now = Instant.now();
Instant later = now.plus( Duration.ofHours( 2 ) );
…
long minutesElapsed = ChronoUnit.MINUTES.between( now , later );
  

120


A proposito di java.time

Il java.time quadro è integrato in Java 8 e versioni successive. Queste classi soppiantare la vecchia eredità classi data-ora problematici, come java.util.Date , Calendar , e SimpleDateFormat .

Il Joda Time progetto, ora in modalità manutenzione , consiglia migrazione java.time.

Per ulteriori informazioni, vedere la Oracle Tutorial . E cercare Stack Overflow per molti esempi e spiegazioni. Le specifiche sono JSR 310 .

Dove ottenere le classi java.time?

Il ThreeTen-Extra progetto java.time estende con classi aggiuntive. Questo progetto è un banco di prova per eventuali aggiunte future java.time. Si possono trovare alcune classi utili, come per esempio Interval , YearWeek , YearQuarter , e informazioni .


Joda Time

UPDATE: Il Joda Time progetto è ora in modalità di manutenzione , con il team di consulenza migrazione al classi java.time . Lascio questa sezione intatto per la storia.

La biblioteca Joda-Time utilizza ISO 8601 per le sue inadempienze. La sua classe Period analizza e genera questi PnYnMnDTnHnMnS stringhe.

DateTime now = DateTime.now(); // Caveat: Ignoring the important issue of time zones.
Period period = new Period( now, now.plusHours( 4 ).plusMinutes( 30));
System.out.println( "period: " + period );

Renders:

period: PT4H30M
Days d = Days.daysBetween(startDate, endDate);
int days = d.getDays();

https://www.joda.org/joda-time/faq .html # datediff

Un'alternativa leggermente più semplice:

System.currentTimeMillis() - oldDate.getTime()

Per quanto riguarda il "più bello": bene, che cosa esattamente avete bisogno? Il problema di rappresentare durate di tempo come un certo numero di ore e di giorni, ecc è che si può portare a imprecisioni ed aspettative sbagliate a causa della complessità di date (ad esempio giorni possono avere 23 o 25 ore a causa di ora legale).

Utilizzando approccio millisecondo può causare problemi in alcuni locali.

Consente di prendere, per esempio, la differenza tra le due date 03/24/2007 e 2007/03/25 dovrebbe essere 1 giorno;

Tuttavia, utilizzando il percorso millisecondo, si otterrà 0 giorni, se si esegue questo nel Regno Unito!

/** Manual Method - YIELDS INCORRECT RESULTS - DO NOT USE**/  
/* This method is used to find the no of days between the given dates */  
public long calculateDays(Date dateEarly, Date dateLater) {  
   return (dateLater.getTime() - dateEarly.getTime()) / (24 * 60 * 60 * 1000);  
} 

Modo migliore per implementare questo è quello di utilizzare java.util.Calendar

/** Using Calendar - THE CORRECT WAY**/  
public static long daysBetween(Calendar startDate, Calendar endDate) {  
  Calendar date = (Calendar) startDate.clone();  
  long daysBetween = 0;  
  while (date.before(endDate)) {  
    date.add(Calendar.DAY_OF_MONTH, 1);  
    daysBetween++;  
  }  
  return daysBetween;  
}  

Ci sono molti modi in cui puoi trovare la differenza tra date e orari. Uno dei modi più semplici di che so potrebbe essere:

      Calendar calendar1 = Calendar.getInstance();
      Calendar calendar2 = Calendar.getInstance();
      calendar1.set(2012, 04, 02);
      calendar2.set(2012, 04, 04);
      long milsecs1= calendar1.getTimeInMillis();
      long milsecs2 = calendar2.getTimeInMillis();
      long diff = milsecs2 - milsecs1;
      long dsecs = diff / 1000;
      long dminutes = diff / (60 * 1000);
      long dhours = diff / (60 * 60 * 1000);
      long ddays = diff / (24 * 60 * 60 * 1000);

      System.out.println("Your Day Difference="+ddays);

L'istruzione print è solo un esempio - è possibile formattare esso, come piace a

.

Dal momento che tutte le risposte qui sono corretti ma usare Java legacy o 3rd librerie parti come Joda o simili, mi limiterò a cadere un altro modo utilizzando la nuova java.time classi in Java 8 e versioni successive. Vedere Oracle Tutorial .

LocalDate e ChronoUnit :

LocalDate d1 = LocalDate.of(2017, 5, 1);
LocalDate d2 = LocalDate.of(2017, 5, 18);

long days = ChronoUnit.DAYS.between(d1, d2);
System.out.println( days );

Sottraendo le date in millisecondi funziona (come descritto in un altro post), ma sono per usare HOUR_OF_DAY e non ora in cui eliminare le parti temporali le date:

public static final long MSPERDAY = 60 * 60 * 24 * 1000;
...
final Calendar dateStartCal = Calendar.getInstance();
dateStartCal.setTime(dateStart);
dateStartCal.set(Calendar.HOUR_OF_DAY, 0); // Crucial.
dateStartCal.set(Calendar.MINUTE, 0);
dateStartCal.set(Calendar.SECOND, 0);
dateStartCal.set(Calendar.MILLISECOND, 0);
final Calendar dateEndCal = Calendar.getInstance();
dateEndCal.setTime(dateEnd);
dateEndCal.set(Calendar.HOUR_OF_DAY, 0); // Crucial.
dateEndCal.set(Calendar.MINUTE, 0);
dateEndCal.set(Calendar.SECOND, 0);
dateEndCal.set(Calendar.MILLISECOND, 0);
final long dateDifferenceInDays = ( dateStartCal.getTimeInMillis()
                                  - dateEndCal.getTimeInMillis()
                                  ) / MSPERDAY;
if (dateDifferenceInDays > 15) {
    // Do something if difference > 15 days
}

Se non si desidera utilizzare JodaTime o simili, la soluzione migliore è probabilmente questo:

final static long MILLIS_PER_DAY = 24 * 3600 * 1000;
long msDiff= date1.getTime() - date2.getTime();
long daysDiff = Math.round(msDiff / ((double)MILLIS_PER_DAY));

Il numero di ms al giorno non è sempre lo stesso (a causa di ora legale e saltare secondi), ma è molto vicino, e almeno deviazioni a causa di ora legale annullano per periodi più lunghi. Pertanto dividendo e quindi arrotondamento darà un risultato corretto (almeno fino a quando il calendario locale utilizzata non contiene tempo strano salta altro che l'ora legale e saltare secondi).

Si noti che questo assume ancora che date1 e date2 sono impostati sulla stessa ora del giorno. Per diversi momenti della giornata, devi prima necessario definire che cosa "differenza data" si intende, come ha sottolineato Jon Skeet.

Date un'occhiata a Joda Tempo , che è una data migliore / ora API per Java e dovrebbe funzionare bene con Scala.

Mi permetta di mostrare differenza tra Joda Intervallo e Giorni:

DateTime start = new DateTime(2012, 2, 6, 10, 44, 51, 0);
DateTime end = new DateTime(2012, 2, 6, 11, 39, 47, 1);
Interval interval = new Interval(start, end);
Period period = interval.toPeriod();
System.out.println(period.getYears() + " years, " + period.getMonths() + " months, " + period.getWeeks() + " weeks, " + period.getDays() + " days");
System.out.println(period.getHours() + " hours, " + period.getMinutes() + " minutes, " + period.getSeconds() + " seconds ");
//Result is:
//0 years, 0 months, *1 weeks, 1 days*
//0 hours, 54 minutes, 56 seconds 

//Period can set PeriodType,such as PeriodType.yearMonthDay(),PeriodType.yearDayTime()...
Period p = new Period(start, end, PeriodType.yearMonthDayTime());
System.out.println(p.getYears() + " years, " + p.getMonths() + " months, " + p.getWeeks() + " weeks, " + p.getDays() + "days");
System.out.println(p.getHours() + " hours, " + p.getMinutes() + " minutes, " + p.getSeconds() + " seconds ");
//Result is:
//0 years, 0 months, *0 weeks, 8 days*
//0 hours, 54 minutes, 56 seconds 

Se avete bisogno di una stringa formattata come ritorno "2 Giorni 07s 03h 42m", provate questo:

public String fill2(int value)
{
    String ret = String.valueOf(value);

    if (ret.length() < 2)
        ret = "0" + ret;            
    return ret;
}

public String get_duration(Date date1, Date date2)
{                   
    TimeUnit timeUnit = TimeUnit.SECONDS;

    long diffInMilli = date2.getTime() - date1.getTime();
    long s = timeUnit.convert(diffInMilli, TimeUnit.MILLISECONDS);

    long days = s / (24 * 60 * 60);
    long rest = s - (days * 24 * 60 * 60);
    long hrs = rest / (60 * 60);
    long rest1 = rest - (hrs * 60 * 60);
    long min = rest1 / 60;      
    long sec = s % 60;

    String dates = "";
    if (days > 0) dates = days + " Days ";

    dates += fill2((int) hrs) + "h ";
    dates += fill2((int) min) + "m ";
    dates += fill2((int) sec) + "s ";

    return dates;
}

Controlla esempio qui http://www.roseindia.net/java/beginners/DateDifferent .shtml Questo esempio vi darà differenza di giorni, ore, minuti, secondi e Milli sec di:.)

import java.util.Calendar;
import java.util.Date;

public class DateDifferent {
    public static void main(String[] args) {
        Date date1 = new Date(2009, 01, 10);
        Date date2 = new Date(2009, 07, 01);
        Calendar calendar1 = Calendar.getInstance();
        Calendar calendar2 = Calendar.getInstance();
        calendar1.setTime(date1);
        calendar2.setTime(date2);
        long milliseconds1 = calendar1.getTimeInMillis();
        long milliseconds2 = calendar2.getTimeInMillis();
        long diff = milliseconds2 - milliseconds1;
        long diffSeconds = diff / 1000;
        long diffMinutes = diff / (60 * 1000);
        long diffHours = diff / (60 * 60 * 1000);
        long diffDays = diff / (24 * 60 * 60 * 1000);
        System.out.println("\nThe Date Different Example");
        System.out.println("Time in milliseconds: " + diff + " milliseconds.");
        System.out.println("Time in seconds: " + diffSeconds + " seconds.");
        System.out.println("Time in minutes: " + diffMinutes + " minutes.");
        System.out.println("Time in hours: " + diffHours + " hours.");
        System.out.println("Time in days: " + diffDays + " days.");
    }
}

Usa GMT fuso orario per ottenere un'istanza del calendario, impostare il tempo utilizzando il metodo set di classe Calendar. Il fuso orario GMT ha 0 compensato (non veramente importante) e l'ora legale bandiera impostato su false.

    final Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));

    cal.set(Calendar.YEAR, 2011);
    cal.set(Calendar.MONTH, 9);
    cal.set(Calendar.DAY_OF_MONTH, 29);
    cal.set(Calendar.HOUR, 0);
    cal.set(Calendar.MINUTE, 0);
    cal.set(Calendar.SECOND, 0);
    final Date startDate = cal.getTime();

    cal.set(Calendar.YEAR, 2011);
    cal.set(Calendar.MONTH, 12);
    cal.set(Calendar.DAY_OF_MONTH, 21);
    cal.set(Calendar.HOUR, 0);
    cal.set(Calendar.MINUTE, 0);
    cal.set(Calendar.SECOND, 0);
    final Date endDate = cal.getTime();

    System.out.println((endDate.getTime() - startDate.getTime()) % (1000l * 60l * 60l * 24l));

A seguito di codice può dare l'output desiderato:

String startDate = "Jan 01 2015";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMM dd yyyy");
LocalDate date = LocalDate.parse(startDate, formatter);

String currentDate = "Feb 11 2015";
LocalDate date1 = LocalDate.parse(currentDate, formatter);

System.out.println(date1.toEpochDay() - date.toEpochDay());
public static String getDifferenceBtwTime(Date dateTime) {

    long timeDifferenceMilliseconds = new Date().getTime() - dateTime.getTime();
    long diffSeconds = timeDifferenceMilliseconds / 1000;
    long diffMinutes = timeDifferenceMilliseconds / (60 * 1000);
    long diffHours = timeDifferenceMilliseconds / (60 * 60 * 1000);
    long diffDays = timeDifferenceMilliseconds / (60 * 60 * 1000 * 24);
    long diffWeeks = timeDifferenceMilliseconds / (60 * 60 * 1000 * 24 * 7);
    long diffMonths = (long) (timeDifferenceMilliseconds / (60 * 60 * 1000 * 24 * 30.41666666));
    long diffYears = (long)(timeDifferenceMilliseconds / (1000 * 60 * 60 * 24 * 365));

    if (diffSeconds < 1) {
        return "one sec ago";
    } else if (diffMinutes < 1) {
        return diffSeconds + " seconds ago";
    } else if (diffHours < 1) {
        return diffMinutes + " minutes ago";
    } else if (diffDays < 1) {
        return diffHours + " hours ago";
    } else if (diffWeeks < 1) {
        return diffDays + " days ago";
    } else if (diffMonths < 1) {
        return diffWeeks + " weeks ago";
    } else if (diffYears < 12) {
        return diffMonths + " months ago";
    } else {
        return diffYears + " years ago";
    }
}   

Nota: startDate e endDates sono -> java.util.Date

import org.joda.time.Duration;
import org.joda.time.Interval;
// Use .getTime() unless it is a joda DateTime object
Interval interval = new Interval(startDate.getTime(), endDate.getTime());
Duration period = interval.toDuration();
//gives the number of days elapsed between start 
period.getStandardDays();

e la data di fine

Simile a giorni, è anche possibile ottenere ore, minuti e secondi

period.getStandardHours();
period.getStandardMinutes();
period.getStandardSeconds();
int daysDiff = (date1.getTime() - date2.getTime()) / MILLIS_PER_DAY;

La cosa migliore da fare è

(Date1-Date2)/86 400 000 

Questo numero è il numero di millisecondi in un giorno.

Una data data-altro ti dà differenza in millisecondi.

Raccogli la risposta in un variabile doppia.

Questo è probabilmente il modo più semplice per farlo - forse è perché ho la codifica in Java (con i suoi data e ora librerie certamente goffo) per un po 'di tempo, ma che il codice sembra "semplice e piacevole" per me!

Sei felice con il risultato di essere restituito in millisecondi, o fa parte della tua domanda che si preferisce averlo restituito in un formato alternativo?

Non utilizzando l'API standard, no. Si può rotolare il proprio fare qualcosa di simile:

class Duration {
    private final TimeUnit unit;
    private final long length;
    // ...
}

In alternativa è possibile utilizzare Joda :

DateTime a = ..., b = ...;
Duration d = new Duration(a, b);

Proprio per rispondere alla domanda iniziale:

Inserire il codice seguente in una funzione come lungo getAge () {}

Date dahora = new Date();
long MillisToYearsByDiv = 1000l *60l * 60l * 24l * 365l;
long javaOffsetInMillis = 1990l * MillisToYearsByDiv;
long realNowInMillis = dahora.getTime() + javaOffsetInMillis;
long realBirthDayInMillis = this.getFechaNac().getTime() + javaOffsetInMillis;
long ageInMillis = realNowInMillis - realBirthDayInMillis;

return ageInMillis / MillisToYearsByDiv;

Il più importante è quello di lavorare con i numeri lunghi quando moltiplicazione e divisione. E, naturalmente, l'offset che Java si applica nella sua calcolo delle date.

:)

Dato che la questione è codificata con Scala,

import scala.concurrent.duration._
val diff = (System.currentTimeMillis() - oldDate.getTime).milliseconds
val diffSeconds = diff.toSeconds
val diffMinutes = diff.toMinutes
val diffHours = diff.toHours
val diffDays = diff.toDays

Ecco una soluzione corretta Java 7 in O (1) senza dipendenze.

public static int countDaysBetween(Date date1, Date date2) {

    Calendar c1 = removeTime(from(date1));
    Calendar c2 = removeTime(from(date2));

    if (c1.get(YEAR) == c2.get(YEAR)) {

        return Math.abs(c1.get(DAY_OF_YEAR) - c2.get(DAY_OF_YEAR)) + 1;
    }
    // ensure c1 <= c2
    if (c1.get(YEAR) > c2.get(YEAR)) {
        Calendar c = c1;
        c1 = c2;
        c2 = c;
    }
    int y1 = c1.get(YEAR);
    int y2 = c2.get(YEAR);
    int d1 = c1.get(DAY_OF_YEAR);
    int d2 = c2.get(DAY_OF_YEAR);

    return d2 + ((y2 - y1) * 365) - d1 + countLeapYearsBetween(y1, y2) + 1;
}

private static int countLeapYearsBetween(int y1, int y2) {

    if (y1 < 1 || y2 < 1) {
        throw new IllegalArgumentException("Year must be > 0.");
    }
    // ensure y1 <= y2
    if (y1 > y2) {
        int i = y1;
        y1 = y2;
        y2 = i;
    }

    int diff = 0;

    int firstDivisibleBy4 = y1;
    if (firstDivisibleBy4 % 4 != 0) {
        firstDivisibleBy4 += 4 - (y1 % 4);
    }
    diff = y2 - firstDivisibleBy4 - 1;
    int divisibleBy4 = diff < 0 ? 0 : diff / 4 + 1;

    int firstDivisibleBy100 = y1;
    if (firstDivisibleBy100 % 100 != 0) {
        firstDivisibleBy100 += 100 - (firstDivisibleBy100 % 100);
    }
    diff = y2 - firstDivisibleBy100 - 1;
    int divisibleBy100 = diff < 0 ? 0 : diff / 100 + 1;

    int firstDivisibleBy400 = y1;
    if (firstDivisibleBy400 % 400 != 0) {
        firstDivisibleBy400 += 400 - (y1 % 400);
    }
    diff = y2 - firstDivisibleBy400 - 1;
    int divisibleBy400 = diff < 0 ? 0 : diff / 400 + 1;

    return divisibleBy4 - divisibleBy100 + divisibleBy400;
}


public static Calendar from(Date date) {

    Calendar c = Calendar.getInstance();
    c.setTime(date);

    return c;
}


public static Calendar removeTime(Calendar c) {

    c.set(HOUR_OF_DAY, 0);
    c.set(MINUTE, 0);
    c.set(SECOND, 0);
    c.set(MILLISECOND, 0);

    return c;
}

Dopo guadare attraverso tutte le altre risposte, per mantenere il tipo di Data Java 7, ma essere più precisi / serie con l'approccio diff Java 8,

public static long daysBetweenDates(Date d1, Date d2) {
    Instant instant1 = d1.toInstant();
    Instant instant2 = d2.toInstant();
    long diff = ChronoUnit.DAYS.between(instant1, instant2);
    return diff;
}

provare questo:

int epoch = (int) (new java.text.SimpleDateFormat("MM/dd/yyyy HH:mm:ss").parse("01/01/1970  00:00:00").getTime() / 1000);

è possibile modificare la stringa nel parse () metodi param.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top