How to get right number of months and day between several dates?Java 8 calculate months between two datesGet Last Day of the Month in PythonHow to return only the Date from a SQL Server DateTime datatypeHow do you get a timestamp in JavaScript?Add days to JavaScript DateHow do I get the current date in JavaScript?Calculate difference between two dates (number of days)?How do servlets work? Instantiation, sessions, shared variables and multithreadingHow to format a JavaScript dateDifference in months between two datesGet current time and date on Android

Which is the best password hashing algorithm in .NET Core?

co-son-in-law or co-brother

How do I make my fill-in-the-blank exercise more obvious?

Tiny image scraper for xkcd.com

Count rook moves 1D

What's the difference between a share and a stock?

Does the Scrying spell require you to have a clear path to the target in order to work?

How will the UK Commons debate tonight despite the prorogation?

Is mathematics truth?

What exactly is a softlock?

Time to call the bluff

What is the most likely cause of short, quick, and useless reviews?

Is torque as fundamental a concept as force?

How to describe hit point damage without talking about wounds

Is the Levitate spell supposed to basically disable a melee-based enemy?

'This one' as a pronoun

Splitting polygons at narrowest part using R?

Is it possible to observe space debris with Binoculars?

What does "se jouer" mean here?

What is this red bug infesting some trees in southern Germany?

How to find better food in airports

Everyone for non livings

Can I sleep overnight at Stansted Airport

Why do old games use flashing as means of showing damage?



How to get right number of months and day between several dates?


Java 8 calculate months between two datesGet Last Day of the Month in PythonHow to return only the Date from a SQL Server DateTime datatypeHow do you get a timestamp in JavaScript?Add days to JavaScript DateHow do I get the current date in JavaScript?Calculate difference between two dates (number of days)?How do servlets work? Instantiation, sessions, shared variables and multithreadingHow to format a JavaScript dateDifference in months between two datesGet current time and date on Android






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








0















I need to compute the proper number of months and days between a list of intervals:



31/03/2017 30/09/2017
01/10/2017 31/03/2018
01/04/2018 30/09/2018
01/10/2018 31/12/2019


If I compute all days between these intervals and then divide by 30, I got



MONTHS: 33 DAYS: 12


but what I want is:



MONTHS: 33 DAYS: 1 (the only day to compute is the first day of first interval)









share|improve this question



















  • 1





    can you show us some code please

    – YCF_L
    Mar 27 at 18:06






  • 1





    I don't think it is a right approach to divide the days by 30 as some months can be 30 or 31 or 28/29. It doesn't provide the accurate result. You may need to define the requirement correctly as the above example showing the end and start date of the month.

    – notionquest
    Mar 27 at 18:07






  • 1





    Use the the java time package probably

    – JustAFellowCoder
    Mar 27 at 18:09






  • 2





    @MichaelMurray Or on Java 6 or 7 even better, use the backport of java.time: ThreeTen Backport.

    – Ole V.V.
    Mar 27 at 18:28






  • 1





    @OleV.V. if someone is dealing with time and is below java 8, it is recommended to update to 8 or above because below 8 is just a mess when it comes to time. Additionally, it is much slower.

    – JustAFellowCoder
    Mar 27 at 18:35

















0















I need to compute the proper number of months and days between a list of intervals:



31/03/2017 30/09/2017
01/10/2017 31/03/2018
01/04/2018 30/09/2018
01/10/2018 31/12/2019


If I compute all days between these intervals and then divide by 30, I got



MONTHS: 33 DAYS: 12


but what I want is:



MONTHS: 33 DAYS: 1 (the only day to compute is the first day of first interval)









share|improve this question



















  • 1





    can you show us some code please

    – YCF_L
    Mar 27 at 18:06






  • 1





    I don't think it is a right approach to divide the days by 30 as some months can be 30 or 31 or 28/29. It doesn't provide the accurate result. You may need to define the requirement correctly as the above example showing the end and start date of the month.

    – notionquest
    Mar 27 at 18:07






  • 1





    Use the the java time package probably

    – JustAFellowCoder
    Mar 27 at 18:09






  • 2





    @MichaelMurray Or on Java 6 or 7 even better, use the backport of java.time: ThreeTen Backport.

    – Ole V.V.
    Mar 27 at 18:28






  • 1





    @OleV.V. if someone is dealing with time and is below java 8, it is recommended to update to 8 or above because below 8 is just a mess when it comes to time. Additionally, it is much slower.

    – JustAFellowCoder
    Mar 27 at 18:35













0












0








0


1






I need to compute the proper number of months and days between a list of intervals:



31/03/2017 30/09/2017
01/10/2017 31/03/2018
01/04/2018 30/09/2018
01/10/2018 31/12/2019


If I compute all days between these intervals and then divide by 30, I got



MONTHS: 33 DAYS: 12


but what I want is:



MONTHS: 33 DAYS: 1 (the only day to compute is the first day of first interval)









share|improve this question














I need to compute the proper number of months and days between a list of intervals:



31/03/2017 30/09/2017
01/10/2017 31/03/2018
01/04/2018 30/09/2018
01/10/2018 31/12/2019


If I compute all days between these intervals and then divide by 30, I got



MONTHS: 33 DAYS: 12


but what I want is:



MONTHS: 33 DAYS: 1 (the only day to compute is the first day of first interval)






