SNTT: Reconstructing DateRanges

Thu Feb 27 09:53:46 EST 2014

Tags: sntt

In the OpenNTF API chat, I was reminded yesterday of how terribly broken DateRange retrieval is in Java. Specifically, though you can create date ranges and use them in view lookups, retrieving them from documents or view entries is FUBAR. To wit:

Field Value 02/27/2014, 02/28/2014, 02/27/2014 - 02/28/2014, 01/01/2014 12:00 AM - 01/02/2014 12:00 PM
doc.getItemValue("SomeField") [02/27/2014, 02/28/2014, 02/27/2014, 02/28/2014, 01/01/2014 12:00:00 AM EST, 01/02/2014 12:00:00 PM EST]

Note: this is consistent with LotusScript
doc.getItemValueDateTimeArray("SomeField") [02/27/2014, 02/28/2014, null, null]
session.evaluate(" SomeField ", doc) [02/27/2014, 02/28/2014, 02/27/2014, 02/28/2014, 01/01/2014 12:00:00 AM EST, 01/02/2014 12:00:00 PM EST]
entry.getColumnValues().get(columnIndex) [02/27/2014, 02/28/2014, 02/27/2014, 02/28/2014, 12/29/**** 12:22:46 PM EST, 10/03/**** 04:53:38 PM EDT]

Note: the final values are inconsistent across multiple executions

So it appears that getItemValueDateTimeArray chokes and gives up when it encounters date ranges, instead just plopping a null value in the Vector. View entries appear to wander off into some invalid-data wilderness, perhaps not properly parsing the ITEM_VALUE_TABLE attached to the entry. Or maybe it's in the ITEM_TABLE. I don't remember; it's complicated. In any event, view entries are a mostly-lost cause.

Document item values, though, are salvagable. Since getItemValue returns the start/end values and getItemValueDateTimeArray returns nulls in the spots that represent DateRanges (which are always at the end, but that's incidental), the two can be matched up to reconstruct the real value. I wrote a method to do just this - it doesn't do any checking to make sure that the item value actually contains DateTimes (and would throw a ClassCastException if it contains something else), it should do the job when you know the item contents:

@SuppressWarnings("unchecked")
private List<Base> noSeriouslyGetItemValueDateTimes(final Session session, final Document doc, final String itemName) throws NotesException {
	List<Base> result = new Vector<Base>();

	List<DateTime> dateTimes = doc.getItemValue(itemName);
	List<DateTime> dateTimesArray = doc.getItemValueDateTimeArray(itemName);
	int foreignIndex = 0;
	for(DateTime dt : dateTimesArray) {
		if(dt != null) {
			result.add(dateTimes.get(foreignIndex++));
			dt.recycle();
		} else {
			DateTime dt1 = dateTimes.get(foreignIndex++);
			DateTime dt2 = dateTimes.get(foreignIndex++);
			DateRange range = session.createDateRange(dt1, dt2);
			result.add(range);
		}
	}

	return result;
}

I'll probably add a similar method to the OpenNTF API (or maybe fix getItemValueDateTimeArray), but this should do for now.

Commenter Photo

Giulio Campobassi - Sun Mar 02 21:53:42 EST 2014

Any method that starts with "noSeriously...." has got to be a good method... +1

New Comment