date - How to calculate monthly occurrence in java -


i need able manage dates in flexible way calculating monthly events.

if use

    simpledateformat sdf = new simpledateformat("dd-m-yyyy hh:mm:ss");      calendar calendar = calendar.getinstance();     calendar.set(2017, calendar.august, 31, 9, 30, 15);     calendar next = calendar;     (int = 1; i++<10;) {         next = (calendar) calendar.clone();         next.add(calendar.month, i);         system.out.println(sdf.format(next.gettime()));     } 

in result can see

31-10-2017 09:30:15

30-11-2017 09:30:15

31-12-2017 09:30:15

31-1-2018 09:30:15

28-2-2018 09:30:15

31-3-2018 09:30:15

30-4-2018 09:30:15

31-5-2018 09:30:15

30-6-2018 09:30:15

it seems following month semantic if add 1 moth date should next month (it's correct), following occurrence semantic has issue, because of acceptance same date day in next month (as can see not same sometimes. there 31, 30, 28). if there no same date, should null example.

does java provides ability calculate months following occurrence semantic strategy handle issue?

more explanation examples.

i not need last month day need occurrences first explanation 31th month day. simplified question possible.

i can workarounds calendar expected more elegant solution.

if use ical4j calculate occurrences, you'll result. , occurrences calculation should fixed (it's bug because of rfc5545).

import net.fortuna.ical4j.model.* import net.fortuna.ical4j.model.component.vevent  void testcalculaterecurrenceseton31th() {     vevent event = new contentbuilder().vevent {         dtstart('20100831t061500z', parameters: parameters() {             value('datetime')})         dtend('20100831t064500z', parameters: parameters() {             value('datetime')})         rrule('freq=monthly;until=20110101')     }      def dates = event.calculaterecurrenceset(new period('20100831t000000/20110131t000000'))      def expected = new periodlist(true)     expected.add new period('20100831t061500z/pt30m')     expected.add new period('20101031t061500z/pt30m')     expected.add new period('20101231t061500z/pt30m')      println dates     assert dates == expected      /*     assertion failed:      assert dates == expected     |     |  |     |     |  [20100831t061500z/pt30m, 20101031t061500z/pt30m, 20101231t061500z/pt30m]     |     false     [20100831t061500z/pt30m, 20100930t061500z/pt30m, 20101030t061500z/pt30m, 20101130t061500z/pt30m, 20101230t061500z/pt30m]     */ } 

but if use same library small change:

      rrule('freq=monthly;until=20110101') 

-->

      rrule('freq=monthly;until=20110101;bymonthday=31') 

it calculated correctly. need same calculation both cases because of rfc5545.

the root issue in ical4j in recur.java:

private void increment(final calendar cal) {     final int calinterval = (getinterval() >= 1) ? getinterval() : 1;     cal.add(calincfield, calinterval); } 

java.time

use modern java.time classes rather troublesome old legacy classes.

your question overwrought , unclear. here general pointers , examples should going in right direction.

the localdate class represents date-only value without time-of-day , without time zone.

localdate ld = localdate.now( zoneid.of( "america/montreal" ) ) ; 

if want add month, call plusmonths.

localdate monthlater = ld.plusmonths( 1 ) ; 

if want add 30 days, call plusdays.

localdate thirtydayslater = ld.plusdays( 30 ) ; 

if want last day of next month, use temporaladjuster first of next month, end of day’s month. find such implementations in temporaladjusters class (note plural s).

localdate firstofnextmonth = ld.with( temporaladjusters.firstofnextmonth() ) ; localdate lastofnextmonth = firstofnextmonth.with( temporaladjusters.lastofmonth() ) ; 

if care months happen have 31 days, use month enum determine length. consider writing own implementation of temporaladjuster, "lastofthenextmonthcontaining31days".

if( ld.getmonth().maxlength() == 31 ) { … } 

if want day of every month, use yearmonth class. trap datetimeexception if month lacks day-of-month such 31 in february.

yearmonth ym = yearmonth.from( ld ) ; localdate thirteenth = ym.atday( 13 ) ; 

get same day-of-month in following month.

int dayofmonth = ld.getdayofmonth() ; yearmonth = yearmonth.from( ld ) ; localdate samedayofmonthinnextmonth = ym.plusmonths( 1 ).atday( dayofmonth ) ;  

if needed, can add time-of-day , time zone zoneddatetime. if time-of-day happens invalid in date, automatically adjusted. sure study adjustment behavior see agrees needs.

localtime lt = localtime.of( 9 , 30 ) ; zoneid z = zoneid.of( "pacific/auckland" ) ; zoneddatetime zdt = zoneddatetime.of( ld , lt , z ) ; 

Comments

Popular posts from this blog

android - InAppBilling registering BroadcastReceiver in AndroidManifest -

python Tkinter Capturing keyboard events save as one single string -

sql server - Why does Linq-to-SQL add unnecessary COUNT()? -