Get week of month with Joda-Time
Asked Answered
F

5

6

Is it possible to parse a date and extract the week of month using Joda-Time. I know it is possible to do it for the week of year but I cannot find how/if it is possible to extract the week of month.

Example: 2014-06_03 where 03 is the third week of this month

DateTime dt = new DateTime();
String yearMonthWeekOfMonth = dt.toString("<PATTERN for the week of month>");

I have tried the pattern "yyyyMMW" but it is not accepted.

Ferrari answered 18/6, 2014 at 8:14 Comment(0)
R
6

Current joda-time version doesn't support week of month, so you should use some workaround.
1) For example, you can use next method:

   static DateTimeFormatter FORMATTER = DateTimeFormat.forPattern("yyyy-MM_'%d'");
   static String printDate(DateTime date)
   {
      final String baseFormat = FORMATTER.print(date); // 2014-06_%d 
      final int weekOfMonth = date.getDayOfMonth() % 7;
      return String.format(baseFormat, weekOfMonth);
   }

Usage:

DateTime dt = new DateTime();
String dateAsString = printDate(dt);  

2) You can use Java 8, because Java's API supports week of month field.

  java.time.LocalDateTime date = LocalDateTime.now();
  DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM_W");
  System.out.println(formatter.format(date));
Reiche answered 18/6, 2014 at 13:25 Comment(2)
Thanks for the reply, finally with SimpleDateFormat did the trick for me, but it is good to know that it is supported by Java 8Ferrari
Correction for the first solution : final int weekOfMonth = (date.getDayOfMonth() / 7) + 1;Wenoa
E
6

This option in Joda is probably nicer:

Weeks.weeksBetween(date, date.withDayOfMonth(1)).getWeeks() + 1
Erato answered 9/5, 2015 at 18:23 Comment(2)
Just pay attention that if date > then date.withDayOfMonth(1) code above returns negative values, at least for joda-time 2.9.1, doesn't know is it bug or intended behaviour, but according to API it should be ..(start,end), public static Weeks weeksBetween(ReadablePartial start,ReadablePartial end), joda-time.sourceforge.net/apidocs/org/joda/time/…, org.joda.time.ReadableInstant)Blur
you can always do Weeks.weeksBefore(date1.isBefore(date2) ? date1 : date2, date1.isBefore(date2) ? date2 : date1)).getWeeks() + 1Erato
A
1

For the case you don't like calculations so much:

    DateTime date = new DateTime();
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date.toDate());
    int weekOfMonth = calendar.get(Calendar.WEEK_OF_MONTH);
Aeonian answered 3/8, 2018 at 13:56 Comment(0)
E
1

java.time

The Joda-Time project is now in maintenance-mode. Its creator Stephen Colebourne went on to found the JSR 310 project that put java.time classes into Java 8 and later.

ThreeTen-Extra library

The same Stephen Colebourne also created the ThreeTen-Extra project. This project produces a library that includes the YearWeek class for your purposes.

ISO 8601 week

Well it suits your purposes if you define “week” according to the ISO 8601 standard definition:

  • Week # 1 contains the first Thursday of the calendar year.
  • Week runs Monday-Sunday.
  • A week-based year is composed of exactly 52 or 53 complete 7-day weeks.

So the first & last weeks may contain some days from the previous & following calendar years.

YearWeek class

Using the YearWeek class is quite simple.

YearWeek currentWeek = YearWeek.now() ;  // Or now( ZoneId.of( "America/Edmonton" ) )

Get the week for a date.

YearWeek yw = YearWeek.of( LocalDate.of( 2025 , Month.JANUARY , 23 ) ) ;

Regarding your input string:

Example: 2014-06_03 where 03 is the third week of this month

… this has no clear meaning. You neglected to explain your definition of week.

We could get the third week, per ISO 8601 standard, that occurs in the month of June.

String input = "2014-06_03";
String[] parts = input.split ( "_" );
YearMonth yearMonth = YearMonth.parse ( parts[ 0 ] );
int week = Integer.parseInt ( parts[ 1 ] );

YearWeek firstWeekInMonth = YearWeek.from ( yearMonth.atDay ( 1 ) );
YearWeek nthWeekInMonth = firstWeekInMonth.plusWeeks ( week - 1 );

Dump to console.

System.out.println ( "yearMonth.toString() = " + yearMonth );
System.out.println ( "firstWeekInMonth.toString() = " + firstWeekInMonth );
System.out.println ( "nthWeekInMonth.toString() = " + nthWeekInMonth );
System.out.println ( nthWeekInMonth.atDay ( DayOfWeek.MONDAY ) + "/" + nthWeekInMonth.atDay ( DayOfWeek.SUNDAY ) + " (inclusive)" );

yearMonth.toString() = 2014-06

firstWeekInMonth.toString() = 2014-W22

nthWeekInMonth.toString() = 2014-W24

2014-06-09/2014-06-15

Ev answered 14/10 at 7:28 Comment(0)
F
0

If the start day of week is Monday then you can use it:

public int getWeekOfMonth(DateTime date){
    DateTime.Property dayOfWeeks = date.dayOfWeek();
    return (int) (Math.ceil((date.dayOfMonth().get() - dayOfWeeks.get()) / 7.0)) + 1;
}
Fluency answered 30/6, 2020 at 3:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.