Hi Mike,
This looks like something I tried to implement a while back - 
nextMatching(). That is, given a DateTime, find the next DateTime that 
matches the given Partial.

I got this working for dates, but I ran into problems with timezones. 
Timezones were essentially unpredictable, and confused the definition of 
what 'next matching' meant (eg. when DST rules lead to overlapping 
hours). As a result, I stopped work on this concept.

This is some of the code I wrote, and was on the BaseDateTimeField 
class. It was then overridden in subclasses to improve performance.

Basically, if we only implemented this for the Local* classes, then this 
would be easy. Its the timezone thats the hard problem to solve.

Stephen


 
//------------------------------------------------------------------------
     /**
      * Finds the next instant that the input instant has the specified 
value.
      * <p>
      * The value of this field will be set into the input milliseconds.
      * The result will always be after the input milliseconds.
      * If the value is invalid, an exception if thrown.
      * <p>
      * Finding the next match avoids changing other fields, especially 
smaller
      * sized ones. For exampe, finding the next 30th dayOfMonth after 
the 31st
      * January will return the 31st March. The time fields will be 
unaltered.
      *
      * @param instant  the milliseconds from 1970-01-01T00:00:00Z to set in
      * @param value  the value to set, in the units of the field
      * @param numberOfRanges  the number of ranges to move by, zero has 
no effect
      * @param firstMustChange  whether the set must change the date
      * @return the updated milliseconds
      * @throws IllegalArgumentException if the value is invalid
      * @since 1.3
      */
     public long next(long instant, int value, int numberOfRanges, 
boolean firstMustChange) {
         if (numberOfRanges == 0) {
             return instant;
         }
         long millis = set(instant, value);
         if (numberOfRanges > 0) {
             if (millis > instant || (millis == instant && 
!firstMustChange)) {
                 numberOfRanges--;
             }
             if (numberOfRanges > 0) {
                 millis = findNext(millis, value, numberOfRanges);
             }
         } else {
             if (millis < instant || (millis == instant && 
!firstMustChange)) {
                 numberOfRanges++;
             }
             if (numberOfRanges < 0) {
                 millis = findNext(millis, value, numberOfRanges);
             }
         }
         return millis;
     }

     /**
      * Finds the next/previous occurrance of a value.
      *
      * @param millis  the milliseconds with a field value equal to value
      * @param value  the value to progress to
      * @param numberOfRanges  the number of progressions, non-zero
      * @return the updated millis
      * @since 1.3
      */
     protected long findNext(long millis, int value, int numberOfRanges) {
         DurationField range = getRangeDurationField();
         if (range == null || range.isSupported() == false) {
             throw new IllegalFieldValueException(getType(), 
Integer.toString(value));
         }
         int sgn = 1;
         if (numberOfRanges < 0) {
             sgn = -1;
             numberOfRanges = -numberOfRanges;
         }
         // need to handle varying unit/range lengths
         long base = millis;
         for (int j = sgn; numberOfRanges > 0; j += sgn) {
             millis = range.add(base, j);
             if (get(millis) == value) {
                 numberOfRanges--;
             }
         }
         return millis;
     }





reece wrote:
> Hi Joda People,
> 
> Pleases us this API generally does ;-)
> 
> The bottom line (I think) is - How do I 'roll' a DateTime forward to the
> next
> occuring Partial (eg 1st October)?
> 
> Some other details follow that illustrate the higher problem in case there
> is a better approach...
> 
> My highish aim is:
> I have MyPartial of 1st October with just those fields set.
> I wish to split MyInterval around MyPartial, if of course it contains it.
> I don't see any ambiguity there.
> 
> 2006-01-01 - 2007-07-01 false
> 2007-07-01 - 2007-10-02 true
> 
> There must be a simpler way but at the moment I'm going through this
> procedure.
> 
> Sub aim: Convert MyPartial to DateTime of the next year after
> MyInterval.start
> So I expected to be able to do some rounding to achieve this - I drew a
> blank.
> Instead I can first artificially add 3 months (1,Jan minus 1,Oct) to
> MyInterval.start and then roundFloor() the year - this gives a year I can
> extract and set on MyPartial, allowing a meaningful MyInstant to be
> extracted.
> 
> Using this the following all result in the correct year to set on MyPartial
> in order to give me a date I can split MyInterval around.
> 
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> MyInterval.start:    Wed 1 Nov '06
> plusMonths(3):       Thu 1 Feb '07
> year().roundFloor(): Mon 1 Jan '07
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> MyInterval.start:    Thu 1 Feb '07
> plusMonths(3):       Tue 1 May '07
> year().roundFloor(): Mon 1 Jan '07
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> MyInterval.start:    Sun 1 Jul '07
> plusMonths(3):       Mon 1 Oct '07
> year().roundFloor(): Mon 1 Jan '07
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> MyInterval.start:    Sun 30 Sep '07
> plusMonths(3):       Sun 30 Dec '07
> year().roundFloor(): Mon 1 Jan '07
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> MyInterval.start:    Mon 1 Oct '07
> plusMonths(3):       Tue 1 Jan '08
> year().roundFloor(): Tue 1 Jan '08
> 
> The problem is, calculating the 3 month period (or whatever period that
> is depending on MyPartial) since MyPartial may be any point in the year.
> I see I can do:
> Days.daysBetween(ReadablePartial start,ReadablePartial end)
> Which may help but if MyPartial is < 29 Feb then this is going to cause
> error. In fact I expect that method would fallover without year field in the
> Partial.
> 
> So the bottom line is - how do I roll a DateTime forward to the next
> occuring Partial?
> 
> Thanks,
> Mike W
> 
> P.S. Fantastic API - I'll never use that festering JDK library again!!
> 
> 
> 
> 
> -------------------------------------------------------------------------
> Take Surveys. Earn Cash. Influence the Future of IT
> Join SourceForge.net's Techsay panel and you'll get the chance to share your
> opinions on IT & business topics through brief surveys - and earn cash
> http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
> _______________________________________________
> Joda-interest mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/joda-interest
> 

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Joda-interest mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/joda-interest

Reply via email to