Why Can't You Just Use java.util.Date for Notes Dates in Java?
The moment you need to do something with a Notes date in Java — compare it, add days, write it back — you hit something awkward: you can’t just use java.util.Date. Domino’s date in the Java API is a class called DateTime, and it lives in a different world from Java’s own time types. You go into DateTime, do the work, and come back out.
This DateTime has three things that trip up people coming from LotusScript: it’s a back-end object that leaks memory, it stores dates as strings, and it crosses to and from java.util.Date over a bridge called toJavaDate(). This piece walks all three.
TL;DR
DateTimeis a back-end object, not a Java date. The docs say it “represents a date and time” and extendsBase. It’s backed by a handle the garbage collector can’t see — create it in a loop withoutrecycleand it leaks.- Create it with
session.createDateTime(...). It takesString,java.util.Date, orjava.util.Calendar; the time zone is set automatically from Domino’s regional settings. Pass a string and a bad or empty value throws an “Invalid date” exception. toJavaDate()is the exit. It converts aDateTimeinto ajava.util.Date, and from there onto modernjava.time.- Reads and writes go through string properties:
getDateOnly/getTimeOnly/getGMTTime/getLocalTimeall return strings;getLocalTimeis writable. - Date math happens on the object:
setNow,adjustDay/adjustHour/adjustMonth/adjustYear,timeDifference(returns the gap between two times in seconds).
What it is: a back-end object that represents a date
The docs define DateTime briefly — it “represents a date and time,” extends Base, and is held by Session, Document, Database, View, and others. The load-bearing phrase is “extends Base”: like Document and Session, DateTime is a heavyweight back-end object with a C handle behind it.
That sets its defining trait: it leaks memory. In a loop over tens of thousands of documents, calling session.createDateTime(...) or reading a DateTime out of a field each time, those objects pile up. This is exactly the trap the site’s recycle() piece describes, and DateTime is the easiest one to overlook — it looks like “just a date,” not something as heavy as Document. But in the Java API, dates need collecting too.
Creating it: three doors into createDateTime
You don’t new a DateTime — you ask the Session for one. createDateTime has three overloads:
public DateTime createDateTime(String date) throws NotesExceptionpublic DateTime createDateTime(java.util.Date date) throws NotesExceptionpublic DateTime createDateTime(java.util.Calendar date) throws NotesException- Pass a
String: the most intuitive, and the most dangerous — the docs state plainly, “An invalid date-time or empty string results in an ‘Invalid date’ exception.” Bad format or an empty string throws, so wrap untrusted string sources in try/catch. - Pass a
java.util.Date: cleanest, built straight from Java’s own date. - Pass a
java.util.Calendar: carries a time zone with it (supported since Release 6).
On time zones, the docs say the created DateTime picks up its zone automatically from Domino’s regional settings — the same as LotusScript, but in Java you’ll more often need to handle it explicitly; see below.
The bridge: toJavaDate()
DateTime isn’t great for modern date math itself; the real exit is toJavaDate():
public java.util.Date toJavaDate() throws NotesExceptionThe docs put it in one line — it “Converts a Notes date and time into a java.util.Date object.” Once you hold a java.util.Date, you’ve stepped out of Domino’s time world into Java’s own, and modern java.time is one step away:
java.util.Date jd = dt.toJavaDate();java.time.LocalDateTime ldt = jd.toInstant().atZone(java.time.ZoneId.systemDefault()).toLocalDateTime();(That last bit is plain Java, not the Domino API — but it’s the practical path for getting a Notes date into LocalDate / LocalDateTime for real date math. DateTime is for talking to Domino; java.time is for calculating.)
Reading and writing: the properties are strings
Several of DateTime’s read properties return strings, not numbers:
getDateOnly(): the date part as a string.getTimeOnly(): the time part as a string.getGMTTime(): the value converted to GMT, as a string.getLocalTime(): the local-zone value as a string — and this one is writable.getTimeZone(): an integer, the hours to add for GMT conversion.
For math, the operations act on the object directly: setNow() sets it to the current moment, adjustDay(n) / adjustHour(n) / adjustMonth(n) / adjustYear(n) add or subtract that unit, and timeDifference(other) returns the gap between two DateTimes in seconds. These map almost one-to-one onto LotusScript’s NotesDateTime — the only difference is that every intermediate DateTime you create needs collecting when you’re done.
A complete example
Create a date, compute thirty days out, cross to a Java type, and remember to collect:
DateTime due = session.createDateTime("2026-08-15"); // a bad string throwsdue.adjustDay(30); // +30 days in place
java.util.Date jd = due.toJavaDate(); // cross the bridge to Java time
DateTime now = session.createDateTime("Today");now.setNow(); // overwrite the seed, set to this instantint secs = due.timeDifference(now); // due minus now: seconds until due (timeDifferenceDouble returns a double)
due.recycle(); // back-end object — collect when donenow.recycle();Those two recycle() lines aren’t optional — in code that runs repeatedly (an agent, a loop), every uncollected DateTime is one more on the pile.
What about LotusScript and SSJS?
- LotusScript:
NotesDateTimeoffers nearly the sameAdjustDay,TimeDifference,LocalTime, but its memory is automatic — you never recycle by hand, which is where LS is more comfortable than Java in this corner. The site has NotesDateTime and time-zone handling pieces. - SSJS / XPages: it’s the same
lotus.domino.DateTimeunderneath —createDateTimeandtoJavaDateare both there; still a back-end object, still worth collecting. You can also drop straight tojava.util.Date/java.timein SSJS — the same “just use the Java type” instinct as the site’s working with java.util.Vector in XPages piece.