SOLVED

Re: Velocity Script Issue

Go to solution
Ashley_D_Innoce
Level 2

I am using this script to give an expiration date that is one week after an email is sent. I can't figure out how to add the "th, nd, st etc" to the date. For example, August 20th instead of August 20. I am having a hard time figuring out how to do this, any help would be appreciated.

#set($dateInSevenDays = $date.calendar)

$dateInSevenDays.add(10,168)

$date.format('EEEE, MMMM d',$dateInSevenDays.time)

1 ACCEPTED SOLUTION
SanfordWhiteman
Level 10 - Community Moderator

Exactly like so:

#set( $defaultTimeZone = $date.getTimeZone().getTimeZone("America/New_York") )

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

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

#set( $ret = $calNow.setTimeZone($defaultTimeZone) )

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

#set( $ISO8601 = "yyyy-MM-dd'T'HH:mm:ss" )

#set( $ISO8601DateOnly = "yyyy-MM-dd" )

#define( $enUSDayOrdinalIndicators )

1st,2nd,3rd,4th,5th,6th,7th,8th,9th,10th,11th,12th,13th,14th,15th,16th,17th,18th,19th,20th,21st,22nd,23rd,24th,25th,26th,27th,28th,29th,30th,31st

#end

#set( $indicatorList = $enUSDayOrdinalIndicators.toString().trim().split(",?\d+") )

Today with a friendly ordinal indicator is

${date.format(

  "EEEE, MMMM d'${indicatorList[$calNow.get($calConst.DAY_OF_MONTH)]}'",

  $calNow,

  $defaultLocale,

  $defaultTimeZone

)}

Here I'm displaying the current date using the ordinal indicator.  You can see elsewhere in the post how to add a certain number of days, and simply use that approach with the $date.format() shown here.  (Note you always must set a timezone or half the world will have errors.) 

View solution in original post

14 REPLIES 14
Chris_Wilcox
Level 9

Reading the documentation that Sanford Whiteman​ linked, I'm not sure if there's a simple way.

All I can think would be to first calculate what the month would be as 1 value, calculate what the date would be as a second value, then essentially map the values to their "th, nd, st" counterparts with an if statement based on the returned 'date' numeric value, then combine the two in your final

Not super easy, but that looks to me like the only way to do it...

SanfordWhiteman
Level 10 - Community Moderator

You shouldn't need any conditionals, just a map (or, simpler, an array) of days-of-month to ordinal indicator. Then interpolate

    ’${indicators[$calNow.get($calConst.DAY_OF_MONTH)]}’

into the output format.

It should be noted that this is an extremely US-English-flavored variant of such a solution. There's no built-in localized version of this because the permutations are too broad.

Ashley_D_Innoce
Level 2

Thanks for the help Sanford. I'm trying this out to see if I can make it work.

Ashley_D_Innoce
Level 2

Thanks Chris, it's a bit over my head so I was trying to find something simple but it does look like that is the only way that I'll be able to do make it work.

SanfordWhiteman
Level 10 - Community Moderator

Exactly like so:

#set( $defaultTimeZone = $date.getTimeZone().getTimeZone("America/New_York") )

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

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

#set( $ret = $calNow.setTimeZone($defaultTimeZone) )

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

#set( $ISO8601 = "yyyy-MM-dd'T'HH:mm:ss" )

#set( $ISO8601DateOnly = "yyyy-MM-dd" )

#define( $enUSDayOrdinalIndicators )

1st,2nd,3rd,4th,5th,6th,7th,8th,9th,10th,11th,12th,13th,14th,15th,16th,17th,18th,19th,20th,21st,22nd,23rd,24th,25th,26th,27th,28th,29th,30th,31st

#end

#set( $indicatorList = $enUSDayOrdinalIndicators.toString().trim().split(",?\d+") )

Today with a friendly ordinal indicator is

${date.format(

  "EEEE, MMMM d'${indicatorList[$calNow.get($calConst.DAY_OF_MONTH)]}'",

  $calNow,

  $defaultLocale,

  $defaultTimeZone

)}

