Java: la forma más fácil de restar fechas
date datepicker (5)
date_passed
una clase con dos campos que deben ser fechas, fecha de date_passed
y fecha de date_passed
. He estado investigando la mejor manera en Java para tener fechas en un formato YYYY MM DD
que permita una fácil resta de fecha, y la capacidad de "compensar" una fecha, digamos en el futuro, por ejemplo.
Ejemplo de lo que me gustaría que hiciera ...
library.circulate_book("Chemistry", **start date here**) //actual date or random date
library.pass_book("Chemistry", **Date Passed here**) //random date such as 5 days after start date
int days_had = Date_Passed - start_date
Hasta el momento, he encontrado muchas formas de formatear fechas usando calendarios y clases de fecha, pero todavía tengo que encontrar una que parezca que funcionaría teniendo en cuenta que la mayoría de las fechas terminan en cadenas. ¡Cualquier sugerencia / pequeño ejemplo es muy apreciado! ¡Además, cualquier enlace a ejemplos sería increíble!
Aquí hay una respuesta usando el Calendar
:
Calendar cal = Calendar.getInstance();
Calendar cal2 = Calendar.getInstance();
cal2.setTime(cal.getTime());
cal2.add(Calendar.DAY_OF_YEAR, 5);
System.out.println((cal2.getTimeInMillis() - cal.getTimeInMillis()) / (1000d * 60 * 60 * 24));
Si está atascado con Java más antiguo, puede usar SimpleDateFormat.
//For substraction
long differenceInMillis = date1.getTime() - date2.getTime();
//Date Format
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy MM dd");
String dateAsString = dateFormat.format(date1); //To get a text representation
Date dateParsed = dateFormat.parse(dateAsString); //To get it back as date
use java 8 date api o joda, sin necesidad de nuevos inventos.
Puede encontrar algunos ejemplos aquí: http://examples.javacodegeeks.com/core-java/java-8-datetime-api-tutorial/
La mejor manera de hacerlo en Java-8 no es la respuesta errónea de Basil Bourque, sino este enfoque:
String startDate = "2016 01 02";
String passedDate = "2016 02 29";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy MM dd");
LocalDate date1 = LocalDate.parse(startDate, formatter);
LocalDate date2 = LocalDate.parse(passedDate, formatter);
long elapsedDays = ChronoUnit.DAYS.between(date1, date2);
System.out.println(elapsedDays); // 58 (correct)
El uso sugerido de java.time.Period.getDays()
es peligroso y a menudo incorrecto tan pronto como la duración transcurra excede un mes. El Period
completo es P1M27D, por lo que este código solo consulta la cantidad parcial de días transcurridos (también hay un mes transcurrido):
System.out.println(Period.between(date1, date2).getDays()); // 27 (WRONG!!!)
Una solución satisfactoria que utiliza las clases java.util.Date
, GregorianCalendar
, etc. es difícil de encontrar. Puede usar la respuesta de Tacktheritrix, pero debe tener en cuenta que la cuenta calculada de los días transcurridos puede diferir debido a las partes por días de java.util.Date
y tampoco es confiable porque ignora la luz del día. interruptores de ahorro (donde el reloj salta por una hora en muchas partes del mundo).
Nota al margen: al menos 8 bibliotecas externas también ofrecen buenas respuestas a su problema. Pero creo que tu caso de uso simple no justifica la incorporación de una biblioteca adicional a menos que aún no estés en Java-8. Cualquier solución alternativa para contar los días transcurridos entre dos fechas no sería más fácil que en Java-8, solo que similar. Y dado que aceptó la respuesta de Basil Bourque relacionada con Java-8, supongo que está realmente en Java-8, por lo que dejo la respuesta de cómo resolver su problema con otras bibliotecas.
Parsing
Primero debe analizar sus entradas de cadena en objetos de fecha y hora. Luego trabajas en la preformación de tu lógica de negocios con esos objetos.
Deja de pensar en los valores de fecha y hora como cadenas, que te volverán loco. Trabajamos con objetos de fecha y hora en nuestro código; intercambiamos datos con usuarios u otras aplicaciones usando una representación de cadena de ese objeto de fecha y hora.
En Java 8 y posterior, use el framework java.time . Ver Tutorial .
Solo desea una fecha, sin hora del día, para que podamos usar la clase LocalDate
.
Esa sintaxis de dos puntos funky es una referencia de método , una forma de decir qué método debería llamar otro código.
String input = "2015 01 02";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern ( "yyyy MM dd" );
LocalDate localDate = formatter.parse ( input , LocalDate :: from );
Restar fechas
Esto ya se ha abordado muchas veces en StackOveflow.com. Por ejemplo, ¿Cómo restar X días de una fecha usando el calendario de Java? . Para más detalles, consulte otras respuestas como esta por mí y esta por mí para obtener más detalles. Consejo: "transcurrido" es una palabra clave de búsqueda.
En resumen, use un Period
para definir una cantidad de días, meses y años estándar.
LocalDate weekLater = localDate.plusDays ( 7 );
Period period = Period.between ( localDate , weekLater );
Integer daysElapsed = period.getDays ();
Volcado a la consola.
System.out.println ( "localDate: " + localDate + " to " + weekLater + " in days: " + daysElapsed );
localDate: 2015-01-02 a 2015-01-09 en días: 7
Tenga en cuenta la limitación de que Period
funciona solo con días completos, es decir, valores solo de fecha sin hora del día. Eso es lo que necesitamos aquí para esta Cuestión, para que se haga el trabajo. Si tenía valores de fecha y hora (objetos ZonedDateTime
), use la clase Days
del proyecto ThreeTen-Extra como se indica en la Pregunta / Respuesta vinculada anterior.