代码之家  ›  专栏  ›  技术社区  ›  D3X

Java中的日期列表增量方法

  •  1
  • D3X  · 技术社区  · 11 年前

    好的,这是一个问题,我正在尝试制定一个方法,它可以帮助我将从日期a到日期B的所有日期放在列表中,并将日期类型放在列表前面,例如: 日期A-2013年1月1日日期B-2013年3月3日

    结果应该是这样的

    2013年1月1日星期二

    2013年1月2日星期三

    2013年1月3日星期四

    这应该在地图/列表中。

    我厌倦了以下方法,首先至少在列表中列出日期,但出现了Java堆外空间错误。

    public static List<ShiftDate> createShiftDate() {
            String startDate = "2013-01-01";
    
            String lastDate = "2013-01-28";
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
            List<ShiftDate> shiftDateList = new ArrayList<ShiftDate>();
            ShiftDate shiftDate = new ShiftDate();
    
            try {
                Date startDate1 = formatter.parse(startDate);
                Date endDate1 = formatter.parse(lastDate);
                Calendar c = Calendar.getInstance();
                Date newDate = startDate1;
    
                while (newDate.compareTo(endDate1) < 0) {
                    c.setTime(newDate);
                    c.add(Calendar.DATE, 1);
                    shiftDate.setDateString(c.getTime().toString());
                    shiftDateList.add(shiftDate);
                }
    
            } catch (ParseException e) {
                e.printStackTrace();
            }
            for (ShiftDate shiftDate1 : shiftDateList) {
                System.out.println(shiftDate1);
            }
            return shiftDateList;
        }
    
    5 回复  |  直到 11 年前
        1
  •  4
  •   Raze    11 年前
    1. 您没有更新循环条件变量( newDate ). 应该是这样的:

          while (newDate.compareTo(endDate1) < 0) {
              c.setTime(newDate);
              c.add(Calendar.DATE, 1);
              newDate = c.getTime();
              shiftDate.setDateString(c.getTime().toString());
              shiftDateList.add(shiftDate);
          }
      
    2. 其他问题:格式化程序设置为dd-MM-yyyy模式,但实际日期是yyyy-MM-dd模式。

    3. 此外,您需要每次或每次创建一个ShiftDate的新实例。否则,您将得到包含相同(上次更新)日期值的整个列表。

          while (newDate.compareTo(endDate1) < 0) {
              c.setTime(newDate);
              c.add(Calendar.DATE, 1);
              newDate = c.getTime();
              shiftDate = new ShiftDate();
              shiftDate.setDateString(c.getTime().toString());
              shiftDateList.add(shiftDate);
          }
      
        2
  •  1
  •   Weibo Li    11 年前

    问题就在这里,你没有增加 newDate 值,因此循环永远不会结束:

    while (newDate.compareTo(endDate1) < 0) {
                    c.setTime(newDate);
                    c.add(Calendar.DATE, 1);
                    shiftDate.setDateString(c.getTime().toString());
                    shiftDateList.add(shiftDate);
                }
    
        3
  •  1
  •   Ruchira Gayan Ranaweera    11 年前

    你可以试试这样的

        String startDate = "2013-01-01";
        String lastDate = "2013-01-28";
        SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd");
        Calendar st=Calendar.getInstance();
        Calendar lt=Calendar.getInstance();
        st.setTime(simpleDateFormat.parse(startDate));
        lt.setTime(simpleDateFormat.parse(lastDate));
        List<Date> list=new ArrayList<>();
        for (Date date = st.getTime(); !st.after(lt); st.add(Calendar.DATE, 1), 
                                                               date = st.getTime())
        {
           list.add(date);
        }
    
        4
  •  1
  •   Max    10 年前

    我最近开发了 Lamma date 为该用例设计的库。有了Lamma,这个问题可以这样解决:

    public static List<Date> createShiftDate() {
        List<Date> dates = Dates.from(2013, 1, 1).to(2013, 1, 28).build();
    
        for (Date date: dates) {
            System.out.println(date.toISOString() + ", " + date.dayOfWeek());
        }
    
        return dates;
    }
    

    并且输出为:

    2013-01-01, Tuesday
    2013-01-02, Wednesday
    2013-01-03, Thursday
    ...
    
        5
  •  1
  •   Basil Bourque    8 年前

    其他答案是正确的。

    时区

    好吧,除了所有的答案和问题都忽略了定义一天意味着什么的时区问题之外,大部分都是正确的。

    Joda时间

    下面是相同类型的代码 Joda-Time 、和地址时区。

    情侣笔记:

    • 在Joda Time中,DateTime确实知道其指定的时区,而java.util.Date则不知道。
    • 请注意呼叫 withTimeAtStartOfDay 获得一天中的第一刻。通常是00:00:00,但并不总是如此。
    • 通常应指定 time zone 而不是依赖违约。
      此示例任意选择 Kolkata time zone (原名印度加尔各答)。
    • 通常应指定 Locale 而不是依赖违约。
      请注意呼叫 withLocale 作为本地化为法语的示例 Puducherry .

    示例代码

    // You might want to store the date times, and then create strings later as output. I'll show both.
    java.util.List<DateTime> dateTimes = new java.util.ArrayList<DateTime>(3);
    java.util.List<String> dateTimeStrings = new java.util.ArrayList<String>(3);
    
    DateTimeZone timeZone = DateTimeZone.forID( "Asia/Kolkata" );
    DateTime start = new DateTime( 2014, 1, 1 , 2, 3, 4, timeZone ).withTimeAtStartOfDay();
    DateTimeFormatter formatter = DateTimeFormat.forPattern( "dd-MM-yyyy EEEE" ).withLocale( Locale.FRENCH );
    for ( int i = 0; i < 3; i++ ) {
        DateTime nextDateTime = start.plusDays( i );
        dateTimes.add( nextDateTime );
        dateTimeStrings.add( formatter.print( nextDateTime ) );
    }
    

    转储到控制台

    System.out.println( "dateTimes: " + dateTimes );
    System.out.println( "dateTimeStrings: " + dateTimeStrings );
    

    运行时

    dateTimes: [2014-01-01T00:00:00.000+05:30, 2014-01-02T00:00:00.000+05:30, 2014-01-03T00:00:00.000+05:30]
    dateTimeStrings: [01-01-2014 mercredi, 02-01-2014 jeudi, 03-01-2014 vendredi]
    

    java时间

    这个 java.time 框架内置于Java8中,后来取代了Joda Time以及与最早版本的Java捆绑在一起的麻烦的旧日期时间类。

    这个 LocalDate 类支持不带时间和时区的仅日期值。

    方便的 DayOfWeek enum可以生成星期几的本地化显示名称。这个 TextStyle 表示显示名称的长度或缩写。

    您的输入字符串是标准的 ISO 8601 总体安排它们可以直接由 本地日期 类,因为所有java.time类在解析和生成表示日期时间值的字符串时默认使用ISO 8601格式。

    处理时间跨度的最佳实践通常是“半开放”,其中的开始是 包含全部费用 而结尾是 独家 。所以我们使用 isBefore 在下面的循环中。

    LocalDate start = LocalDate.parse( "2013-01-01" );
    LocalDate stop = LocalDate.parse( "2013-01-28" );
    
    List<String> outputs = new ArrayList<>();
    LocalDate localDate = start ;
    Locale locale = Locale.CANADA_FRENCH;  // Or Locale.US Locale.UK etc.
    while ( localDate.isBefore( stop ) ) {
        String displayName = localDate.getDayOfWeek().getDisplayName( TextStyle.FULL , locale );
        String localDateString = localDate.toString();
        String output = localDateString + " " + displayName;
        outputs.add( output );
    
        // Set up next loop.
        localDate = localDate.plusDays( 1 );
    }