0

below the lastDay variable does not always contain the i+1 of the list. No clue why. I am in the course of introducing the Date from Java 8. But still I would like to know what is going wrong... Peter (very beginner)

// organize the intervals and split them into the years
        ArrayList<intervall> tmpIntervallList = new ArrayList<intervall>();
        Calendar lastDay = Calendar.getInstance();

        for (i = 0; i < deliveryList.size() - 1; i++) {

            Log.d(TAG, "my log comments: Intervallanfang " +
                    deliveryList.get(i).getDatumasString() +" nächstes: " + deliveryList.get(i+1).getDatumasString());
            //Beginning of the next intervall -1 is the last day of the Intervall before.
            lastDay.set(deliveryList.get(i+1).getYear(),
                    deliveryList.get(i+1).getMonth(),
                    deliveryList.get(i+1).getDay());

            //debugging
            String tmp1String = String.format("%d/%d/%d", lastDay.get(Calendar.DAY_OF_MONTH),
                    lastDay.get(Calendar.MONTH) + 1,
                    lastDay.get(Calendar.YEAR));
            Log.d(TAG, "my log comments: tmp lastday " + tmp1String );

            lastDay.add(Calendar.DATE, -1);

            //debugging
            String tmpString = String.format("%d/%d/%d", lastDay.get(Calendar.DAY_OF_MONTH),
                    lastDay.get(Calendar.MONTH) + 1,
                    lastDay.get(Calendar.YEAR));
            Log.d(TAG, "my log comments: ende intervall " + tmpString);

            intervall tmp2intervall = new intervall(deliveryList.get(i).getAmountFilled(),
                    deliveryList.get(i).getYear(),
                    deliveryList.get(i).getMonth(),
                    deliveryList.get(i).getDay(),
                    lastDay.get(Calendar.YEAR),
                    lastDay.get(Calendar.MONTH),
                    lastDay.get(Calendar.DAY_OF_MONTH));
            tmpIntervallList.add(tmp2intervall);
        }

And the outcome is

my log comments: Intervallanfang 01/01/2018 nächstes: 01/02/2018

my log comments: tmp lastday 1/1/2018

my log comments: ende intervall 31/12/2017

my log comments: Intervallanfang 01/02/2018 nächstes: 01/06/2018

my log comments: tmp lastday 1/1/2018

my log comments: ende intervall 31/12/2017

my log comments: Intervallanfang 01/06/2018 nächstes: 01/01/2019

my log comments: tmp lastday 1/1/2019

my log comments: ende intervall 31/12/2018

my log comments: Intervallanfang 01/01/2019 nächstes: 01/01/2020

my log comments: tmp lastday 1/1/2020

my log comments: ende intervall 31/12/2019

my log comments: Intervallanfang 01/01/2020 nächstes: 01/06/2020

my log comments: tmp lastday 1/1/2020

my log comments: ende intervall 31/12/2019

my log comments: Intervallanfang 01/06/2020 nächstes: 02/01/2021

my log comments: tmp lastday 2/1/2021

my log comments: ende intervall 1/1/2021

