-4

Java don't execute some lines of my code when I use Calendary library.

I'm trying to get the date of monday before 1 of actual month.

//Today is Tuesday, 2 January of 2019 (29/01/2019)

Calendar cp1 = GregorianCalendar.getInstance();
cp1.set(Calendar.DAY_OF_MONTH, 1); //THIS LINE DON'T WORKS
cp1.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
SimpleDateFormat sdf=new SimpleDateFormat ("dd/MM/yyyy");
System.out.println(sdf.format (cp1.getTime()));

// return 28/01/2019 instead of 31/12/2018.

IF I ADD System.out.println(cp1) after line 2 java don't jump line 2 and works well.

//Today is Tuesday, 2 January of 2019 (29/01/2019)

Calendar cp1 = GregorianCalendar.getInstance();
cp1.set(Calendar.DAY_OF_MONTH, 1); //THIS LINE WORKS NOW
System.out.println (cp1.getTime());
cp1.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
SimpleDateFormat sdf=new SimpleDateFormat ("dd/MM/yyyy");
System.out.println(sdf.format (cp1.getTime())); 

//return 31/12/2018 that is the correct date.

//Why java didn't execute 2nd line in my first code? Is a java bug?

Expected result "31/12/2018". Actual result "28/01/2019".

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
Hammerin87
  • 65
  • 1
  • 1
  • 8
  • I ran your second part of the code and to me it also returns "28/01/2019". I'd also suggest you edit your question and try express a bit better what you mean by _I'm trying to get the date of monday before 1 of actual month_ – nullPointer Jan 29 '19 at 16:42
  • Sorry, I'm noob. For my, first part of my code returns 28/01/2019, second part returns for me "31/12/2018". However, "28/01/2019" is wrong. The correct result is "31/12/2018". Why java don't execute second line? – Hammerin87 Jan 29 '19 at 16:44
  • 2019-01-28, 2018-12-31 are both Monday. your Day of month is overridden by Monday. If you want 12/31 then should set the month to Dec and 5th week – CSK Jan 29 '19 at 16:46
  • The `return 31/12/2018 that is the correct date.` is not reproductible, I suggest you to test again https://ideone.com/IjE3X8 , both does the same – azro Jan 29 '19 at 16:47
  • https://www.youtube.com/watch?v=pCB4vuh70XE&feature=youtu.be – Hammerin87 Jan 29 '19 at 17:16
  • https://ideone.com/a5Tq6I – Hammerin87 Jan 29 '19 at 17:21
  • I recommend you don’t use `Calendar` and `SimpleDateFormat`. Those classes are poorly designed and long outdated, the latter in particular notoriously troublesome. Instead use `LocalDate` and `DateTimeFormatter`, both from [java.time, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/). – Ole V.V. Jan 30 '19 at 16:41
  • Ok, I will start to change all my classes. – Hammerin87 Jan 31 '19 at 07:52

1 Answers1

2

I'd strongly recommand to use java.time as it's easier to deal with.

Use the TemporalAdjuster implementation found in the TemporalAdjusters class. Pass a DayOfWeek enum object for your desired day-of-week.

LocalDate now = LocalDate.now();
LocalDate mondayBefore1OfMonth = now.withDayOfMonth(1)
                                    .with(TemporalAdjusters.previous(DayOfWeek.MONDAY));

System.out.println(mondayBefore1OfMonth); // 2018-12-31

For your problem (reproductible as https://ideone.com/ph73wK ), it seems that if you don't make a call to the private method computeTime()the field Calendar.DAY_OF_MONTH is overriden or something like that, by making a call to .getTime() or .get(Calendar.DAY_OF_MONTH) it'll update the date and you'll get good result

azro
  • 53,056
  • 7
  • 34
  • 70