java date






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Mar 27 at 18:02









BaisoBaiso

346 bronze badges




346 bronze badges










  • 1





    can you show us some code please

    – YCF_L
    Mar 27 at 18:06






  • 1





    I don't think it is a right approach to divide the days by 30 as some months can be 30 or 31 or 28/29. It doesn't provide the accurate result. You may need to define the requirement correctly as the above example showing the end and start date of the month.

    – notionquest
    Mar 27 at 18:07






  • 1





    Use the the java time package probably

    – JustAFellowCoder
    Mar 27 at 18:09






  • 2





    @MichaelMurray Or on Java 6 or 7 even better, use the backport of java.time: ThreeTen Backport.

    – Ole V.V.
    Mar 27 at 18:28






  • 1





    @OleV.V. if someone is dealing with time and is below java 8, it is recommended to update to 8 or above because below 8 is just a mess when it comes to time. Additionally, it is much slower.

    – JustAFellowCoder
    Mar 27 at 18:35












  • 1





    can you show us some code please

    – YCF_L
    Mar 27 at 18:06






  • 1





    I don't think it is a right approach to divide the days by 30 as some months can be 30 or 31 or 28/29. It doesn't provide the accurate result. You may need to define the requirement correctly as the above example showing the end and start date of the month.

    – notionquest
    Mar 27 at 18:07






  • 1





    Use the the java time package probably

    – JustAFellowCoder
    Mar 27 at 18:09






  • 2





    @MichaelMurray Or on Java 6 or 7 even better, use the backport of java.time: ThreeTen Backport.

    – Ole V.V.
    Mar 27 at 18:28






  • 1





    @OleV.V. if someone is dealing with time and is below java 8, it is recommended to update to 8 or above because below 8 is just a mess when it comes to time. Additionally, it is much slower.

    – JustAFellowCoder
    Mar 27 at 18:35







1




1





can you show us some code please

– YCF_L
Mar 27 at 18:06





can you show us some code please

– YCF_L
Mar 27 at 18:06




1




1





I don't think it is a right approach to divide the days by 30 as some months can be 30 or 31 or 28/29. It doesn't provide the accurate result. You may need to define the requirement correctly as the above example showing the end and start date of the month.

– notionquest
Mar 27 at 18:07





I don't think it is a right approach to divide the days by 30 as some months can be 30 or 31 or 28/29. It doesn't provide the accurate result. You may need to define the requirement correctly as the above example showing the end and start date of the month.

– notionquest
Mar 27 at 18:07




1




1





Use the the java time package probably

– JustAFellowCoder
Mar 27 at 18:09





Use the the java time package probably

– JustAFellowCoder
Mar 27 at 18:09




2




2





@MichaelMurray Or on Java 6 or 7 even better, use the backport of java.time: ThreeTen Backport.

– Ole V.V.
Mar 27 at 18:28





@MichaelMurray Or on Java 6 or 7 even better, use the backport of java.time: ThreeTen Backport.

– Ole V.V.
Mar 27 at 18:28




1




1





@OleV.V. if someone is dealing with time and is below java 8, it is recommended to update to 8 or above because below 8 is just a mess when it comes to time. Additionally, it is much slower.

– JustAFellowCoder
Mar 27 at 18:35





@OleV.V. if someone is dealing with time and is below java 8, it is recommended to update to 8 or above because below 8 is just a mess when it comes to time. Additionally, it is much slower.

– JustAFellowCoder
Mar 27 at 18:35












2 Answers
2






active

oldest

votes


















2
















The Answer by Ole V.V. is correct, and wisely uses the modern java.time classes.



LocalDateRange



As a bonus, I will mention adding the excellent ThreeTen-Extra library to your project to access the LocalDateRange class. This class represents a span of time as a pair of LocalDate objects. That seems a match to your business problem.



LocalDate start = … ;
LocalDate stop = … ;
LocalDateRange range = LocalDateRange.of( start , stop ) ;


From this LocalDateRange object you can obtain the Period objects used in that Answer by Ole V.V.



Period period = range.toPeriod() ;


Notice that LocalDateRange has handy methods for comparison, such as abuts, contains, overlaps, and so on.



Half-Open



You may be confused about how to handle end-of-month/first-of-month.



Generally in date-time handling, it is best to represent a span-of-time using the Half-Open approach. In this approach, the beginning is inclusive while the ending is exclusive.



So a month starts on the first of the month and runs up to, but does not include the first of the next month.