as requested some more source code

    public  intervall(int amountFilled, int yearBegin, int monthBegin, int 
               dayBegin, int yearEnd, int monthEnd, int dayEnd) {
                   begin = Calendar.getInstance();
                   end = Calendar.getInstance();
                   this.setIntervall( yearBegin, monthBegin, dayBegin, 
                          yearEnd, monthEnd, dayEnd);
                   this.amountFilled = amountFilled;

....

    public void setIntervall(int amountFilled, int yearBegin, int 
    monthBegin, int dayBegin, int yearEnd, int monthEnd, int dayEnd){
       this.begin.set(yearBegin, monthBegin, dayBegin);
       this.end.set(yearEnd, monthEnd, dayEnd);

.....

Peter
  • 3
  • 3
  • 1
    What is the object in deliverylist? And what are its getters and setters? – Compass Feb 04 '20 at 22:09
  • 1
    I recommend you don’t use `Calendar`. That class is poorly designed and long outdated. Instead use `LocalDate` from [java.time, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/). And use a `DateTimeFormatter` for formatting it in your log output. – Ole V.V. Feb 05 '20 at 06:25
  • as said I am in the course of introducing the Date from Java 8 - still I would like to understand what went wrong. – Peter Feb 05 '20 at 07:58
  • I agree that the log output is not what I would have expected from the code. I can’t see what’s wrong. A suggested path to follow from here is [to create a Minimal, Reproducible Example](https://stackoverflow.com/help/minimal-reproducible-example). – Ole V.V. Feb 05 '20 at 09:33

2 Answers2

2

Avoid legacy date-time classes

You are using terrible date-time classes that were supplanted years ago by the modern java.time classes defined in JSR 310. Never use Date or Calendar.

java.time

Get today's date. A time zone is required. For any given moment, the date varies around the globe by time zone.

ZoneId z = ZoneId.of( "Europe/Berlin" ) ;
LocalDate today = LocalDate.now( z ) ;

Generate a string in standard ISO 8601 format, YYYY-MM-DD. Note that java.time uses sane numbering, so months are 1-12, no need for + 1.

String output = today.toString() ;

To add or subtract days to that date, call plusDays or minusDays. The java.time classes use immutable objects. So rather than altering the original, we get a fresh new LocalDate object as a result.

LocalDate yesterday = today.minusDays( 1 ) ;
LocalDate tomorrow = today.plusDays( 1 ) ;

ThreeTen-Extra

I suggest you add the ThreeTen-Extra library to your project. This gives you access to the LocalDateRange class to represent a pair of LocalDate objects.

LocalDateRange dateRange = LocalDateRange.of( today , today.plusWeeks( 1 ) ) ;

I am guessing this class could be used in place of your homemade intervall class. By the way, class names in Java should have an initial uppercase letter, Intervall class name, intervall instance variable name.

This LocalDateRange class has several methods for comparisons, such as abuts, contains, overlaps, and so on.

boolean containsJan23 = dateRange.contains( LocalDate.of( 2020 , Month.JANUARY , 23 ) ) ;
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
  • 1
    this does not explain the strange behavior. As written I am in the course of introducing the Date from Java 8 but still I would like to understand. – Peter Feb 05 '20 at 08:01
  • 1
    You can tell your teacher from me that “the `Date` from Java 8” is absurd. The `Date` class is from Java 1.0 and was finally *outmoded* with the introduction of `LocalDate` and java.time in Java 8. – Ole V.V. Feb 06 '20 at 17:50
1

this does not explain the strange behavior. As written I am in the course of introducing the Date from Java 8 but still I would like to understand.

Let’s just inspect the first two lines of your log output for a start:

my log comments: Intervallanfang 01/01/2018 nächstes: 01/02/2018
my log comments: tmp lastday 1/1/2018

(For readers who don’t read German: the first line means interval start 01/01/2018 next: 01/02/2018.)

The dates nächstes and tmp lastday come from the same element from your deliveryList, namely deliveryList.get(i+1). 01/02/2018 comes from getDatumasString() whereas 1/1/2018 comes from getYear(), getMonth() and getDay(). In the output you have correctly added 1 to the month number because the months are insanely numbered from 0 instead of 1 (probably a trait from the confusing GregorianCalendar class). So when these two dates do not agree, the problem must be inside whatever class those deliveries belong to. With the information you have provided, I don’t know what class that is, and even less what the problem in that class is (there was a reason why in a comment I encouraged you to create a Minimal, Reproducible Example).

There is a pattern, though: When we read your entire log output, nächstes and tmp lastday always agree on year and on day of month (even in the last iteration, where day of month is 2 for a change). And tmp lastday always gives month as 1 (January) no matter what it is in nächstes (2, 6 or 1). So it would seem that there’s a bug in getMonth() that causes it to return 0 (January) always irrespective of what is in the object.

Why getMonth() always returns January, it’s guesswork from me, but I dare start guessing. It might come from parsing the date string using SimpleDateFormat, a notorious troublemaker of a class. There are two typical errors that regularly causes it to return a date in January even though the input string is in a different month:

  1. Using upper case Y instead of lower case y for year in a format pattern string. See for example java parsing string to date.
  2. Even more likely in your case, using lower case m for month. See for example SimpleDateFormat ignoring month when parsing

If any of these two turns out to fit your issue, I can almost guarantee you one thing: It would not have happened with java.time, the modern Java date and time API that Basil Bourque rightfully endorses in the other answer. java.time much better catches such errors long before you need to start debugging them.

Nimantha
  • 6,405
  • 6
  • 28
  • 69
Ole V.V.
  • 81,772
  • 15
  • 137
  • 161