java 日历和数组列表:我如何分配正确的日期?

62lalag4  于 2023-09-29  发布在  Java
关注(0)|答案(2)|浏览(76)

lastDay变量下面的变量并不总是包含列表的i+1。不知道为什么。我正在介绍Java 8中的Date。但我还是想知道出了什么问题...彼得(非常初学者)

// 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);
        }

并且结果是
我的日志评论:Intervallanfang 01/01/2018 nächstes:01/02/2018
我的日志评论:最后一天1/1/2018
我的日志评论:2017年12月31日
我的日志评论:Intervallanfang 01/02/2018 nächstes:01/06/2018
我的日志评论:最后一天1/1/2018
我的日志评论:结束intervall 31/12/2017
我的日志评论:Intervallanfang 01/06/2018 nächstes:01/01/2019
我的日志评论:最后一天1/1/2019
我的日志评论:结束intervall 31/12/2018
我的日志评论:Intervallanfang 01/01/2019 nächstes:01/01/2020
我的日志评论:最后一天1/1/2020
我的日志评论:2019年12月31日
我的日志评论:Intervallanfang 01/01/2020 nächstes:01/06/2020
我的日志评论:最后一天1/1/2020
我的日志评论:2019年12月31日
我的日志评论:Intervallanfang 01/06/2020 nächstes:02/01/2021
我的日志评论:最后一天2/1/2021
我的日志评论:结束间隔1/1/2021
如要求更多的源代码

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);

.....

wko9yo5t

wko9yo5t1#

避免使用遗留的日期时间类

您正在使用糟糕的日期-时间类,这些类在几年前就被JSR 310中定义的现代 java.time 类所取代。不要使用DateCalendar

java.time

找到今天的日期。需要时区。对于任何给定的时刻,地球仪因时区而异。

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

生成标准ISO 8601格式的字符串YYYY-MM-DD。注意 java.time 使用了合理的编号,所以月份是1-12,不需要+ 1

String output = today.toString() ;

要在该日期上加上或减去天数,请调用plusDaysminusDaysjava.time 类使用不可变对象。因此,我们并没有改变原来的对象,而是得到了一个新的LocalDate对象。

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

ThreeTen-Extra

我建议您将ThreeTen-Extra库添加到项目中。这使您可以访问LocalDateRange类来表示一对LocalDate对象。

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

我猜这个类可以用来代替你自制的intervall类。顺便说一句,Java中的类名应该有一个大写字母开头,Intervall类名,intervall示例变量名。
这个LocalDateRange类有几个用于比较的方法,如邻接、包含、重叠等。

boolean containsJan23 = dateRange.contains( LocalDate.of( 2020 , Month.JANUARY , 23 ) ) ;
oxf4rvwz

oxf4rvwz2#

这不能解释奇怪的行为。正如所写的,我正在介绍Java 8中的Date,但我仍然想了解。
让我们从检查日志输出的前两行开始:

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

(For不懂德语的读者:第一行表示间隔开始01/01/2018 next:01/02/2018.)
日期nächstestmp lastday来自deliveryList的同一个元素,即deliveryList.get(i+1)01/02/2018来自getDatumasString(),而1/1/2018来自getYear()getMonth()getDay()。在输出中,您已经正确地将1添加到月份编号中,因为月份编号是从0而不是1开始的(可能是令人困惑的GregorianCalendar类的特征)。因此,当这两个日期不一致时,问题一定在这些交付所属的任何类别内。根据您提供的信息,我不知道这是什么类,更不知道该类中的问题是什么(在评论中,我鼓励您创建一个最小的可复制示例是有原因的)。
但有一种模式:当我们读取整个日志输出时,nächstestmp lastday在年份和月份的日期上总是一致的(即使在最后一次迭代中,月份的日期是2)。tmp lastday总是给出月份为1(1月),无论它在nächstes中是什么(2,6或1)。因此,似乎getMonth()中有一个bug,导致它总是返回0(一月),而不管对象中有什么。
为什么getMonth()总是返回一月,这是我的猜测,但我敢开始猜测。它可能来自使用SimpleDateFormat解析日期字符串,这是一个臭名昭著的麻烦制造者。有两个典型的错误会经常导致它返回一月份的日期,即使输入字符串是在不同的月份:
1.在格式模式字符串中使用大写字母Y而不是小写字母y表示年份。例如java parsing string to date
1.在您的情况下,更有可能使用小写的m表示月份。例如SimpleDateFormat ignoring month when parsing
如果这两个中的任何一个符合你的问题,我几乎可以向你保证一件事:这不会发生在java.time上,这是BasilBourque在另一个答案中正确认可的现代Java日期和时间API。time可以更好地在您需要开始调试这些错误之前捕获这些错误。

相关问题