【问题标题】:Validate Item Fall Within Start Date And End Date验证项目是否在开始日期和结束日期内
【发布时间】:2023-04-07 12:52:01
【问题描述】:

我有一个 java 程序,它将检查每个项目的开始日期和结束日期。每个项目必须有自己特定的开始日期和结束日期范围。如果新的开始日期和结束日期的范围在旧的开始日期和结束日期范围内,系统将提示错误消息。例如:

 Company: ABC
 Item_Number     Start Date      End Date
 Item 11A        01/08/2014      01/09/2014  
 Item 11B        02/09/2014      30/09/2014
 Item 11C        18/08/2014      30/08/2014

当最终用户尝试添加项目 11C 时,系统会提示错误消息。有什么建议可以解决这个问题吗?非常感谢。

【问题讨论】:

  • Date#before, Date#after...和某种循环

标签: java arrays date


【解决方案1】:

你可以这样做:

public class DateDemo {

    public static void main(String[] args) {

        Date date = new Date(11, 5, 21);
        Date date2 = new Date(15, 1, 21);

        // tests if date2 is before date and prints result
        boolean before = date2.before(date);
        if (before) {
            System.out.println("Date 2 is before date: " + before);
            throw new RuntimeException("Error with dates");
        }

    }
}

当然,这只是一个例子,因为我不知道这个日期是从哪里来的。 而且您必须在循环中执行此操作才能验证所有这些。

【讨论】:

  • 如果它们相等呢??
  • 为什么要抛出 RuntimeException?
  • 嗨,如果它们相等,系统也会显示错误消息。我尝试使用嵌套循环,但我没有得到我想要的结果。
  • 在我的拙见中,我认为我需要一个循环来保持它的正确检查?
【解决方案2】:

使用Guava Range 可以简化您的问题

public class ValidateDateFall {

    public static void main(String args[]) throws ParseException {

        List<Item> itemArr = Lists.newArrayList();

        itemArr.add(new Item("11A", "01/08/2014", "01/09/2014"));
        itemArr.add(new Item("11B", "02/09/2014", "30/09/2014"));
        itemArr.add(new Item("11C", "18/08/2014", "30/08/2014"));

        Range<Date> currentPeriod = null;

        for(Item item:itemArr) {

            // Initial Current Range
            if(currentPeriod == null) {
                currentPeriod = Range.closed(item.startDate, item.endDate);
                continue;
            } 

            // Check item start date and end date is within in current period
            Range<Date> itemRange = Range.closed(item.startDate, item.endDate);
            boolean isEnclosed = currentPeriod.encloses(itemRange);

            // if within current item then prompt error message or not then extend the period
            if(isEnclosed) {
                System.out.println("Prompt Error Message:" + item);
            } else {
                currentPeriod = currentPeriod.span(itemRange);
            }
        }
    }
}

// Item Pojo
class Item{

    private static final SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");

    public String name;
    public Date startDate;
    public Date endDate;

    public Item(String name, String startDateStr, String endDate) throws ParseException {
        this.name = name;
        this.startDate = sdf.parse(startDateStr);
        this.endDate = sdf.parse(endDate);;
    }

    @Override
    public String toString() {
        return Objects.toStringHelper(this.getClass()).add("start date", startDate).add("end date", endDate).toString();
    }
}