Here I'm displaying the current date using the ordinal indicator.  You can see elsewhere in the post how to add a certain number of days, and simply use that approach with the $date.format() shown here.  (Note you always must set a timezone or half the world will have errors.) 

Ashley_D_Innoce
Level 2

Thanks so much, this is exactly what I needed!! I added 7 days using code from the article that you had sent and got the code below and it is working great:

#set( $defaultTimeZone = $date.getTimeZone().getTimeZone("America/New_York") )

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

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

#set( $ret = $calNow.setTimeZone($defaultTimeZone) )

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

#set( $ISO8601 = "yyyy-MM-dd'T'HH:mm:ss" )

#set( $ISO8601DateOnly = "yyyy-MM-dd" )

#define( $enUSDayOrdinalIndicators )

1st,2nd,3rd,4th,5th,6th,7th,8th,9th,10th,11th,12th,13th,14th,15th,16th,17th,18th,19th,20th,21st,22nd,23rd,24th,25th,26th,27th,28th,29th,30th,31st

#end

#set( $indicatorList = $enUSDayOrdinalIndicators.toString().trim().split(",?\d+") )

$calNow.add($calConst.DATE,7)

#set( $FRIENDLY_24H_DATETIME_WITH_FRIENDLY_TZ = "EEEE, MMMM d'${indicatorList[$calNow.get($calConst.DAY_OF_MONTH)]}'" )

${date.format(

  "EEEE, MMMM d'${indicatorList[$calNow.get($calConst.DAY_OF_MONTH)]}'",

  $calNow,

  $defaultLocale,

  $defaultTimeZone

)}

Thanks!!!

SanfordWhiteman
Level 10 - Community Moderator

Great!

Please highlight your code though ...

Ashley_D_Innoce
Level 2

#set( $defaultTimeZone = $date.getTimeZone().getTimeZone("America/New_York") )

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

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

#set( $ret = $calNow.setTimeZone($defaultTimeZone) )

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

#set( $ISO8601 = "yyyy-MM-dd'T'HH:mm:ss" )

#set( $ISO8601DateOnly = "yyyy-MM-dd" )

#define( $enUSDayOrdinalIndicators )

1st,2nd,3rd,4th,5th,6th,7th,8th,9th,10th,11th,12th,13th,14th,15th,16th,17th,18th,19th,20th,21st,22nd,23rd,24th,25th,26th,27th,28th,29th,30th,31st

#end

#set( $indicatorList = $enUSDayOrdinalIndicators.toString().trim().split(",?\d+") )

$calNow.add($calConst.DATE,7)

#set( $FRIENDLY_24H_DATETIME_WITH_FRIENDLY_TZ = "EEEE, MMMM d'${indicatorList[$calNow.get($calConst.DAY_OF_MONTH)]}'" )

${date.format(

  "EEEE, MMMM d'${indicatorList[$calNow.get($calConst.DAY_OF_MONTH)]}'",

  $calNow,

  $defaultLocale,

  $defaultTimeZone

)}

Thanks! I didn't know how to do that in the comments!

SanfordWhiteman
Level 10 - Community Moderator

Maybe edit your earlier post to delete the unhighlighted version?

(I'm very sensitive to unhighlighted code, as I literally can't read it.)

Ashley_D_Innoce
Level 2

Understandable, I highlighted my earlier post too

SanfordWhiteman
Level 10 - Community Moderator

I added this snippet to my blog post as well, so it'll be there for future threads.

Chris_Wilcox
Level 9

It's unfortunate because the output of your date format has to fit within the velocity rules, so you can't just modify it to add the "th" yourself. You'd have to split it to first return the month, then return the day. Then basically do:

#if $dayOfMonth = 1

     1st

#elseif $dayOfMonth = 2

     2nd

#elseif $dayOfMonth = 3

     3rd

etc...

Not real fun, but that should (might?) work!

SanfordWhiteman
Level 10 - Community Moderator

Split? Not really. Every Calendar object has properties for all of its components, accessed using the common get() accessor. Once you have a Calendar you have everything else you need.

SanfordWhiteman
Level 10 - Community Moderator

Please read the seminal post on days and times in Velocity: https://blog.teknkl.com/velocity-days-and-weeks/