7

Inspired by the following posts

I need a function that returns the ordinal position for a given day in the month, for example:

01/01/1970 = 1 because it's the first Thursday in January, 1970

02/01/1970 = 1 because it's the first Friday in January, 1970

19/01/1970 = 3 because it's the third Monday in January, 1970

31/01/1970 = 5 because it's the fifth Saturday in January, 1970

What have I tried? - Nothing...I don't even know where to start; the Java 8 date/time API is pretty new to me.

Ideally I want a function with this signature:

public int getOrdinalPosition(TemporalAccessor temporal) {
    ...
}
Community
  • 1
  • 1
Matthew Layton
  • 39,871
  • 52
  • 185
  • 313
  • So the cardinal position refers to the week number in the month where the given date falls? – Ravindra Ranwala Jan 06 '19 at 15:22
  • 2
    Actually, asking for the “nth” is *ordinal* not *cardinal*. Ordinal means counting by position. Cardinal means counting for quantity. See: https://www.differencebetween.com/difference-between-cardinal-numbers-and-vs-ordinal-numbers/ – Basil Bourque Jan 06 '19 at 21:44
  • @BasilBourque good point well made, thanks for your update! – Matthew Layton Jan 07 '19 at 11:07

4 Answers4

4

Well, take 19/01/1970. Subtract 7 days from that and it's.. still january. Subtract 7 days again and.. still january. Subtract 7 days a 4th time and.. oh hey it's no longer january. The 4th time you removed 7 days, it ceased to be the right month.

That's all you need here.

Relevant methods: a for loop, a counter, and.. the minusDays(7) method, and getMonth().

rzwitserloot
  • 85,357
  • 5
  • 51
  • 72
3

ChronoField.ALIGNED_WEEK_OF_MONTH

You can use LocalDate.get() and ChronoField.ALIGNED_WEEK_OF_MONTH.

import java.time.LocalDate;
import java.time.temporal.ChronoField;
import java.time.temporal.TemporalAccessor;

/**
 *
 * @author Sedrick
 */
public class JavaApplication19 {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
        LocalDate localDate1 = LocalDate.of(1970, 01, 01);
        LocalDate localDate2 = LocalDate.of(1970, 02, 01);
        LocalDate localDate3 = LocalDate.of(1970, 01, 19);
        LocalDate localDate4 = LocalDate.of(1970, 01, 31);


        System.out.println(localDate1.get(ChronoField.ALIGNED_WEEK_OF_MONTH));
        System.out.println(localDate2.get(ChronoField.ALIGNED_WEEK_OF_MONTH));
        System.out.println(localDate3.get(ChronoField.ALIGNED_WEEK_OF_MONTH));
        System.out.println(localDate4.get(ChronoField.ALIGNED_WEEK_OF_MONTH));

        System.out.println(getOrdinalPosition(localDate4));
    }

    static public int getOrdinalPosition(TemporalAccessor temporal) {
        return LocalDate.from(temporal).get(ChronoField.ALIGNED_WEEK_OF_MONTH);
    }
}

Output:

run:
1
1
3
5
5
BUILD SUCCESSFUL (total time: 0 seconds)
SedJ601
  • 12,173
  • 3
  • 41
  • 59
2

This seems to work...

public int getOrdinalPosition(TemporalAccessor temporal) {
    return ((LocalDate.from(temporal).getDayOfMonth() - 1) / 7) + 1;
}
Matthew Layton
  • 39,871
  • 52
  • 185
  • 313
  • 2
    @RavindraRanwala readability is in the eye of the beholder; short code tends to put the burden of proof on the longer code, and you didn't bring any. This is not error prone whatsoever; it does precisely what OP wanted (which is NOT 'the number of the week the day is in', it is 'this is the Xth thursday of the month; what's X?' – rzwitserloot Jan 06 '19 at 14:13
2

What you need is ChronoField.ALIGNED_WEEK_OF_MONTH

LocalDate.of(1970,1,1).get(ChronoField.ALIGNED_WEEK_OF_MONTH)      //1
LocalDate.of(1970,1,2).get(ChronoField.ALIGNED_WEEK_OF_MONTH)      //1
LocalDate.of(1970,1,19).get(ChronoField.ALIGNED_WEEK_OF_MONTH)     //3
LocalDate.of(1970,1,31).get(ChronoField.ALIGNED_WEEK_OF_MONTH)     //5
Pankaj Singhal
  • 15,283
  • 9
  • 47
  • 86