Pergunta

Estou usando o Java's java.util.Date classe em scala e deseja comparar um Date objeto e a hora atual. Eu sei que posso calcular o delta usando gettime ():

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

No entanto, isso me deixa com um long representando milissegundos. Existe alguma maneira mais simples e melhor de obter um Delta Time?

Foi útil?

Solução

O JDK Date A API está terrivelmente quebrada, infelizmente. Eu recomendo usar Biblioteca de Time Joda.

Joda Time tem um conceito de tempo Intervalo:

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

EDIT: A propósito, Joda tem dois conceitos: Interval por representar um intervalo de tempo entre dois instantes de tempo (representar o tempo entre as 8h e as 10h) e um Duration Isso representa um período de tempo sem os limites do tempo real (por exemplo, representa duas horas!)

Se você se preocupa apenas com comparações de tempo, a maioria Date implementações (incluindo o JDK One) implementos Comparable interface que permite que você use o Comparable.compareTo()

Outras dicas

Diff simples (sem 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 então você pode ligar:

getDateDiff(date1,date2,TimeUnit.MINUTES);

Para obter o diferencial das 2 datas em minutos de minutos.

TimeUnit é java.util.concurrent.TimeUnit, um enum java padrão que vai de nanos para dias.


Diff legível humano (sem 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

A saída é algo como Map:{DAYS=1, HOURS=3, MINUTES=46, SECONDS=40, MILLISECONDS=0, MICROSECONDS=0, NANOSECONDS=0}, com as unidades ordenadas.

Você só precisa converter esse mapa em uma string amigável.


Aviso

Os trechos de código acima calculam um diferencial simples entre 2 instantes. Pode causar problemas durante um interruptor de poupança do dia, como explicado em esta postagem. Isso significa que, se você calcular o diferencial entre as datas, sem tempo, poderá ter um dia/hora perdido.

Na minha opinião, a data diferencia é meio subjetiva, especialmente em dias. Você pode:

  • Conte o número de 24h tempo decorrido: dia+1 - dia = 1 dia = 24h

  • Conte o número de tempo decorrido, cuidando das economias do dia: dia+1 - dia = 1 = 24h (mas usando a meia -noite e a economia do dia pode ser de 0 dias e 23h)

  • contar o número de day switches, que significa dia+1 13:00 - dia 11h = 1 dia, mesmo que o tempo decorrido seja apenas 2h (ou 1h se houver um dia de verão: P)

Minha resposta é válida se sua definição de data diferenciado nos dias corresponde ao primeiro caso

Com jodatime

Se você estiver usando o Jodatime, poderá obter o Diff por 2 instantes (Millies apoiados em readnagenas) datas com:

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

Mas você também pode obter o diferencial para as datas/horários locais:

// 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) )

Observe que isso funciona com as datas do UTC, portanto a diferença pode ser um dia de folga se você olhar para as datas locais. E fazê -lo funcionar corretamente com datas locais requer uma abordagem completamente diferente devido ao horário de verão.

Você precisa definir seu problema com mais clareza. Você poderia Basta pegar o número de milissegundos entre os dois Date Objetos e dividir pelo número de milissegundos em 24 horas, por exemplo ... mas:

  • Isso não levará em consideração as zonas de tempo - Date está sempre no UTC
  • Isso não levará em consideração o horário de verão (onde pode haver dias que têm apenas 23 horas de duração, por exemplo)
  • Mesmo dentro da UTC, quantos dias existem nas 16 de agosto às 23h a 18 de agosto 2h? Faltam apenas 27 horas, isso significa um dia? Ou deve -se três dias porque abrange três datas?

Usando o Java.Time estrutura incorporada em 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());

Resultado:

ISO-8601: PT24H10M

Minutos: 1450

Para mais informações, consulte o Oracle Tutorial e a ISO 8601 padrão.

tl; dr

Converta seu obsoleto java.util.Date objetos para sua substituição, java.time.Instant. Em seguida, calcule o tempo decorrido como um 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

Formato ISO 8601: PnYnMnDTnHnMnS

O padrão sensível ISO 8601 define uma representação textual concisa de um período de tempo como vários anos, meses, dias, horas etc. O padrão chama tal extensão duração. O formato é PnYnMnDTnHnMnS onde o P significa "período", o T Separa a parte da data da parte do tempo e, entre os números, seguidos por uma letra.

Exemplos:

  • P3Y6M4DT12H30M5S
    três anos, seis meses, quatro dias, doze horas, trinta minutos e cinco segundos
  • PT4H30M
    Quatro horas e meia

Java.Time

o Java.Time estrutura incorporada em java 8 e depois suplanta o velho problemático java.util.Date/java.util.Calendar Aulas. As novas classes são inspiradas pelo sucesso Joda-Time Framework, destinado a seu sucessor, semelhante em conceito, mas re-arquitetado. Definido por JSR 310. Estendido pelo Threeten-Extra projeto. Veja o Tutorial.

Momento

o Instant classe representa um momento na linha do tempo em UTC com uma resolução de nanossegundos (até nove (9) dígitos de uma fração decimal).

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

Melhor para evitar as aulas herdadas, como Date/Calendar. Mas se você precisar interromper com o código antigo ainda não atualizado para Java.Time, converta para frente e para trás. Ligue para novos métodos de conversão adicionados às classes antigas. Para se mudar de um java.util.Date para um Instant, ligar Date::toInstant.

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

Período de tempo

As aulas de Java.Time dividiram essa idéia de representar um período de tempo como vários anos, meses, dias, horas, minutos, segundos em duas metades:

  • Period Durante anos, meses, dias
  • Duration por dias, horas, minutos, segundos

Aqui está um exemplo.

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

Despejar para consolar.

Ambos Period e Duration use o ISO 8601 padrão para gerar uma representação de string de seu valor.

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

Agora: 2015-11-26T00: 46: 48.016-05: 00 [America/Montreal] ao futuro: 2015-11-26T00: 46: 48.016-05: 00 [America/Montreal] = Pt1H3M

Java 9 adiciona métodos a Duration Para obter a parte dos dias, parte das horas, parte de minutos e parte de segundos.

Você pode obter o número total de dias ou horas ou minutos ou segundos ou milissegundos ou nanossegundos em toda a duração.

long totalHours = duration.toHours();

Em Java 9 o Duration A classe recebe novos métodos Para devolver as várias partes de dias, horas, minutos, segundos, milissegundos/nanossegundos. Ligar para to…Part métodos: toDaysPart(), toHoursPart(), e assim por diante.

ChronoUnit

Se você se preocupa apenas com uma granularidade maior mais simples, como "número de dias decorridos", use o ChronoUnit enum.

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

Outro exemplo.

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

120


Sobre Java.Time

o Java.Time A estrutura é incorporada ao Java 8 e mais tarde. Essas aulas suplantam o velho problemático legado classes de data de data, como java.util.Date, Calendar, & SimpleDateFormat.

o Joda-Time Projeto, agora em Modo de manutenção, aconselha a migração para Java.Time.

Para saber mais, consulte o Oracle Tutorial. E Pesquise o excesso de pilha para muitos exemplos e explicações. Especificação é JSR 310.

Onde obter as aulas de Java.Time?

  • Java SE 8 e SE 9 e depois
    • Construídas em.
    • Parte da API Java padrão com uma implementação agrupada.
    • O Java 9 adiciona alguns recursos e correções menores.
  • Java SE 6 e SE 7
    • Grande parte da funcionalidade Java.Time está em volta para Java 6 e 7 em Threeten-Backport.
  • Android
    • o Threetenabp Adaptação do projeto Threeten-Backport (mencionado acima) para o Android especificamente.
    • Ver Como usar….

o Threeten-Extra O projeto estende Java.Time com classes adicionais. Este projeto é um terreno de prova para possíveis adições futuras ao Java.Time. Você pode encontrar algumas aulas úteis aqui, como Interval, YearWeek, YearQuarter, e mais.


Joda-Time

ATUALIZAÇÃO: O Joda-Time Projeto está agora em Modo de manutenção, com a equipe aconselhando a migração para o Java.Time Aulas. Deixo esta seção intacta para a história.

A Biblioteca Joda-Time usa a ISO 8601 para seus padrões. Seu Period A classe analisa e gera essas cordas pnynmndtnhnmns.

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 );

