Obtengo la fecha actual (en formato 31/12/1999, es decir, mm / dd / aaaa) usando el siguiente código:
Textview txtViewData;
txtViewDate.setText("Today is " +
android.text.format.DateFormat.getDateFormat(this).format(new Date()));
y tengo otra fecha en el formato: 2010-08-25 (es decir, aaaa / mm / dd),
así que quiero encontrar la diferencia entre la fecha y el número de días, ¿cómo puedo encontrar la diferencia en días?
(En otras palabras, quiero encontrar la diferencia entre FECHA ACTUAL - fecha formateada aaaa / mm / dd )
Respuestas:
No es realmente un método confiable, es mejor usar JodaTime
Calendar thatDay = Calendar.getInstance(); thatDay.set(Calendar.DAY_OF_MONTH,25); thatDay.set(Calendar.MONTH,7); // 0-11 so 1 less thatDay.set(Calendar.YEAR, 1985); Calendar today = Calendar.getInstance(); long diff = today.getTimeInMillis() - thatDay.getTimeInMillis(); //result in millis
Aquí hay una aproximación ...
long days = diff / (24 * 60 * 60 * 1000);
Para analizar la fecha de una cadena, puede usar
String strThatDay = "1985/08/25"; SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd"); Date d = null; try { d = formatter.parse(strThatDay);//catch exception } catch (ParseException e) { // TODO Auto-generated catch block e.printStackTrace(); } Calendar thatDay = Calendar.getInstance(); thatDay.setTime(d); //rest is the same....
Aunque, ya que está seguro del formato de fecha ... También podría hacerlo
Integer.parseInt()
en sus subcadenas para obtener sus valores numéricos.fuente
("yyyy/mm/dd");
debería reemplazarse por("yyyy/MM/dd");
Es M mayúscula para el mes, minúscula para los minutos. Corregido.Math.round(millisBetweenDates * 1f / TimeUnit.MILLISECONDS.convert(1, TimeUnit.DAYS));
Este NO es mi trabajo, encontré la respuesta aquí . no quería un enlace roto en el futuro :).
La clave es esta línea para tener en cuenta la configuración de la luz del día, ref. Código completo.
TimeZone.setDefault(TimeZone.getTimeZone("Europe/London"));
o intente pasar
TimeZone
como parámetrodaysBetween()
y llamarsetTimeZone()
a los objetossDate
yeDate
.Así que aquí va:
public static Calendar getDatePart(Date date){ Calendar cal = Calendar.getInstance(); // get calendar instance cal.setTime(date); cal.set(Calendar.HOUR_OF_DAY, 0); // set hour to midnight cal.set(Calendar.MINUTE, 0); // set minute in hour cal.set(Calendar.SECOND, 0); // set second in minute cal.set(Calendar.MILLISECOND, 0); // set millisecond in second return cal; // return the date part }
getDatePart () tomado de aquí
/** * This method also assumes endDate >= startDate **/ public static long daysBetween(Date startDate, Date endDate) { Calendar sDate = getDatePart(startDate); Calendar eDate = getDatePart(endDate); long daysBetween = 0; while (sDate.before(eDate)) { sDate.add(Calendar.DAY_OF_MONTH, 1); daysBetween++; } return daysBetween; }
Los matices: Encontrar la diferencia entre dos fechas no es tan sencillo como restar las dos fechas y dividir el resultado entre (24 * 60 * 60 * 1000). De hecho, ¡es erróneo!
Por ejemplo: la diferencia entre las dos fechas 24/03/2007 y 25/03/2007 debe ser de 1 día; Sin embargo, utilizando el método anterior, en el Reino Unido, ¡obtendrá 0 días!
Compruébelo usted mismo (código a continuación). Seguir el camino de los milisegundos conducirá a redondear los errores y se volverán más evidentes una vez que tenga algo como el horario de verano.
Código completo:
import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.TimeZone; public class DateTest { public class DateTest { static SimpleDateFormat sdf = new SimpleDateFormat("dd-MMM-yyyy"); public static void main(String[] args) { TimeZone.setDefault(TimeZone.getTimeZone("Europe/London")); //diff between these 2 dates should be 1 Date d1 = new Date("01/01/2007 12:00:00"); Date d2 = new Date("01/02/2007 12:00:00"); //diff between these 2 dates should be 1 Date d3 = new Date("03/24/2007 12:00:00"); Date d4 = new Date("03/25/2007 12:00:00"); Calendar cal1 = Calendar.getInstance();cal1.setTime(d1); Calendar cal2 = Calendar.getInstance();cal2.setTime(d2); Calendar cal3 = Calendar.getInstance();cal3.setTime(d3); Calendar cal4 = Calendar.getInstance();cal4.setTime(d4); printOutput("Manual ", d1, d2, calculateDays(d1, d2)); printOutput("Calendar ", d1, d2, daysBetween(cal1, cal2)); System.out.println("---"); printOutput("Manual ", d3, d4, calculateDays(d3, d4)); printOutput("Calendar ", d3, d4, daysBetween(cal3, cal4)); } private static void printOutput(String type, Date d1, Date d2, long result) { System.out.println(type+ "- Days between: " + sdf.format(d1) + " and " + sdf.format(d2) + " is: " + result); } /** Manual Method - YIELDS INCORRECT RESULTS - DO NOT USE**/ /* This method is used to find the no of days between the given dates */ public static long calculateDays(Date dateEarly, Date dateLater) { return (dateLater.getTime() - dateEarly.getTime()) / (24 * 60 * 60 * 1000); } /** Using Calendar - THE CORRECT WAY**/ public static long daysBetween(Date startDate, Date endDate) { ... }
SALIDA:
fuente
La mayoría de las respuestas fueron buenas y adecuadas para su problema de
Sugiero este enfoque muy simple y directo que está garantizado para darle la diferencia correcta en cualquier zona horaria:
int difference= ((int)((startDate.getTime()/(24*60*60*1000)) -(int)(endDate.getTime()/(24*60*60*1000))));
¡Y eso es!
fuente
Utilice la API de jodatime
donde 'inicio' y 'final' son sus objetos DateTime . Para analizar sus cadenas de fecha en objetos DateTime, use el método parseDateTime
También hay una biblioteca JodaTime específica para Android .
fuente
Este fragmento representa el horario de verano y es O (1).
private final static long MILLISECS_PER_DAY = 24 * 60 * 60 * 1000; private static long getDateToLong(Date date) { return Date.UTC(date.getYear(), date.getMonth(), date.getDate(), 0, 0, 0); } public static int getSignedDiffInDays(Date beginDate, Date endDate) { long beginMS = getDateToLong(beginDate); long endMS = getDateToLong(endDate); long diff = (endMS - beginMS) / (MILLISECS_PER_DAY); return (int)diff; } public static int getUnsignedDiffInDays(Date beginDate, Date endDate) { return Math.abs(getSignedDiffInDays(beginDate, endDate)); }
fuente
Este es un cálculo simple y el mejor para mí y puede serlo para usted.
try { /// String CurrDate= "10/6/2013"; /// String PrvvDate= "10/7/2013"; Date date1 = null; Date date2 = null; SimpleDateFormat df = new SimpleDateFormat("M/dd/yyyy"); date1 = df.parse(CurrDate); date2 = df.parse(PrvvDate); long diff = Math.abs(date1.getTime() - date2.getTime()); long diffDays = diff / (24 * 60 * 60 * 1000); System.out.println(diffDays); } catch (Exception e1) { System.out.println("exception " + e1); }
fuente
La
Correct Way
respuesta de Sam Quest solo funciona si la primera fecha es anterior a la segunda. Además, devolverá 1 si las dos fechas están dentro de un solo día.Esta es la solución que mejor me funcionó. Al igual que la mayoría de las otras soluciones, seguiría mostrando resultados incorrectos dos días al año debido a una compensación de ahorro de luz en un día incorrecto.
private final static long MILLISECS_PER_DAY = 24 * 60 * 60 * 1000; long calculateDeltaInDays(Calendar a, Calendar b) { // Optional: avoid cloning objects if it is the same day if(a.get(Calendar.ERA) == b.get(Calendar.ERA) && a.get(Calendar.YEAR) == b.get(Calendar.YEAR) && a.get(Calendar.DAY_OF_YEAR) == b.get(Calendar.DAY_OF_YEAR)) { return 0; } Calendar a2 = (Calendar) a.clone(); Calendar b2 = (Calendar) b.clone(); a2.set(Calendar.HOUR_OF_DAY, 0); a2.set(Calendar.MINUTE, 0); a2.set(Calendar.SECOND, 0); a2.set(Calendar.MILLISECOND, 0); b2.set(Calendar.HOUR_OF_DAY, 0); b2.set(Calendar.MINUTE, 0); b2.set(Calendar.SECOND, 0); b2.set(Calendar.MILLISECOND, 0); long diff = a2.getTimeInMillis() - b2.getTimeInMillis(); long days = diff / MILLISECS_PER_DAY; return Math.abs(days); }
fuente
la mejor y más fácil forma de hacer esto
public int getDays(String begin) throws ParseException { long MILLIS_PER_DAY = 24 * 60 * 60 * 1000; SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy", Locale.ENGLISH); long begin = dateFormat.parse(begin).getTime(); long end = new Date().getTime(); // 2nd date want to compare long diff = (end - begin) / (MILLIS_PER_DAY); return (int) diff; }
fuente
tl; dr
ChronoUnit.DAYS.between( LocalDate.parse( "1999-12-28" ) , LocalDate.parse( "12/31/1999" , DateTimeFormatter.ofPattern( "MM/dd/yyyy" ) ) )
Detalles
Otras respuestas están desactualizadas. Las antiguas clases de fecha y hora incluidas con las primeras versiones de Java han demostrado estar mal diseñadas, ser confusas y problemáticas. Evítales.
java.time
El proyecto Joda-Time fue un gran éxito como reemplazo de esas clases antiguas. Estas clases proporcionaron la inspiración para el marco java.time integrado en Java 8 y versiones posteriores.
Gran parte de la funcionalidad de java.time se ha actualizado a Java 6 y 7 en ThreeTen-Backport y se ha adaptado aún más a Android en ThreeTenABP .
LocalDate
los
LocalDate
clase representa un valor de solo fecha sin hora del día y sin zona horaria.Analizar cadenas
Si sus cadenas de entrada están en formato estándar ISO 8601 , la
LocalDate
clase puede analizar directamente la cadena.LocalDate start = LocalDate.parse( "1999-12-28" );
Si no está en formato ISO 8601, defina un patrón de formato con
DateTimeFormatter
.String input = "12/31/1999"; DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "MM/dd/yyyy" ); LocalDate stop = LocalDate.parse( input , formatter );
Días transcurridos a través de
ChronoUnit
Ahora obtenga una cuenta de los días transcurridos entre ese par de
LocalDate
objetos. LaChronoUnit
enumeración calcula el tiempo transcurrido.long totalDays = ChronoUnit.DAYS.between( start , stop ) ;
Si no está familiarizado con las enumeraciones de Java, sepa que son mucho más poderosas y útiles que las enumeraciones convencionales en la mayoría de los otros lenguajes de programación. Consulte el
Enum
documento de la clase, el tutorial de Oracle y Wikipedia para obtener más información.Acerca de java.time
El marco java.time está integrado en Java 8 y versiones posteriores. Estas clases suplantar la vieja problemáticos heredados clases de fecha y hora como
java.util.Date
,Calendar
, ySimpleDateFormat
.El proyecto Joda-Time , ahora en modo de mantenimiento , aconseja la migración a las clases java.time .
Para obtener más información, consulte el tutorial de Oracle . Y busque Stack Overflow para obtener muchos ejemplos y explicaciones. La especificación es JSR 310 .
¿Dónde obtener las clases java.time?
El proyecto ThreeTen-Extra extiende java.time con clases adicionales. Este proyecto es un campo de pruebas para posibles adiciones futuras a java.time. Usted puede encontrar algunas clases útiles aquí, como
Interval
,YearWeek
,YearQuarter
, y más .fuente
Utilice las siguientes funciones:
/** * Returns the number of days between two dates. The time part of the * days is ignored in this calculation, so 2007-01-01 13:00 and 2007-01-02 05:00 * have one day inbetween. */ public static long daysBetween(Date firstDate, Date secondDate) { // We only use the date part of the given dates long firstSeconds = truncateToDate(firstDate).getTime()/1000; long secondSeconds = truncateToDate(secondDate).getTime()/1000; // Just taking the difference of the millis. // These will not be exactly multiples of 24*60*60, since there // might be daylight saving time somewhere inbetween. However, we can // say that by adding a half day and rounding down afterwards, we always // get the full days. long difference = secondSeconds-firstSeconds; // Adding half a day if( difference >= 0 ) { difference += SECONDS_PER_DAY/2; // plus half a day in seconds } else { difference -= SECONDS_PER_DAY/2; // minus half a day in seconds } // Rounding down to days difference /= SECONDS_PER_DAY; return difference; } /** * Truncates a date to the date part alone. */ @SuppressWarnings("deprecation") public static Date truncateToDate(Date d) { if( d instanceof java.sql.Date ) { return d; // java.sql.Date is already truncated to date. And raises an // Exception if we try to set hours, minutes or seconds. } d = (Date)d.clone(); d.setHours(0); d.setMinutes(0); d.setSeconds(0); d.setTime(((d.getTime()/1000)*1000)); return d; }
fuente
Hay una solución simple, que al menos para mí, es la única solución factible.
El problema es que todas las respuestas que veo que se lanzan, usando Joda, Calendario, Fecha o lo que sea, solo tienen en cuenta la cantidad de milisegundos. Terminan contando el número de ciclos de 24 horas entre dos fechas , en lugar del número real de días. . Entonces, algo desde el 1 de enero a las 11 p.m. hasta el 2 de enero a la 1 a.m. devolverá 0 días.
Para contar el número real de días entre
startDate
yendDate
, simplemente haga:// Find the sequential day from a date, essentially resetting time to start of the day long startDay = startDate.getTime() / 1000 / 60 / 60 / 24; long endDay = endDate.getTime() / 1000 / 60 / 60 / 24; // Find the difference, duh long daysBetween = endDay - startDay;
Esto devolverá "1" entre el 2 de enero y el 1 de enero. Si necesita contar el día de finalización, simplemente agregue 1 a
daysBetween
(necesitaba hacer eso en mi código ya que quería contar el número total de días en el rango).Esto es algo similar a lo que Daniel ha sugerido, pero supongo que es un código más pequeño.
fuente
Todas estas soluciones adolecen de uno de dos problemas. O la solución no es perfectamente precisa debido a errores de redondeo, días bisiestos y segundos, etc. o termina repitiendo el número de días entre sus dos fechas desconocidas.
Esta solución resuelve el primer problema y mejora el segundo en un factor de aproximadamente 365, mejor si sabe cuál es su rango máximo.
/** * @param thisDate * @param thatDate * @param maxDays * set to -1 to not set a max * @returns number of days covered between thisDate and thatDate, inclusive, i.e., counting both * thisDate and thatDate as an entire day. Will short out if the number of days exceeds * or meets maxDays */ public static int daysCoveredByDates(Date thisDate, Date thatDate, int maxDays) { //Check inputs if (thisDate == null || thatDate == null) { return -1; } //Set calendar objects Calendar startCal = Calendar.getInstance(); Calendar endCal = Calendar.getInstance(); if (thisDate.before(thatDate)) { startCal.setTime(thisDate); endCal.setTime(thatDate); } else { startCal.setTime(thatDate); endCal.setTime(thisDate); } //Get years and dates of our times. int startYear = startCal.get(Calendar.YEAR); int endYear = endCal.get(Calendar.YEAR); int startDay = startCal.get(Calendar.DAY_OF_YEAR); int endDay = endCal.get(Calendar.DAY_OF_YEAR); //Calculate the number of days between dates. Add up each year going by until we catch up to endDate. while (startYear < endYear && maxDays >= 0 && endDay - startDay + 1 < maxDays) { endDay += startCal.getActualMaximum(Calendar.DAY_OF_YEAR); //adds the number of days in the year startDate is currently in ++startYear; startCal.set(Calendar.YEAR, startYear); //reup the year } int days = endDay - startDay + 1; //Honor the maximum, if set if (maxDays >= 0) { days = Math.min(days, maxDays); } return days; }
Si necesita días entre fechas (sin incluir la última fecha), simplemente elimine
+ 1
cuando veaendDay - startDay + 1
.fuente
De otra forma:
public static int numberOfDaysBetweenDates(Calendar fromDay, Calendar toDay) { fromDay = calendarStartOfDay(fromDay); toDay = calendarStartOfDay(toDay); long from = fromDay.getTimeInMillis(); long to = toDay.getTimeInMillis(); return (int) TimeUnit.MILLISECONDS.toDays(to - from); }
fuente
usa estas funciones
public static int getDateDifference(int previousYear, int previousMonthOfYear, int previousDayOfMonth, int nextYear, int nextMonthOfYear, int nextDayOfMonth, int differenceToCount){ // int differenceToCount = can be any of the following // Calendar.MILLISECOND; // Calendar.SECOND; // Calendar.MINUTE; // Calendar.HOUR; // Calendar.DAY_OF_MONTH; // Calendar.MONTH; // Calendar.YEAR; // Calendar.---- Calendar previousDate = Calendar.getInstance(); previousDate.set(Calendar.DAY_OF_MONTH, previousDayOfMonth); // month is zero indexed so month should be minus 1 previousDate.set(Calendar.MONTH, previousMonthOfYear); previousDate.set(Calendar.YEAR, previousYear); Calendar nextDate = Calendar.getInstance(); nextDate.set(Calendar.DAY_OF_MONTH, previousDayOfMonth); // month is zero indexed so month should be minus 1 nextDate.set(Calendar.MONTH, previousMonthOfYear); nextDate.set(Calendar.YEAR, previousYear); return getDateDifference(previousDate,nextDate,differenceToCount); } public static int getDateDifference(Calendar previousDate,Calendar nextDate,int differenceToCount){ // int differenceToCount = can be any of the following // Calendar.MILLISECOND; // Calendar.SECOND; // Calendar.MINUTE; // Calendar.HOUR; // Calendar.DAY_OF_MONTH; // Calendar.MONTH; // Calendar.YEAR; // Calendar.---- //raise an exception if previous is greater than nextdate. if(previousDate.compareTo(nextDate)>0){ throw new RuntimeException("Previous Date is later than Nextdate"); } int difference=0; while(previousDate.compareTo(nextDate)<=0){ difference++; previousDate.add(differenceToCount,1); } return difference; }
fuente
java.time
paquete ahora es heredada y debe evitarse. Esto incluyeDate
yCalendar
, y las clases java.sql. Consulte el tutorial de Oracle.public void dateDifferenceExample() { // Set the date for both of the calendar instance GregorianCalendar calDate = new GregorianCalendar(2012, 10, 02,5,23,43); GregorianCalendar cal2 = new GregorianCalendar(2015, 04, 02); // Get the represented date in milliseconds long millis1 = calDate.getTimeInMillis(); long millis2 = cal2.getTimeInMillis(); // Calculate difference in milliseconds long diff = millis2 - millis1; // Calculate difference in seconds long diffSeconds = diff / 1000; // Calculate difference in minutes long diffMinutes = diff / (60 * 1000); // Calculate difference in hours long diffHours = diff / (60 * 60 * 1000); // Calculate difference in days long diffDays = diff / (24 * 60 * 60 * 1000); Toast.makeText(getContext(), ""+diffSeconds, Toast.LENGTH_SHORT).show(); }
fuente
Encontré una manera muy fácil de hacer esto y es lo que estoy usando en mi aplicación.
Digamos que tiene las fechas en los objetos Time (o lo que sea, solo necesitamos los milisegundos):
Time date1 = initializeDate1(); //get the date from somewhere Time date2 = initializeDate2(); //get the date from somewhere long millis1 = date1.toMillis(true); long millis2 = date2.toMillis(true); long difference = millis2 - millis1 ; //now get the days from the difference and that's it long days = TimeUnit.MILLISECONDS.toDays(difference); //now you can do something like if(days == 7) { //do whatever when there's a week of difference } if(days >= 30) { //do whatever when it's been a month or more }
fuente
Joda-Time
La mejor manera es utilizar Joda-Time , la biblioteca de código abierto de gran éxito que agregaría a su proyecto.
String date1 = "2015-11-11"; String date2 = "2013-11-11"; DateTimeFormatter formatter = new DateTimeFormat.forPattern("yyyy-MM-dd"); DateTime d1 = formatter.parseDateTime(date1); DateTime d2 = formatter.parseDateTime(date2); long diffInMillis = d2.getMillis() - d1.getMillis(); Duration duration = new Duration(d1, d2); int days = duration.getStandardDays(); int hours = duration.getStandardHours(); int minutes = duration.getStandardMinutes();
Si está utilizando Android Studio , es muy fácil agregar joda-time. En su build.gradle (aplicación):
dependencies { compile 'joda-time:joda-time:2.4' compile 'joda-time:joda-time:2.4' compile 'joda-time:joda-time:2.2' }
fuente
toString
enDuration
genera una representación de cadena en una de las ISO 8601 formatos estándar,PnYnMnDTnHnMnS
. ElP
marca el comienzo, mientras que elT
separa el año-mes-días de la hora-minutos-segundos. TambiénP3D
son tres días yP3DT12H
son tres días y medio.Date userDob = new SimpleDateFormat("yyyy-MM-dd").parse(dob); Date today = new Date(); long diff = today.getTime() - userDob.getTime(); int numOfDays = (int) (diff / (1000 * 60 * 60 * 24)); int hours = (int) (diff / (1000 * 60 * 60)); int minutes = (int) (diff / (1000 * 60)); int seconds = (int) (diff / (1000));
fuente