43083

Java: Easiest Way to Subtract Dates

Question:

I have created a class with two fields that need to be dates, start_date and date_passed. I have been researching the best way in java to have dates in a YYYY MM DD format that allows for easy date subtraction, and the ability to "make-up" a date, say in the future for example.

Example of what I'd like it to do...

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

So far, I've found plenty of ways to format dates using Calendars and Date classes, but have yet to find one that looks like it would work considering most dates end up as Strings. Any suggestions/small examples are greatly appreciated! Also, any links to examples would be awesome!

Answer1:

tl;dr

To move from one date to another by adding/subtracting a number of days.

LocalDate.now( ZoneId.of( "Pacific/Auckland" ) ) .minusDays( 5 )

To calculate the number of days, months, and years elapsed between two dates.

Period.between( start , stop )

Parsing

First you must parse your string inputs into date-time objects. Then you work on preforming your <a href="https://en.wikipedia.org/wiki/Business_logic" rel="nofollow">business logic</a> with those objects.

Stop thinking of date-time values as strings, that will drive you nuts. We work with date-time objects in our code; we exchange data with users or other apps using a String representation of that date-time object.

In Java 8 and later, use the <a href="http://docs.oracle.com/javase/8/docs/api/java/time/package-summary.html" rel="nofollow">java.time</a> framework. See <a href="http://docs.oracle.com/javase/tutorial/datetime/TOC.html" rel="nofollow">Tutorial</a>.

You want only a date, without time-of-day, so we can use the <a href="http://docs.oracle.com/javase/8/docs/api/java/time/LocalDate.html" rel="nofollow">LocalDate</a> class.

That funky double-colon syntax is a <a href="http://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html" rel="nofollow">method reference</a>, a way to say what method should be called by other code.

String input = "2015 01 02"; DateTimeFormatter formatter = DateTimeFormatter.ofPattern ( "yyyy MM dd" ); LocalDate localDate = formatter.parse ( input , LocalDate :: from );

Current date

Determining today’s date requires a time zone. For any given moment, the date varies around the globe by zone.

ZoneId z = ZoneId.of( "Africa/Tunis" ) ; LocalDate todayTunis = LocalDate.now( z ) ;

If you want the JVM’s current default time zone, call ZoneId.systemDefault.

Subtracting Dates

This has been addressed many times before on StackOveflow.com. For example, <a href="https://stackoverflow.com/q/212321/642706" rel="nofollow">How to subtract X days from a date using Java calendar?</a>. For details, see other Answers such as <a href="https://stackoverflow.com/a/33530885/642706" rel="nofollow">this one by me</a> and <a href="https://stackoverflow.com/a/21273477/642706" rel="nofollow">this one by me</a> for more details. Tip: "elapsed" is a key search word.

Briefly, use a <a href="http://docs.oracle.com/javase/8/docs/api/java/time/Period.html" rel="nofollow">Period</a> to define a number of standard days, months, and years.

LocalDate weekLater = localDate.plusDays ( 7 ); Period period = Period.between ( localDate , weekLater ); Integer daysElapsed = period.getDays ();

Dump to console.

System.out.println ( "localDate: " + localDate + " to " + weekLater + " in days: " + daysElapsed ); <blockquote>

localDate: 2015-01-02 to 2015-01-09 in days: 7

</blockquote>

Note the limitation that Period works only with whole days, that is, date-only values without time-of-day. That is what we need here for this Question, so job done. If you had date-time values (ZonedDateTime objects), use the <a href="http://www.threeten.org/threeten-extra/" rel="nofollow">ThreeTen-Extra</a> project’s Days class as noted in linked Question/Answer above.

Answer2:

<strong>The best way to do this in Java-8 is not the flawed answer of Basil Bourque but this approach:</strong>

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)

The suggested use of java.time.Period.getDays() is dangerous and often wrong as soon as the elapsed duration exceeds one month. The whole Period is P1M27D so this code effectively only queries the partial amount of elapsed days (there is also an elapsed month):

System.out.println(Period.between(date1, date2).getDays()); // 27 (WRONG!!!)

<strong>A satisfying solution using the classes java.util.Date, GregorianCalendar etc. is hard to find.</strong> You can use the answer of Tacktheritrix but have to be aware of the fact that the calculated count of elapsed days might differ due to the sub-day-parts of java.util.Date and is also not reliable because of ignoring day-light-saving switches (where the clock jumps by one hour in many parts of the world).

Side note: At least <strong>8 external libraries</strong> offer good answers to your problem, too. But I think, your simple use-case does not justify the embedding of an extra library unless you are not yet on Java-8. Any alternative solution how to count the elapsed days between two dates would not be easier than in Java-8 - only similar. And since you accepted the Java-8-related answer of Basil Bourque, I assume that you are indeed on Java-8 so I leave out the answer how to solve your problem with other libraries.

Answer3:

use java 8 date api or joda, no need for new inventions.

you can find some examples here: <a href="http://examples.javacodegeeks.com/core-java/java-8-datetime-api-tutorial/" rel="nofollow">http://examples.javacodegeeks.com/core-java/java-8-datetime-api-tutorial/</a>

Answer4:

Here's an answer using 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));

Answer5:

If you are stuck withan older java you can use 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

Recommend

  • Pad counter with leading 0 up to 9, then remove leading zero with php
  • How to install docker in docker container?
  • Custom jQuery Validation .addMethod
  • An AppBar application not working correctly in Windows 8.x/10 (desktop working area does not get red
  • iOS how to make a button run a code for another view controller?
  • Wrong state in Server Controls with same ID's when dynamically adding UserControl to UpdatePane
  • Change permission of a ZipEntry
  • Why I receive this error using componentWillReceiveProps?
  • What are recommended Core Graphics techniques for drawing very custom UITableViewCells
  • PhoneGap or Appcelerator Implementation
  • Adding a delete button in PHP on each row of a MySQL table
  • JQuery and PHP validation problem?
  • Selenium - how to switch to a different (login) window that is brought up?
  • Highlight special word in a TextBox
  • Highcharts Drawing a line with chart.renderer.path
  • How to assert page/tab/window title in Behat + Mink
  • MySQL - Filter records which date is biggest
  • iOS App crash issue `[UIWindow warpPoint:]`
  • Find corners of a rotated rectangle
  • Get name of days between two date in ios?
  • Why do you need 2 Javascript files for cross-platform Cordova plugin?
  • Does hibernate load two seprate copies of same instance if they are loaded twice from database?
  • Pandas vs matplotlib datetime
  • How to define something in JavaScript [closed]
  • PHPMailer return to AJAX
  • Neo4j…how to get a visual representation of my data?
  • Amazon Elastick BeanStalk error: Failed to create the AWS Elastic Beanstalk application version
  • DataTables move rows between tables
  • How to clear a browser cache in Protractor
  • `$http:badreq Bad Request Configuration` - from angular post method, what is wrong here?
  • How to decleare char *const argv[] in swift [duplicate]
  • php “page caching” solution suggestions for CMS Applications
  • Bitrate JWplayer
  • Make checkout phone field optional for specific countries in WooCommerce
  • Grails - How to implement a foreign key relationship not using an id column?
  • Call Microservice from another Microservice within Docker
  • Accessing Arguments, Workflow Variables from custom activities
  • Jersey serializes character value to ASCII equivalent numeric string
  • CAS 4 - Not able to retrieve the LDAP groups after successful authentication
  • What does the “id” field in an Android “Google Play Music” broadcast intent correspond to?