【讨论】:

    【解决方案3】:

    这里是使用Joda-TimeGuava's Range 的可能实现的简单单元测试。

      import com.google.common.collect.Lists;
      import com.google.common.collect.Range;
      import org.joda.time.LocalDate;
      import org.junit.Test;
      import java.util.List;
      import static org.junit.Assert.assertEquals;
    
      public class ItemDateRangeTest {
    
        static class Item {
          private final String id;
          private final LocalDate startDate;
          private final LocalDate endDate;
    
          public Item(String id, LocalDate startDate, LocalDate endDate) {
            this.id = id;
            this.startDate = startDate;
            this.endDate = endDate;
          }
    
          public String getId() {
            return id;
          }
    
          public LocalDate getStartDate() {
            return startDate;
          }
    
          public LocalDate getEndDate() {
            return endDate;
          }
    
          public Range<LocalDate> getRange() {
            // Closed range includes the lower and upper bounds
            return Range.closed(startDate, endDate);
          }
        }
    
    
        static class ItemStore {
          private final List<Item> items = Lists.newArrayList();
    
          public void add(Item newItem) throws IllegalArgumentException{
            for (Item item : items) {
                if (item.getRange().isConnected(newItem.getRange())) {
                  throw new IllegalArgumentException("error: date range overlap!");
                }
            }
            items.add(newItem);
          }
          public List<Item> getItems() {
            return items;
          }
        }
    
        @Test()
        public void testItemDateRangeNoOverlap() {
          final ItemStore itemStore = new ItemStore();
          Item itemA = new Item("11A", new LocalDate(2014, 8, 1), new LocalDate(2014, 9, 1));
          Item itemB = new Item("11B", new LocalDate(2014, 9, 2), new LocalDate(2014, 9, 30));
          itemStore.add(itemA);
          itemStore.add(itemB);
          assertEquals(itemStore.getItems().get(0), itemA);
          assertEquals(itemStore.getItems().get(1), itemB);
        }
    
        @Test(expected = IllegalArgumentException.class)
        public void testItemDateRangeWithOverlap() {
          final ItemStore itemStore = new ItemStore();
          itemStore.add(new Item("11A", new LocalDate(2014,8,1), new LocalDate(2014,9,1)));
          itemStore.add(new Item("11B", new LocalDate(2014,9,2), new LocalDate(2014,9,30)));
          itemStore.add(new Item("11C", new LocalDate(2014,8,18), new LocalDate(2014,8,30)));
        }
      }
    

    【讨论】:

      【解决方案4】:

      日期范围可能很棘手...

      首先,您要确保原始开始日期不等于比较开始日期或结束日期,并且原始结束日期不等于比较开始日期或结束日期

      startDate.equals(originalStartDate) ||
      startDate.equals(originalEndDate) ||
      endDate.equals(originalStartDate) ||
      endDate.equals(originalEndDate)
      

      如果一切正常 (false),那么您需要检查比较开始日期是否介于原始开始日期或结束日期之间,以及比较结束日期​​是否介于原始开始日期或结束日期之间...

      (startDate.after(originalStartDate) || startDate.before(originalEndDate) ||
      (endDate.after(originalStartDate) || endDate.before(originalEndDate)
      

      这会尝试捕获两个范围相互包含或重叠的任何点...

      因为我实际上写了一些测试代码......

      import java.text.ParseException;
      import java.text.SimpleDateFormat;
      import java.util.ArrayList;
      import java.util.Date;
      import java.util.List;
      
      public class CompareDates {
      
          public static void main(String[] args) {
              try {
                  List<Event> events = new ArrayList<Event>(3);
                  events.add(new Event(toDate("01/08/2014"), toDate("01/09/2014")));
                  events.add(new Event(toDate("02/09/2014"), toDate("30/09/2014")));
      
                  Date start = toDate("18/08/2014");
                  Date end = toDate("30/08/2014");
      
                  for (Event evt : events) {
                      System.out.println(evt.conflicts(start, end));
                  }
      
              } catch (ParseException exp) {
                  exp.printStackTrace();
              }
          }
      
          public static Date toDate(String value) throws ParseException {
              return new SimpleDateFormat("dd/MM/yyyy").parse(value);
          }
      
          public static class Event {
              private Date startDate;
              private Date endDate;
      
              public Event(Date startDate, Date endDate) {
                  this.startDate = startDate;
                  this.endDate = endDate;
              }
      
              public boolean conflicts(Date start, Date end) {
      
                  return start.equals(startDate) ||
                                  start.equals(endDate) ||
                                  end.equals(startDate) ||
                                  end.equals(endDate) ||
                                  (start.after(startDate) && start.before(endDate)) || 
                                  (end.after(startDate) && end.before(endDate));
      
              }
      
          }
      
      }
      

      【讨论】:

      • 我第一次尝试你的方法~
      猜你喜欢
      • 1970-01-01
      • 2015-09-29
      • 1970-01-01
      • 1970-01-01
      • 2010-10-24
      • 1970-01-01
      • 2022-01-06
      • 1970-01-01
      • 2019-07-11
      相关资源
      最近更新 更多