Renderiza:

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

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

Uma alternativa um pouco mais simples:

System.currentTimeMillis() - oldDate.getTime()

Quanto a "Gind": bem, o que exatamente você precisa? O problema de representar as durações do tempo como várias horas e dias etc. é que isso pode levar a imprecisões e expectativas erradas devido à complexidade das datas (por exemplo, dias podem ter 23 ou 25 horas devido ao horário de verão).

O uso da abordagem de milissegundos pode causar problemas em alguns locais.

Vamos tomar, por exemplo, a diferença entre as duas datas 03/24/2007 e 25/03/2007 deve ser 1 dia;

No entanto, usando a rota Millissegundo, você terá 0 dias, se você executar isso no Reino Unido!

/** 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);  
} 

Melhor maneira de implementar isso é usar 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;  
}  

Existem muitas maneiras de encontrar a diferença entre datas e horários. Uma das maneiras mais simples que eu conheço seria:

      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);

A declaração de impressão é apenas um exemplo - você pode formatá -la, da maneira que você gosta.

Como todas as respostas aqui estão corretas, mas use Java Legacy ou Libs de terceiros como Joda ou similar, vou cair de outra maneira usando o novo Java.Time Aulas em Java 8 e mais tarde. Ver Oracle Tutorial.

Usar 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 );

Subtrair as datas em milissegundos obras (conforme descrito em outro post), mas você tenho Para usar hour_of_day e não hora ao limpar as partes do tempo de suas datas:

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 você não quer usar Jodatime ou similar, a melhor solução é provavelmente a seguinte:

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

O número de MS por dia nem sempre é o mesmo (por causa do horário de verão e segundos de salto), mas é muito próximo e pelo menos desvios devido ao horário de verão cancelado por períodos mais longos. Portanto, a divisão e o arredondamento fornecerá um resultado correto (pelo menos enquanto o calendário local usado não contiver saltos de tempo estranhos além do DST e dos segundos de salto).

Observe que isso ainda assume que date1 e date2 estão definidos para a mesma hora do dia. Por diferentes horários do dia, você precisaria primeiro definir o que significa "diferença de data", conforme apontado por Jon Skeet.

Dar uma olhada em Joda Time, que é uma API de data/hora aprimorada para Java e deve funcionar bem com o Scala.

Deixe -me mostrar a diferença entre o intervalo Joda e os dias:

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 você precisar de uma string de retorno formatada como "2 dias 03h 42m 07s", tente o seguinte:

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;
}

Verifique o exemplo aqui http://www.roseindia.net/java/beginners/datedifferent.shtmlEste exemplo oferece diferença em dias, horas, minutos, segundo e Milli Sec's :).

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.");
    }
}

Use o fuso horário GMT para obter uma instância do calendário, defina o tempo usando o método definido da classe de calendário. O fuso horário da GMT tem 0 deslocamento (não é realmente importante) e o horário de verão definido como 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));

O código a seguir pode fornecer a saída desejada:

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 são -> 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 data de término

Semelhante aos dias, você também pode obter horas, minutos e segundos

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

A melhor coisa a fazer é

(Date1-Date2)/86 400 000 

Esse número é o número de milissegundos Em um dia.

Uma data-outra data dá a você diferença em milissegundos.

Colete a resposta em um em dobro variável.

Essa é provavelmente a maneira mais direta de fazê -lo - talvez seja porque eu tenho codificação em Java (com suas bibliotecas de data e hora reconhecidamente desajeitadas) há algum tempo, mas esse código parece "simples e agradável" para mim!

Você está feliz com o resultado devolvido em milissegundos ou faz parte da sua pergunta que você prefere retornar em algum formato alternativo?

Não usando a API padrão, não. Você pode rolar o seu próprio fazendo algo assim:

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

Ou você pode usar Joda:

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

Só para responder à pergunta inicial:

Coloque o seguinte código em uma função como long 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;

O mais importante aqui é trabalhar com números longos ao multiplicar e dividir. E, é claro, a compensação que Java aplica em seu cálculo de datas.

:)

Como a pergunta é marcada com 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

Aqui está uma solução Java 7 correta em O (1) sem dependências.

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;
}

Depois de percorrer todas as outras respostas, para manter o tipo Java 7 Date, mas seja mais preciso/padrão com a abordagem Java 8 Dif,

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;
}

Experimente isso:

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

Você pode editar a string nos métodos parse () param.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top