Recently, I was trying to change the display of some dates in our application. We’ve found that the simplest way for our international company to display dates is to stick to the dd-MMM-yyyy format since that seems the clearest. No one wonders whether 1/4/16 represent the 4th of January or the 1st of April, because they all see 04-Jan-2016.
This was simplest to fix for all the date fields that use simple inputText controls – just change the convertDateTime pattern.
<xp:inputText value="#{modDoc.RevPerf1Date}" id="revisedPerformanceDateStart"> <xp:dateTimeHelper></xp:dateTimeHelper> <xp:this.converter> <xp:convertDateTime pattern="dd-MMM-yyyy"></xp:convertDateTime> </xp:this.converter> </xp:inputText>
Then, I noticed that in place I wasn’t letting them edit the dates, it wasn’t using that format. We’re not displaying the inputText, but using a label computed from that control to determine what to display. This code may actually hurt your eyes, but it did convert the date into a US-format date, like 01/04/2016.
<xp:label id="label14" style="color:black;"> <xp:this.value><![CDATA[#{javascript:if(modDoc.isNewNote()){ if(modDoc.getItemValueDate("PerfDate1") != null) { var termBegin = @Text(modDoc.getItemValue("PerfDate1")); if(termBegin != ""){ var dt2:NotesDateTime = session.createDateTime(termBegin); var d = new Date(dt2.toJavaDate()); var mon = ("0" + (d.getMonth() + 1)).slice(-2) var td = ("0" + d.getDate()).slice(-2); var yr = d.getFullYear(); mon + "/" + td + "/" + yr } } else { if(sessionScope.POPerformBeginDate != null && sessionScope.POPerformBeginDate != "null" && sessionScope.POPerformBeginDate != ""){ var dt:NotesDateTime = session.createDateTime(sessionScope.POPerformBeginDate); dt.toJavaDate() modDoc.setValue("PerfDate1",dt); var d = new Date(dt.toJavaDate()); var mon = ("0" + (d.getMonth() + 1)).slice(-2) var td = ("0" + d.getDate()).slice(-2); var yr = d.getFullYear(); mon + "/" + td + "/" + yr } } } else { var termBegin = @Text(modDoc.getItemValue("PerfDate1")); if(termBegin != ""){ var dt2:NotesDateTime = session.createDateTime(termBegin); var d = new Date(dt2.toJavaDate()); var mon = ("0" + (d.getMonth() + 1)).slice(-2) var td = ("0" + d.getDate()).slice(-2); var yr = d.getFullYear(); mon + "/" + td + "/" + yr; } }}]]></xp:this.value> </xp:label>
Before we decided to convert to the new format, the ugliness of the code didn’t matter. It was used in one place (printing purchase order modifications) and it worked. Since I didn’t want to invent my own library function for computing the text value of the date in the new format, I searched for a better way to format the dates. I ran across Declan Lynch’s blog entry on using SimpleDateFormat. Unfortunately, that just points in the right direction, rather than providing working code. So, when I tried to implement that for displaying the labels correctly, I just couldn’t get it to work. This frustration led me to the simple solution: use convertDateTime on the labels. Duh!
<xp:label id="performanceDateStartDisplay" style="color:black;"> <xp:this.value><![CDATA[#{javascript:getComponent("performanceDateStart").getValue();}]]></xp:this.value> <xp:this.converter> <xp:convertDateTime pattern="dd-MMM-yyyy"></xp:convertDateTime> </xp:this.converter> </xp:label>
Now, on the printed purchase order modification, I also had changes in dates detailed in the text as a sentence. So, you’d see To Change the Period of performance from 01/04/2016 to 01/08/2106 to 01/11/2016 to 01/15/2016, which was not using our newly minted date format. I couldn’t figure out a way to use the converters within the text without creating several computed labels (each with a rendered formula) to display the text. Then, I remembered my dalliance with SimpleDateFormatter.
So, within that control, I brought in the package and created a function that gets the field value as a Vector using getItemValueDateTimeArray and formats it using my chosen SimpleDateFormat. The text string gets built with four calls to that function and returns our text To Change the Period of performance from 04-Jan-2016 to 08-Jan-2016 to 11-Jan-2016 to 15-Jan-2016
<xp:text id="revisedPerformanceRange"> <xp:this.value><![CDATA[#{javascript:function getFormattedDate ( doc:NotesDocument, fieldName:String ) { importPackage(java.text); var dateFormatter:java.text.SimpleDateFormat = new SimpleDateFormat("dd-MMM-yyyy"); var d:Date = new Date(@Today()); if ( doc.hasItem (fieldName) ) { var valueVector:java.util.Vector = doc.getItemValueDateTimeArray(fieldName); var iterator = valueVector.iterator(); while (iterator.hasNext()) { var itemvalue = iterator.next(); if ((typeof(itemvalue)).endsWith("DateTime")) { d = new Date(itemvalue.toJavaDate()); return dateFormatter.format(d); } } } else { return fieldName + " is not on the document" } } var modNotesDoc:NotesDocument = modDoc.getDocument(); var revisedPerformanceRangeText = "To Change the Period of performance from "; revisedPerformanceRangeText = revisedPerformanceRangeText + getFormattedDate(modNotesDoc,"PerfDate1") + " to "; revisedPerformanceRangeText = revisedPerformanceRangeText + getFormattedDate(modNotesDoc,"PerfDate2") + " to "; revisedPerformanceRangeText = revisedPerformanceRangeText + getFormattedDate(modNotesDoc,"RevPerf1Date") + " to "; revisedPerformanceRangeText = revisedPerformanceRangeText + getFormattedDate(modNotesDoc,"RevPerf2Date"); return revisedPerformanceRangeText;}]]></xp:this.value> </xp:text>
Took some fiddling to figure it out, but gave me exactly what I wanted, two different ways.