LocalDateRange rangeOfMonthOfNovember2019 = 
LocalDateRange.of(
LocalDate.of( 2019 , Month.NOVEMBER , 1 ) ,
LocalDate.of( 2019 , Month.DECEMBER , 1
)
;


You can ask each LocalDateRange for days elapsed: LocalDateRange::lengthInDays.



DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd/MM/uuuu" );
List < LocalDateRange > ranges = new ArrayList <>( 4 );
ranges.add(
LocalDateRange.of(
LocalDate.parse( "31/03/2017" , f ) ,
LocalDate.parse( "30/09/2017" , f )
)
);
ranges.add(
LocalDateRange.of(
LocalDate.parse( "01/10/2017" , f ) ,
LocalDate.parse( "31/03/2018" , f )
)
);
ranges.add(
LocalDateRange.of(
LocalDate.parse( "01/04/2018" , f ) ,
LocalDate.parse( "30/09/2018" , f )
)
);
ranges.add(
LocalDateRange.of(
LocalDate.parse( "01/10/2018" , f ) ,
LocalDate.parse( "31/12/2019" , f )
)
);

// Sum the periods, one from each range.
Period period = Period.ZERO;
int days = 0;
for ( LocalDateRange range : ranges )

days = ( days + range.lengthInDays() );
period = period.plus( range.toPeriod() ).normalized();



Dump to console.



System.out.println( "ranges: " + ranges );
System.out.println( "days: " + days + " | pseudo-months: " + ( days / 30 ) + " and days: " + ( days % 30 ) );
System.out.println( "period: " + period );



ranges: [2017-03-31/2017-09-30, 2017-10-01/2018-03-31, 2018-04-01/2018-09-30, 2018-10-01/2019-12-31]



days: 1002 | pseudo-months: 33 and days: 12



period: P2Y5M119D




If you insist on fully-closed rather than half-open, LocalDateRange can still help you with its ofClosed method. But I strongly suggest you adopt half-open instead, as I believe you will find it makes your life easier to use one consistent approach across all your code. And educate your users. I have seen much confusion among office staff making incorrect assumptions about inclusive/exclusive dates. Your practice of tracking end-of-month to end-of-month seems likely to engender ever more confusion.



YearMonth



Another class you might find useful is built into Java: YearMonth. This class represents a particular month as a whole unit.



YearMonth yearMonth = YearMonth.of( 2019 , Month.NOVEMBER ) ;


Notice methods such as atDay to produce a LocalDate from a YearMonth.



ISO 8601



Tip: Make a habit of using only the ISO 8601 standard formats rather than localized formats when serializing date-time values as text.



So for a date, use YYYY-MM-DD.



The java.time classes use these formats by default when parsing/generating text. So no need to specify a formatting pattern.



LocalDate.parse( "2019-01-23" ) 


The standard ISO 8601 format for an entire month is YYYY-MM such as 2019-11.



YearMonth yearMonth = YearMonth.parse( "2019-11" ) ; // Entire month of November 2019.



About java.time



The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.



To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.



The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.



You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.



Where to obtain the java.time classes?




  • Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.

    • Java 9 adds some minor features and fixes.



  • Java SE 6 and Java SE 7

    • Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.



  • Android

    • Later versions of Android bundle implementations of the java.time classes.

    • For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….


The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.






share|improve this answer



























  • You fail to mention periods as a valid and simple/useful method for each only specifies intervals. Therefore, I will be marking this answer as incorrect until further revision.

    – JustAFellowCoder
    Mar 28 at 14:42











  • @JustAFellowCoder Reread, looking for range.toPeriod().

    – Basil Bourque
    Mar 28 at 14:53






  • 1





    @JustAFellowCoder Actually, upon further reflection, I now see that Period is not the solution here. The Question asks for pseudo-months as arbitrary 30-day chunks of time, unrelated to calendar. The Period class separates years-months from days. See the output of my example code: P2Y5M119D.

    – Basil Bourque
    Mar 28 at 18:36











  • BasilBourque fair

    – JustAFellowCoder
    Mar 28 at 18:47


















1
















You may ignore the dates in between and just calculate the difference between the first and the last date:



 LocalDate first = LocalDate.of(2017, 3, 31);
LocalDate lastInclusive = LocalDate.of(2019, 12, 31);
LocalDate lastExclusive = lastInclusive.plusDays(1);
Period between = Period.between(first, lastExclusive);

System.out.format("Months: %s days: %d%n",
between.toTotalMonths(), between.getDays());


Output is in this case:




Months: 33 days: 1




Since Period.between() calculates the difference up to the end date exclusive and you want the end date included, I add one day to your end date.



Months can be 28, 29, 30 and 31 days long and are longer than 30 days on the average, which is why dividing by 30 gave you too many days. You may read up on the exact working of Period.between() and check if it always gives you what you want.



Links



  • Oracle Turorial: section Period and Duration

  • Documentation of Period.bewteen()





share|improve this answer



























    Your Answer






    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













    draft saved

    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55383799%2fhow-to-get-right-number-of-months-and-day-between-several-dates%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    2
















    The Answer by Ole V.V. is correct, and wisely uses the modern java.time classes.



    LocalDateRange



    As a bonus, I will mention adding the excellent ThreeTen-Extra library to your project to access the LocalDateRange class. This class represents a span of time as a pair of LocalDate objects. That seems a match to your business problem.



    LocalDate start = … ;
    LocalDate stop = … ;
    LocalDateRange range = LocalDateRange.of( start , stop ) ;


    From this LocalDateRange object you can obtain the Period objects used in that Answer by Ole V.V.



    Period period = range.toPeriod() ;


    Notice that LocalDateRange has handy methods for comparison, such as abuts, contains, overlaps, and so on.



    Half-Open



    You may be confused about how to handle end-of-month/first-of-month.



    Generally in date-time handling, it is best to represent a span-of-time using the Half-Open approach. In this approach, the beginning is inclusive while the ending is exclusive.



    So a month starts on the first of the month and runs up to, but does not include the first of the next month.



    LocalDateRange rangeOfMonthOfNovember2019 = 
    LocalDateRange.of(
    LocalDate.of( 2019 , Month.NOVEMBER , 1 ) ,
    LocalDate.of( 2019 , Month.DECEMBER , 1
    )
    ;


    You can ask each LocalDateRange for days elapsed: LocalDateRange::lengthInDays.



    DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd/MM/uuuu" );
    List < LocalDateRange > ranges = new ArrayList <>( 4 );
    ranges.add(
    LocalDateRange.of(
    LocalDate.parse( "31/03/2017" , f ) ,
    LocalDate.parse( "30/09/2017" , f )
    )
    );
    ranges.add(
    LocalDateRange.of(
    LocalDate.parse( "01/10/2017" , f ) ,
    LocalDate.parse( "31/03/2018" , f )
    )
    );
    ranges.add(
    LocalDateRange.of(
    LocalDate.parse( "01/04/2018" , f ) ,
    LocalDate.parse( "30/09/2018" , f )
    )
    );
    ranges.add(
    LocalDateRange.of(
    LocalDate.parse( "01/10/2018" , f ) ,
    LocalDate.parse( "31/12/2019" , f )
    )
    );

    // Sum the periods, one from each range.
    Period period = Period.ZERO;
    int days = 0;
    for ( LocalDateRange range : ranges )

    days = ( days + range.lengthInDays() );
    period = period.plus( range.toPeriod() ).normalized();



    Dump to console.



    System.out.println( "ranges: " + ranges );
    System.out.println( "days: " + days + " | pseudo-months: " + ( days / 30 ) + " and days: " + ( days % 30 ) );
    System.out.println( "period: " + period );



    ranges: [2017-03-31/2017-09-30, 2017-10-01/2018-03-31, 2018-04-01/2018-09-30, 2018-10-01/2019-12-31]



    days: 1002 | pseudo-months: 33 and days: 12



    period: P2Y5M119D




    If you insist on fully-closed rather than half-open, LocalDateRange can still help you with its ofClosed method. But I strongly suggest you adopt half-open instead, as I believe you will find it makes your life easier to use one consistent approach across all your code. And educate your users. I have seen much confusion among office staff making incorrect assumptions about inclusive/exclusive dates. Your practice of tracking end-of-month to end-of-month seems likely to engender ever more confusion.



    YearMonth



    Another class you might find useful is built into Java: YearMonth. This class represents a particular month as a whole unit.



    YearMonth yearMonth = YearMonth.of( 2019 , Month.NOVEMBER ) ;


    Notice methods such as atDay to produce a LocalDate from a YearMonth.



    ISO 8601



    Tip: Make a habit of using only the ISO 8601 standard formats rather than localized formats when serializing date-time values as text.



    So for a date, use YYYY-MM-DD.



    The java.time classes use these formats by default when parsing/generating text. So no need to specify a formatting pattern.



    LocalDate.parse( "2019-01-23" ) 


    The standard ISO 8601 format for an entire month is YYYY-MM such as 2019-11.



    YearMonth yearMonth = YearMonth.parse( "2019-11" ) ; // Entire month of November 2019.



    About java.time



    The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.



    To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.



    The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.



    You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.



    Where to obtain the java.time classes?




    • Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.

      • Java 9 adds some minor features and fixes.



    • Java SE 6 and Java SE 7

      • Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.



    • Android

      • Later versions of Android bundle implementations of the java.time classes.

      • For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….


    The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.






    share|improve this answer



























    • You fail to mention periods as a valid and simple/useful method for each only specifies intervals. Therefore, I will be marking this answer as incorrect until further revision.

      – JustAFellowCoder
      Mar 28 at 14:42











    • @JustAFellowCoder Reread, looking for range.toPeriod().

      – Basil Bourque
      Mar 28 at 14:53






    • 1





      @JustAFellowCoder Actually, upon further reflection, I now see that Period is not the solution here. The Question asks for pseudo-months as arbitrary 30-day chunks of time, unrelated to calendar. The Period class separates years-months from days. See the output of my example code: P2Y5M119D.

      – Basil Bourque
      Mar 28 at 18:36











    • BasilBourque fair

      – JustAFellowCoder
      Mar 28 at 18:47















    2
















    The Answer by Ole V.V. is correct, and wisely uses the modern java.time classes.



    LocalDateRange



    As a bonus, I will mention adding the excellent ThreeTen-Extra library to your project to access the LocalDateRange class. This class represents a span of time as a pair of LocalDate objects. That seems a match to your business problem.



    LocalDate start = … ;
    LocalDate stop = … ;
    LocalDateRange range = LocalDateRange.of( start , stop ) ;


    From this LocalDateRange object you can obtain the Period objects used in that Answer by Ole V.V.



    Period period = range.toPeriod() ;


    Notice that LocalDateRange has handy methods for comparison, such as abuts, contains, overlaps, and so on.



    Half-Open



    You may be confused about how to handle end-of-month/first-of-month.



    Generally in date-time handling, it is best to represent a span-of-time using the Half-Open approach. In this approach, the beginning is inclusive while the ending is exclusive.



    So a month starts on the first of the month and runs up to, but does not include the first of the next month.



    LocalDateRange rangeOfMonthOfNovember2019 = 
    LocalDateRange.of(
    LocalDate.of( 2019 , Month.NOVEMBER , 1 ) ,
    LocalDate.of( 2019 , Month.DECEMBER , 1
    )
    ;


    You can ask each LocalDateRange for days elapsed: LocalDateRange::lengthInDays.



    DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd/MM/uuuu" );
    List < LocalDateRange > ranges = new ArrayList <>( 4 );
    ranges.add(
    LocalDateRange.of(
    LocalDate.parse( "31/03/2017" , f ) ,
    LocalDate.parse( "30/09/2017" , f )
    )
    );
    ranges.add(
    LocalDateRange.of(
    LocalDate.parse( "01/10/2017" , f ) ,
    LocalDate.parse( "31/03/2018" , f )
    )
    );
    ranges.add(
    LocalDateRange.of(
    LocalDate.parse( "01/04/2018" , f ) ,
    LocalDate.parse( "30/09/2018" , f )
    )
    );
    ranges.add(
    LocalDateRange.of(
    LocalDate.parse( "01/10/2018" , f ) ,
    LocalDate.parse( "31/12/2019" , f )
    )
    );

    // Sum the periods, one from each range.
    Period period = Period.ZERO;
    int days = 0;
    for ( LocalDateRange range : ranges )

    days = ( days + range.lengthInDays() );
    period = period.plus( range.toPeriod() ).normalized();



    Dump to console.



    System.out.println( "ranges: " + ranges );
    System.out.println( "days: " + days + " | pseudo-months: " + ( days / 30 ) + " and days: " + ( days % 30 ) );
    System.out.println( "period: " + period );



    ranges: [2017-03-31/2017-09-30, 2017-10-01/2018-03-31, 2018-04-01/2018-09-30, 2018-10-01/2019-12-31]



    days: 1002 | pseudo-months: 33 and days: 12



    period: P2Y5M119D




    If you insist on fully-closed rather than half-open, LocalDateRange can still help you with its ofClosed method. But I strongly suggest you adopt half-open instead, as I believe you will find it makes your life easier to use one consistent approach across all your code. And educate your users. I have seen much confusion among office staff making incorrect assumptions about inclusive/exclusive dates. Your practice of tracking end-of-month to end-of-month seems likely to engender ever more confusion.



    YearMonth



    Another class you might find useful is built into Java: YearMonth. This class represents a particular month as a whole unit.



    YearMonth yearMonth = YearMonth.of( 2019 , Month.NOVEMBER ) ;


    Notice methods such as atDay to produce a LocalDate from a YearMonth.



    ISO 8601



    Tip: Make a habit of using only the ISO 8601 standard formats rather than localized formats when serializing date-time values as text.



    So for a date, use YYYY-MM-DD.



    The java.time classes use these formats by default when parsing/generating text. So no need to specify a formatting pattern.



    LocalDate.parse( "2019-01-23" ) 


    The standard ISO 8601 format for an entire month is YYYY-MM such as 2019-11.



    YearMonth yearMonth = YearMonth.parse( "2019-11" ) ; // Entire month of November 2019.



    About java.time



    The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.



    To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.



    The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.



    You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.



    Where to obtain the java.time classes?




    • Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.

      • Java 9 adds some minor features and fixes.



    • Java SE 6 and Java SE 7

      • Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.



    • Android

      • Later versions of Android bundle implementations of the java.time classes.

      • For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….


    The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.






    share|improve this answer



























    • You fail to mention periods as a valid and simple/useful method for each only specifies intervals. Therefore, I will be marking this answer as incorrect until further revision.

      – JustAFellowCoder
      Mar 28 at 14:42











    • @JustAFellowCoder Reread, looking for range.toPeriod().

      – Basil Bourque
      Mar 28 at 14:53






    • 1





      @JustAFellowCoder Actually, upon further reflection, I now see that Period is not the solution here. The Question asks for pseudo-months as arbitrary 30-day chunks of time, unrelated to calendar. The Period class separates years-months from days. See the output of my example code: P2Y5M119D.

      – Basil Bourque
      Mar 28 at 18:36











    • BasilBourque fair

      – JustAFellowCoder
      Mar 28 at 18:47













    2














    2










    2









    The Answer by Ole V.V. is correct, and wisely uses the modern java.time classes.



    LocalDateRange



    As a bonus, I will mention adding the excellent ThreeTen-Extra library to your project to access the LocalDateRange class. This class represents a span of time as a pair of LocalDate objects. That seems a match to your business problem.



    LocalDate start = … ;
    LocalDate stop = … ;
    LocalDateRange range = LocalDateRange.of( start , stop ) ;


    From this LocalDateRange object you can obtain the Period objects used in that Answer by Ole V.V.



    Period period = range.toPeriod() ;


    Notice that LocalDateRange has handy methods for comparison, such as abuts, contains, overlaps, and so on.



    Half-Open



    You may be confused about how to handle end-of-month/first-of-month.



    Generally in date-time handling, it is best to represent a span-of-time using the Half-Open approach. In this approach, the beginning is inclusive while the ending is exclusive.



    So a month starts on the first of the month and runs up to, but does not include the first of the next month.



    LocalDateRange rangeOfMonthOfNovember2019 = 
    LocalDateRange.of(
    LocalDate.of( 2019 , Month.NOVEMBER , 1 ) ,
    LocalDate.of( 2019 , Month.DECEMBER , 1
    )
    ;


    You can ask each LocalDateRange for days elapsed: LocalDateRange::lengthInDays.



    DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd/MM/uuuu" );
    List < LocalDateRange > ranges = new ArrayList <>( 4 );
    ranges.add(
    LocalDateRange.of(
    LocalDate.parse( "31/03/2017" , f ) ,
    LocalDate.parse( "30/09/2017" , f )
    )
    );
    ranges.add(
    LocalDateRange.of(
    LocalDate.parse( "01/10/2017" , f ) ,
    LocalDate.parse( "31/03/2018" , f )
    )
    );
    ranges.add(
    LocalDateRange.of(
    LocalDate.parse( "01/04/2018" , f ) ,
    LocalDate.parse( "30/09/2018" , f )
    )
    );
    ranges.add(
    LocalDateRange.of(
    LocalDate.parse( "01/10/2018" , f ) ,
    LocalDate.parse( "31/12/2019" , f )
    )
    );

    // Sum the periods, one from each range.
    Period period = Period.ZERO;
    int days = 0;
    for ( LocalDateRange range : ranges )

    days = ( days + range.lengthInDays() );
    period = period.plus( range.toPeriod() ).normalized();



    Dump to console.



    System.out.println( "ranges: " + ranges );
    System.out.println( "days: " + days + " | pseudo-months: " + ( days / 30 ) + " and days: " + ( days % 30 ) );
    System.out.println( "period: " + period );



    ranges: [2017-03-31/2017-09-30, 2017-10-01/2018-03-31, 2018-04-01/2018-09-30, 2018-10-01/2019-12-31]



    days: 1002 | pseudo-months: 33 and days: 12



    period: P2Y5M119D




    If you insist on fully-closed rather than half-open, LocalDateRange can still help you with its ofClosed method. But I strongly suggest you adopt half-open instead, as I believe you will find it makes your life easier to use one consistent approach across all your code. And educate your users. I have seen much confusion among office staff making incorrect assumptions about inclusive/exclusive dates. Your practice of tracking end-of-month to end-of-month seems likely to engender ever more confusion.



    YearMonth



    Another class you might find useful is built into Java: YearMonth. This class represents a particular month as a whole unit.



    YearMonth yearMonth = YearMonth.of( 2019 , Month.NOVEMBER ) ;


    Notice methods such as atDay to produce a LocalDate from a YearMonth.



    ISO 8601



    Tip: Make a habit of using only the ISO 8601 standard formats rather than localized formats when serializing date-time values as text.



    So for a date, use YYYY-MM-DD.



    The java.time classes use these formats by default when parsing/generating text. So no need to specify a formatting pattern.



    LocalDate.parse( "2019-01-23" ) 


    The standard ISO 8601 format for an entire month is YYYY-MM such as 2019-11.



    YearMonth yearMonth = YearMonth.parse( "2019-11" ) ; // Entire month of November 2019.



    About java.time



    The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.



    To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.



    The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.



    You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.



    Where to obtain the java.time classes?




    • Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.

      • Java 9 adds some minor features and fixes.



    • Java SE 6 and Java SE 7

      • Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.



    • Android

      • Later versions of Android bundle implementations of the java.time classes.

      • For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….


    The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.






    share|improve this answer















    The Answer by Ole V.V. is correct, and wisely uses the modern java.time classes.



    LocalDateRange



    As a bonus, I will mention adding the excellent ThreeTen-Extra library to your project to access the LocalDateRange class. This class represents a span of time as a pair of LocalDate objects. That seems a match to your business problem.



    LocalDate start = … ;
    LocalDate stop = … ;
    LocalDateRange range = LocalDateRange.of( start , stop ) ;


    From this LocalDateRange object you can obtain the Period objects used in that Answer by Ole V.V.



    Period period = range.toPeriod() ;


    Notice that LocalDateRange has handy methods for comparison, such as abuts, contains, overlaps, and so on.



    Half-Open



    You may be confused about how to handle end-of-month/first-of-month.



    Generally in date-time handling, it is best to represent a span-of-time using the Half-Open approach. In this approach, the beginning is inclusive while the ending is exclusive.



    So a month starts on the first of the month and runs up to, but does not include the first of the next month.



    LocalDateRange rangeOfMonthOfNovember2019 = 
    LocalDateRange.of(
    LocalDate.of( 2019 , Month.NOVEMBER , 1 ) ,
    LocalDate.of( 2019 , Month.DECEMBER , 1
    )
    ;


    You can ask each LocalDateRange for days elapsed: LocalDateRange::lengthInDays.



    DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd/MM/uuuu" );
    List < LocalDateRange > ranges = new ArrayList <>( 4 );
    ranges.add(
    LocalDateRange.of(
    LocalDate.parse( "31/03/2017" , f ) ,
    LocalDate.parse( "30/09/2017" , f )
    )
    );
    ranges.add(
    LocalDateRange.of(
    LocalDate.parse( "01/10/2017" , f ) ,
    LocalDate.parse( "31/03/2018" , f )
    )
    );
    ranges.add(
    LocalDateRange.of(
    LocalDate.parse( "01/04/2018" , f ) ,
    LocalDate.parse( "30/09/2018" , f )
    )
    );
    ranges.add(
    LocalDateRange.of(
    LocalDate.parse( "01/10/2018" , f ) ,
    LocalDate.parse( "31/12/2019" , f )
    )
    );

    // Sum the periods, one from each range.
    Period period = Period.ZERO;
    int days = 0;
    for ( LocalDateRange range : ranges )

    days = ( days + range.lengthInDays() );
    period = period.plus( range.toPeriod() ).normalized();



    Dump to console.



    System.out.println( "ranges: " + ranges );
    System.out.println( "days: " + days + " | pseudo-months: " + ( days / 30 ) + " and days: " + ( days % 30 ) );
    System.out.println( "period: " + period );



    ranges: [2017-03-31/2017-09-30, 2017-10-01/2018-03-31, 2018-04-01/2018-09-30, 2018-10-01/2019-12-31]



    days: 1002 | pseudo-months: 33 and days: 12



    period: P2Y5M119D




    If you insist on fully-closed rather than half-open, LocalDateRange can still help you with its ofClosed method. But I strongly suggest you adopt half-open instead, as I believe you will find it makes your life easier to use one consistent approach across all your code. And educate your users. I have seen much confusion among office staff making incorrect assumptions about inclusive/exclusive dates. Your practice of tracking end-of-month to end-of-month seems likely to engender ever more confusion.



    YearMonth



    Another class you might find useful is built into Java: YearMonth. This class represents a particular month as a whole unit.



    YearMonth yearMonth = YearMonth.of( 2019 , Month.NOVEMBER ) ;


    Notice methods such as atDay to produce a LocalDate from a YearMonth.



    ISO 8601



    Tip: Make a habit of using only the ISO 8601 standard formats rather than localized formats when serializing date-time values as text.



    So for a date, use YYYY-MM-DD.



    The java.time classes use these formats by default when parsing/generating text. So no need to specify a formatting pattern.



    LocalDate.parse( "2019-01-23" ) 


    The standard ISO 8601 format for an entire month is YYYY-MM such as 2019-11.



    YearMonth yearMonth = YearMonth.parse( "2019-11" ) ; // Entire month of November 2019.



    About java.time



    The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.



    To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.



    The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.



    You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.



    Where to obtain the java.time classes?




    • Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.

      • Java 9 adds some minor features and fixes.



    • Java SE 6 and Java SE 7

      • Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.



    • Android

      • Later versions of Android bundle implementations of the java.time classes.

      • For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….


    The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Mar 28 at 18:35

























    answered Mar 28 at 3:04









    Basil BourqueBasil Bourque

    133k38 gold badges443 silver badges625 bronze badges




    133k38 gold badges443 silver badges625 bronze badges















    • You fail to mention periods as a valid and simple/useful method for each only specifies intervals. Therefore, I will be marking this answer as incorrect until further revision.

      – JustAFellowCoder
      Mar 28 at 14:42











    • @JustAFellowCoder Reread, looking for range.toPeriod().

      – Basil Bourque
      Mar 28 at 14:53






    • 1





      @JustAFellowCoder Actually, upon further reflection, I now see that Period is not the solution here. The Question asks for pseudo-months as arbitrary 30-day chunks of time, unrelated to calendar. The Period class separates years-months from days. See the output of my example code: P2Y5M119D.

      – Basil Bourque
      Mar 28 at 18:36











    • BasilBourque fair

      – JustAFellowCoder
      Mar 28 at 18:47

















    • You fail to mention periods as a valid and simple/useful method for each only specifies intervals. Therefore, I will be marking this answer as incorrect until further revision.

      – JustAFellowCoder
      Mar 28 at 14:42











    • @JustAFellowCoder Reread, looking for range.toPeriod().

      – Basil Bourque
      Mar 28 at 14:53






    • 1





      @JustAFellowCoder Actually, upon further reflection, I now see that Period is not the solution here. The Question asks for pseudo-months as arbitrary 30-day chunks of time, unrelated to calendar. The Period class separates years-months from days. See the output of my example code: P2Y5M119D.

      – Basil Bourque
      Mar 28 at 18:36











    • BasilBourque fair

      – JustAFellowCoder
      Mar 28 at 18:47
















    You fail to mention periods as a valid and simple/useful method for each only specifies intervals. Therefore, I will be marking this answer as incorrect until further revision.

    – JustAFellowCoder
    Mar 28 at 14:42





    You fail to mention periods as a valid and simple/useful method for each only specifies intervals. Therefore, I will be marking this answer as incorrect until further revision.

    – JustAFellowCoder
    Mar 28 at 14:42













    @JustAFellowCoder Reread, looking for range.toPeriod().

    – Basil Bourque
    Mar 28 at 14:53





    @JustAFellowCoder Reread, looking for range.toPeriod().

    – Basil Bourque
    Mar 28 at 14:53




    1




    1





    @JustAFellowCoder Actually, upon further reflection, I now see that Period is not the solution here. The Question asks for pseudo-months as arbitrary 30-day chunks of time, unrelated to calendar. The Period class separates years-months from days. See the output of my example code: P2Y5M119D.

    – Basil Bourque
    Mar 28 at 18:36





    @JustAFellowCoder Actually, upon further reflection, I now see that Period is not the solution here. The Question asks for pseudo-months as arbitrary 30-day chunks of time, unrelated to calendar. The Period class separates years-months from days. See the output of my example code: P2Y5M119D.

    – Basil Bourque
    Mar 28 at 18:36













    BasilBourque fair

    – JustAFellowCoder
    Mar 28 at 18:47





    BasilBourque fair

    – JustAFellowCoder
    Mar 28 at 18:47













    1
















    You may ignore the dates in between and just calculate the difference between the first and the last date:



     LocalDate first = LocalDate.of(2017, 3, 31);
    LocalDate lastInclusive = LocalDate.of(2019, 12, 31);
    LocalDate lastExclusive = lastInclusive.plusDays(1);
    Period between = Period.between(first, lastExclusive);

    System.out.format("Months: %s days: %d%n",
    between.toTotalMonths(), between.getDays());


    Output is in this case:




    Months: 33 days: 1




    Since Period.between() calculates the difference up to the end date exclusive and you want the end date included, I add one day to your end date.



    Months can be 28, 29, 30 and 31 days long and are longer than 30 days on the average, which is why dividing by 30 gave you too many days. You may read up on the exact working of Period.between() and check if it always gives you what you want.



    Links



    • Oracle Turorial: section Period and Duration

    • Documentation of Period.bewteen()





    share|improve this answer





























      1
















      You may ignore the dates in between and just calculate the difference between the first and the last date:



       LocalDate first = LocalDate.of(2017, 3, 31);
      LocalDate lastInclusive = LocalDate.of(2019, 12, 31);
      LocalDate lastExclusive = lastInclusive.plusDays(1);
      Period between = Period.between(first, lastExclusive);

      System.out.format("Months: %s days: %d%n",
      between.toTotalMonths(), between.getDays());


      Output is in this case:




      Months: 33 days: 1




      Since Period.between() calculates the difference up to the end date exclusive and you want the end date included, I add one day to your end date.



      Months can be 28, 29, 30 and 31 days long and are longer than 30 days on the average, which is why dividing by 30 gave you too many days. You may read up on the exact working of Period.between() and check if it always gives you what you want.



      Links



      • Oracle Turorial: section Period and Duration

      • Documentation of Period.bewteen()





      share|improve this answer



























        1














        1










        1









        You may ignore the dates in between and just calculate the difference between the first and the last date:



         LocalDate first = LocalDate.of(2017, 3, 31);
        LocalDate lastInclusive = LocalDate.of(2019, 12, 31);
        LocalDate lastExclusive = lastInclusive.plusDays(1);
        Period between = Period.between(first, lastExclusive);

        System.out.format("Months: %s days: %d%n",
        between.toTotalMonths(), between.getDays());


        Output is in this case:




        Months: 33 days: 1




        Since Period.between() calculates the difference up to the end date exclusive and you want the end date included, I add one day to your end date.



        Months can be 28, 29, 30 and 31 days long and are longer than 30 days on the average, which is why dividing by 30 gave you too many days. You may read up on the exact working of Period.between() and check if it always gives you what you want.



        Links



        • Oracle Turorial: section Period and Duration

        • Documentation of Period.bewteen()





        share|improve this answer













        You may ignore the dates in between and just calculate the difference between the first and the last date:



         LocalDate first = LocalDate.of(2017, 3, 31);
        LocalDate lastInclusive = LocalDate.of(2019, 12, 31);
        LocalDate lastExclusive = lastInclusive.plusDays(1);
        Period between = Period.between(first, lastExclusive);

        System.out.format("Months: %s days: %d%n",
        between.toTotalMonths(), between.getDays());


        Output is in this case:




        Months: 33 days: 1




        Since Period.between() calculates the difference up to the end date exclusive and you want the end date included, I add one day to your end date.



        Months can be 28, 29, 30 and 31 days long and are longer than 30 days on the average, which is why dividing by 30 gave you too many days. You may read up on the exact working of Period.between() and check if it always gives you what you want.



        Links



        • Oracle Turorial: section Period and Duration

        • Documentation of Period.bewteen()






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Mar 27 at 21:27









        Ole V.V.Ole V.V.

        37.4k7 gold badges47 silver badges64 bronze badges




        37.4k7 gold badges47 silver badges64 bronze badges






























            draft saved

            draft discarded
















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55383799%2fhow-to-get-right-number-of-months-and-day-between-several-dates%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Kamusi Yaliyomo Aina za kamusi | Muundo wa kamusi | Faida za kamusi | Dhima ya picha katika kamusi | Marejeo | Tazama pia | Viungo vya nje | UrambazajiKuhusu kamusiGo-SwahiliWiki-KamusiKamusi ya Kiswahili na Kiingerezakuihariri na kuongeza habari

            Swift 4 - func physicsWorld not invoked on collision? The Next CEO of Stack OverflowHow to call Objective-C code from Swift#ifdef replacement in the Swift language@selector() in Swift?#pragma mark in Swift?Swift for loop: for index, element in array?dispatch_after - GCD in Swift?Swift Beta performance: sorting arraysSplit a String into an array in Swift?The use of Swift 3 @objc inference in Swift 4 mode is deprecated?How to optimize UITableViewCell, because my UITableView lags

            Access current req object everywhere in Node.js ExpressWhy are global variables considered bad practice? (node.js)Using req & res across functionsHow do I get the path to the current script with Node.js?What is Node.js' Connect, Express and “middleware”?Node.js w/ express error handling in callbackHow to access the GET parameters after “?” in Express?Modify Node.js req object parametersAccess “app” variable inside of ExpressJS/ConnectJS middleware?Node.js Express app - request objectAngular Http Module considered middleware?Session variables in ExpressJSAdd properties to the req object in expressjs with Typescript