3

Here is what I want to do: I got a date range from e.g. 03.04.2013 to 23.04.2013 - that's my main range.

Now I have the possibility to create some own time ranges (e.g. 04.04.2013 to 09.04.2013 and 11.04.2013 to 23.04.2013). Those have to cover the whole main range, so every day of the main range (excluding weekens) needs an corresponding day in my own time ranges.

My plan would be to create an Array for the main range. Then I check each day of my own time ranges against the main range. If there is an accordance, I would remove the day from the main range. So in the end, if everything is ok, there would be an emtpy array, because all days are covered by my own time ranges. If not, then the days not covered would still be in the main range and I could work with them (in this example: 03.04.2013, 10.04.2013)

Does anybody have an better idea to solve this problem? NotesDateTimeRanges?

M. Schaetzl
  • 251
  • 2
  • 15
  • hmm - really wonder what's so bad about this question that someone gave it a -1... And your answer is fine I think. Don't forget to recycle your Notes objects, though... – Lothar Mueller May 03 '13 at 13:40

2 Answers2

2

I would add the dates into a sorted collection and then a "pirate algorithm". Look left, look right and if any of the looks fails you can stop (unless you want to find all missing dates).

Off my head (you might need to massage the final list to store the value back):

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;   
}
Community
  • 1
  • 1
stwissel
  • 20,110
  • 6
  • 54
  • 101
  • Post your solution once you are done. Things to watch out for: edge condition -> does getWorkDayList include the last day or not (and should it)? You might need to convert the entries inside dateList back to NotesDateTime objects – stwissel May 06 '13 at 10:37
1

I've done it this way now (seems to work so far):

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

And I'm using this function (adopted from this 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;
}
Community
  • 1
  • 1
M. Schaetzl
  • 251
  • 2
  • 15