Velocity - comparing to today's date | Community
Skip to main content
Level 9
December 2, 2018
Solved

Velocity - comparing to today's date

  • December 2, 2018
  • 4 replies
  • 8859 views

Ugh. I know I've asked very similar things to this before, so I feel like I should know better....but I'm having trouble comparing a date to today's date. I've successfully done this in the past with two points in time, but not when one is today's date....and that's tripping me up. Here's what I have so far. $LTD.Expiry_Date__c is a date field that comes in from Salesforce like this: "2015-11-05".

##set time zone and locale settings for date conversions

#set( $TimeZone = $date.getTimeZone().getTimeZone('America/New York') )  

#set( $locale = $date.getLocale() )

##set a calendar object

#set( $calNow = $date.getCalendar() )

#set( $calConst = $field.in($calNow) )

#set ($validCredits = [])

#if( ! $LTD.Expiry_Date__c)

#set ($discard = $validCredits.add($LTD.Compass_ID__c))

#else

##set travel credit expiry date and convert it to a date, then a calendar so we can compare later

#set($TravelCreditExpiryDate = $LTD.Expiry_Date__c)

#set($TravelCreditExpiryDate = $convert.parseDate($TravelCreditExpiryDate,'yyyy-MM-dd',$locale,$TimeZone))

#set($TravelCreditExpiryDate= $date.toCalendar($TravelCreditExpiryDate))

##compare the expiry date of the travel credit to today's date.

##if expiry date is in the future, add to valid credits list.

#if ( $calNow.compareTo($TravelCreditExpiryDate) < 0)

#set ($discard = $validCredits.add($LTD.Compass_ID__c))

#end

#end

Here is the error I get:

Cannot get email content- <div>An error occurred when procesing the email Rendered_Email_Velocity_Error_Area_?! </div> <p>Invocation of method 'compareTo' in class java.util.GregorianCalendar threw exception java.lang.ClassCastException: java.lang.String cannot be cast to java.util.Calendar near</p> <div><pre >?</pre></div>

So either my travel credit isn't being formatted properly, or my current date $calNow isn't. I think the travel credit part is right since I've used that before. So I'm guessing it's today's date. But how can I fix this?

Any ideas?

Thanks in advance.

This post is no longer active and is closed to new replies. Need help? Start a new post to ask your question.
Best answer by SanfordWhiteman

It's not $calNow that's the problem, because if it were null or another non-Calendar value it wouldn't have a compareTo method at all.

The prob is certainly with your custom field remaining a String because it can't be converted. You have a condition in there that suggests it may be empty. In that empty case the Calendar conversion will fail, and in turn the compareTo will error out, but you haven't short-circuited the rest of the processing.

4 replies

SanfordWhiteman
SanfordWhitemanAccepted solution
Level 10
December 2, 2018

It's not $calNow that's the problem, because if it were null or another non-Calendar value it wouldn't have a compareTo method at all.

The prob is certainly with your custom field remaining a String because it can't be converted. You have a condition in there that suggests it may be empty. In that empty case the Calendar conversion will fail, and in turn the compareTo will error out, but you haven't short-circuited the rest of the processing.

Level 9
December 2, 2018

Hmm....I still don't think I get it. Since my code structure is basically this (after changing to isEmpty for logic):

#if( $LTD.Expiry_Date__c.isEmpty())

#set ($discard = $validCredits.add($LTD.Compass_ID__c))

#else

##compare dates

#end

So if my first check is to see whether it's empty.....then the #else section should only be dealing with circumstances where there is a value in there, right? Since the field is a date field in Salesforce I know the output must be either empty, or yyyy-mm-dd. So why would my #else section be failing if it's only applying where the value is there?

To test this further I got the output of that field for the test lead where this is failing (using preview of the email and selecting sample lead). The field value is:

Expiry_Date__c=2015-12-15

What am I missing here.....

SanfordWhiteman
Level 10
December 3, 2018

It's

America/New_York

not

America/New York

(Was on my phone before so I didn't notice this typo.)

Because of the typo, $TimeZone is never set. Thus the later use of $TimeZone in the conversion to Date fails silently, and the variable remains as-is, a String.

SanfordWhiteman
Level 10
December 2, 2018

Also, you're testing for Boolean false, not empty. You should be using isEmpty there.

SanfordWhiteman
Level 10
December 9, 2018

@Phillip Wild​​ please come back to the thread and mark one of my answers as Correct (probably the one noting the typo) for future searches, thanks.

Grant_Booth
Level 9
August 22, 2019

I think I found a simpler way of doing this. Excuse me if I leave out something obvious because I'm new to velocity, but it's working in my tests and seemed conceptually simpler to me. The idea is that you convert each date to integers, and then simply subtract the two.
I'm trying to determine that a voucher is expired by comparing a custom date field from SFDC with today's date.


##get today's date as yyyyMMdd

#set($todayString = $date.get('yyyyMMdd'))

##make an integer variable
#set($todayInt = 0)

##convert the string to an integer
#set($today = $todayInt.parseInt($todayString))

##remove the dashes from the custom date field to make it yyyyMMdd
#set( $ExpDateString = $Voucher.Expiration_Date__c.replace("-","") )

##make an integer variable
#set( $ExpDateInt = 0)

##convert the expiration date to an integer
#set( $ExpDate = $ExpDateInt.parseInt($ExpDateString) )

##subtract the $today integer from the $ExpDate integer
#if( $ExpDate - $today >= 0 )
This voucher has NOT expired yet
#else
This voucher is EXPIRED
#end

SanfordWhiteman
Level 10
August 22, 2019

The difference between 2 unpunctuated ISO 8601 dates *from the same timezone* converted to Integers is indeed a valid way to determine the simple answer to "which one is later."

But date math should be done with proper libraries.

Grant_Booth
Level 9
August 23, 2019

And I agree with that sentiment, it's always preferable, but in our use case a margin of error of +/- 1 day is acceptable, so I'm going to save the headache of troubleshooting date objects and using the proper libraries for another day