检查日期范围与其他一些日期范围的缺失天数

Posted

技术标签:

【中文标题】检查日期范围与其他一些日期范围的缺失天数【英文标题】:Check date range vs. some other date ranges for missing days 【发布时间】:2013-05-03 06:17:25 【问题描述】:

这是我想做的: 我得到了一个日期范围,例如03.04.2013 到 23.04.2013 - 这是我的主要范围。

现在我可以创建一些自己的时间范围(例如 04.04.2013 到 09.04.2013 和 11.04.2013 到 23.04.2013)。这些必须涵盖整个主要范围,因此主要范围的每一天(不包括周末)都需要在我自己的时间范围内对应一天。

我的计划是为主要范围创建一个数组。然后我检查我自己时间范围的每一天与主要范围。如果有一致,我会从主要范围中删除这一天。 所以最后,如果一切正常,就会有一个空数组,因为所有的日子都在我自己的时间范围内。如果没有,那么未涵盖的日期仍将在主要范围内,我可以使用它们(在此示例中:03.04.2013、10.04.2013)

有没有人有更好的办法来解决这个问题? NotesDateTimeRanges?

【问题讨论】:

hmm - 真的很想知道这个问题有什么不好以至于有人给了它一个-1......我认为你的答案很好。不过,不要忘记回收您的 Notes 对象... 感谢您的留言! :) 【参考方案1】:

我会将日期添加到sorted collection,然后是“海盗算法”。向左看,向右看,如果有任何一个失败,你可以停下来(除非你想找到所有丢失的日期)。

我不知道(您可能需要修改最终列表以将值存储回来):

var AbsenctSince:NotesDateTime; //Start Date - stored in the NotesItem
var endDate:NotesDateTime; // Return, could be in Notes or Today
var wfDoc:NotesDocument = docApplication.getDocument();
var responseCDs:NotesDocumentCollection = wfDoc.getResponses();
var docResponse:NotesDocument;
var nextResponse:NotesDocument;

//Get the date, which limits the function - if there is a return information, then this is the limit, else today
AbsenctSince = wfDoc.getDateTimeValue("AbsentSince") ;
if (wfDoc.hasItem("ReturnInformationDat")) 
    endDate = wfDoc.getDateTimeValue("ReturnInformationDat");
 else 
    endDate = session.createDateTime("Today");


//Get all days between two dates - as pure Java!
var dateList:java.util.List = getWorkDayList(AbsenctSince.toJavaDate(), endDate.toJavaDate());

// Looping once through the reponse documents
var docResponse = responseCDs.getFirstDocument();
while (docResponse != null) 
    nextResponse = responseCDs.getNextDocument(docResponse);
    var CDValidSince:NotesDateTime = docResponse.getDateTimeValue("CDValidSince");
    var CDValidTill:NotesDateTime = docResponse.getDateTimeValue("CDValidTill");
    // Now we need get all days in this range
    var removeDates:java.util.List = getWorkDayList(CDValidSince.toJavaDate(),CDValidTill.toJavaDate());
    dateList.removeAll(removeDates);
    docResponse.recycle();
    docResponse = nextResponse;  
   
// Both docs are null - nothing to recycle left
// Now we only have uncovered dates left in dateList

docApplication.replaceItemValue("openDates", dateList);

// Cleanup
try 
 AbsenctSince.recycle();
 endDate.recyle();
 wfDoc.recycle();
 responseCDs.recycle(); 
 catch (e) 
dBar.error(e);


function getWorkDayList(startDate, endDate) 
var dates:java.util.List = new java.util.ArrayList();
var calendar:java.util.Calendar = new java.util.GregorianCalendar();
    calendar.setTime(startDate);
    while (calendar.getTime().before(endDate)) 
   var workDay = calendar.get(calendar.DAY_OF_WEEK);
   if (workDay != calendar.SATURDAY && workDay != calendar.SUNDAY) 
        var result = calendar.getTime();    
        dates.add(result);
   
     calendar.add(java.util.Calendar.DATE, 1);
   
   return dates;   

【讨论】:

完成后发布您的解决方案。需要注意的事情:边缘条件 - > getWorkDayList 是否包括最后一天(并且应该)?您可能需要将 dateList 中的条目转换回 NotesDateTime 对象【参考方案2】:

我现在已经这样做了(到目前为止似乎有效):

var dateArray = new Array();
var responseCDs:NotesDocumentCollection = docApplication.getDocument().getResponses();
var dt:NotesDateTime = session.createDateTime("Today");
var wfDoc = docApplication.getDocument();
dt.setNow();

//Get the date, which limits the function - if there is a return information, then this is the limit, else today
var AbsenctSince:NotesDateTime = session.createDateTime(wfDoc.getItemValue("AbsentSince").toString().substr(0,19));
if (wfDoc.hasItem("ReturnInformationDat")) 
    var endDate:NotesDateTime = session.createDateTime(wfDoc.getItemValue("ReturnInformationDat").toString().substr(0,19));
 else 
    var endDate:NotesDateTime = session.createDateTime("Today");


//Get all days between two dates
dateArray = getDates(AbsenctSince, endDate);

for (var i=dateArray.length-1; i >= 0 ; i--) 
    var checkDate:NotesDateTime = session.createDateTime(dateArray[i].toString().substr(0,19));
    var day = checkDate.toJavaDate().getDay();

    //Remove weekends first
    if ((day == 6) || (day == 0))  //6 = Saturday, 0 = Sunday
        dBar.info("splice: " + dateArray[i]);
        dateArray = dateArray.splice(i,1);
     else 
        var docResponse = responseCDs.getFirstDocument();
        //Work through all response docs to check if any date is covered
        while (docResponse != null) 
            var CDValidSince:NotesDateTime = session.createDateTime(docResponse.getItemValue("CDValidSince").toString().substr(0,19));
            var CDValidTill:NotesDateTime = session.createDateTime(docResponse.getItemValue("CDValidTill").toString().substr(0,19));

            //checkDate covered? If yes, it will be removed
            if (checkDate.timeDifference(CDValidSince)/86400 >= 0 && checkDate.timeDifference(CDValidTill)/86400 <= 0 ) 
                dBar.info("splice: " + dateArray[i]);
                dateArray = dateArray.splice(i,1);
            

            docResponse = responseCDs.getNextDocument();
        
       


docApplication.replaceItemValue("openDates", dateArray);

而我正在使用这个函数(来自question here):

function getDates(startDate:NotesDateTime, endDate:NotesDateTime) 
    var dateArray = new Array();
    var currentDate:NotesDateTime = startDate;
    while (endDate.timeDifference(currentDate) > 0) 
        dateArray.push( currentDate.getDateOnly() );
        currentDate.adjustDay(1);
    
    return dateArray;

【讨论】:

以上是关于检查日期范围与其他一些日期范围的缺失天数的主要内容,如果未能解决你的问题,请参考以下文章

从日期范围生成天数

MySQL:查找日期范围之间的缺失日期

计算介于预定义日期范围之间的天数

mysql检查其他日期范围内的日期范围

给定日期范围(开始日期和结束日期),我如何计算天数,不包括 .Net 中指定的星期几?

日期范围内给定年份的天数