Search

What the Quote?

"Doublemint me that."

Steven Rodgers

"To be or not to be...."

William Shakespeare

"Woe is me, I have no bitches... it's a paradox."

Laura Tripcony

« why most box office figures are complete nonsense | Main| yellow all day long »

Quick tip: shorthand date adjustment in LotusScript

Category lotusscript
How many times (this week) have you needed an object representing a past or future date in LotusScript? Pretty standard stuff... you instantiate a NotesDateTime with Now, then call an adjustment method to correct the date:

Dim datTomorrow As New NotesDateTime(Cstr(Now))
Call datTomorrow.AdjustDay(1)


And it's only two lines of code... but there's a way to do it in one by performing the adjustment immediately in the instantiation. LotusScript actually treats each date as a Double. The integer portion is the date (the number of days since 12/30/1899) and the fraction indicates the percentage of the day. Hence, if you convert Now to a Double instead of a String it'll return something like 39665.7083333333 (Cdat that and Cstr it, and you'll get "8/5/2008 5:00:00 PM"). As a result, you can add/substract the number of days you want to adjust, convert the result to a scalar date, and then a String... then pass that into the NotesDateTime constructor and by the time the object is initialized it already has the desired value:

Dim datTomorrow As New NotesDateTime(Cstr(Cdat(Cdbl(Now) + 1))) 'Same time tomorrow
Dim datOneWeekLater As New NotesDateTime(Cstr(Cdat(Cdbl(Now) + 7))) 'Same time next week
Dim datLaterToday As New NotesDateTime(Cstr(Cdat(Cdbl(Now) + (1/24)))) 'Come back in an hour


Enjoy.

Comments

Gravatar Image1 - As an non-American, I am always extremely nervous about combining string and date functions. In theory, converting a date to a string and immediately back again should have no impact (same date rules should always apply), but I guess I don't trust the software & OS enough.

I always use:
dim dateTomorrow as New NotesDateTime("")
dateTomorrow.LsLocalTime = Now()
dateTomorrow.AdjustDay(1)

Gravatar Image2 - I totally agree with Michelle regarding strings, and was going to post a suggestion using Datenumber, but Nick got there first Emoticon

Here's one that I've had to use a few times - getting the last day of the month:

DateNumber( Year( Today() ), Month( Today() ) + 1, 1 ) - 1

Gravatar Image3 - You could also use:

var n = Now
'// Tomorrow
dd = Datenumber( Year( n ), Month( n ), Day( n ) + 1 )
'// In a week
dd = Datenumber( Year( n ), Month( n ), Day( n ) + 7 )
'// One hour from now.
dd = TimeNumber ( Hour( n ) + 1, Minute( n ), Second( n ) )

If you add\ subtract, for example +67 or -103 days\ months\ years it will properly roll the year\ month\ day to correct date, just as with NotesDateTime.adjustDay().

I prefer to use this, because I can then pull out year\ month\ hour, etc. regardless of whether it's US date, Euro date. Anyone see any issues with this method?

Gravatar Image4 - Valid points all... I haven't tested this approach internationally yet. In theory it should still be fine, because Cdbl(Now) is purely numeric - an integer to represent days since 1 Jan 100 AD (my earlier reference to 30 Dec 1899 wasn't entirely accurate... that's the date represented by an integer of 0, but integers can be negative, so LotusScript can store dates all the way back to 100 AD) and a fraction representing the time. Adding 1 to the result, then, returns a number representing a date 1 day later than the original. Intuitively this feels safer to me than using Datenumber, because performing the calculation inside that function can cause it to be passed numbers that aren't valid (according to Designer Help, which is wrong in this case... surprise, surprise):

Datenumber( Year( n ), Month( n ), Day( n ) + 7 )
%REM
On 31 Aug 2008, this would evaluate to Datenumber(2008, 8, 32)
%END REM


As it turns out, LotusScript doesn't care, because it does the incrementing on the fly:

Datenumber( Year( Now ), 15, 37)
%REM
On any day in 2008, this returns 6 Apr 2009:
- Year (Now) returns 2008
- 15 has a Fix of 1, Mod of 3; year becomes 2009
- 37 has a Fix of 1, Mod of 6; month becomes 4, day becomes 6
%END REM


Cdat actually expects to be passed a number in the [daycount].[timefraction] format, though it can also convert any String that can be converted to a date... but in my original example code, the conversion to a String is delayed until after the date conversion, so the result "should" be in the regional date format.

Finally, from the Designer Help description of the NotesDateTime constructor:

"The date and time components are interpreted according to the regional settings of the operating system if possible. For example, if the regional setting for dates is M/d/yy h:mm:ss:tt, then "3/4/05 6:07" means 4 March 2005 at 6:07 AM."

All of this leads me to believe this approach would be locale agnostic... but I wouldn't be at all surprised if it weren't.

Post A Comment

:-D:-o:-p:-x:-(:-):-\:angry::cool::cry::emb::grin::huh::laugh::lips::rolleyes:;-)

Contact Me

Elsewhere

Assorted Linkage


Locations of visitors to this page