Finds the numeric position of the first instance of a character or string within another string.

 integer strpos( string haystack, string needle[, integer offset] )

Finds the numeric position of the first instance of needle in the haystack string.

  • haystack is the string to search through.
  • needle is the substring to match in haystack.
  • offset is the index (starting at 0) of the string to start at.


{strpos('Sailthru and Zephyr are fun and games','and')}   =  9
{strpos('Sailthru and Zephyr are fun and games','and',20)}   =  28

Show a Countdown Clock Based On a User Variable

Use Case: You want to find out how to see how many days ago a person’s birthday was. This requires having a user’s birthday set as a var on the user profile (ex. birthay_date) in the format of YYYY-MM-DD or YYYYMMDD. Eventually, you’d like to use this to target specialized promotions (i.e. if they haven’t purchased an item since their birthday).

Used in conjunction with date(), time(), int(), strpos(), and substr(). Let’s assume the current date is January 1st.


On the User Profile:

zephyr example birthday_date

In the Setup:

{birthdayNoYear = substr(birthday_date,strpos(birthday_date,'-')+1)}
{currentYear = int(date('yyyy'))}
{currentBirthday = currentYear + '-' + birthdayNoYear}
{yearStart = time(currentYear+"-01-01")}
{birthdayTime = (time(currentBirthday) - time("now"))/86400}
{if type((currentYear+1)/4) == "float"}
{leapYear = false}
{leapYear = true}

{if date("MM-dd") == birthdayNoYear}
{birthdayCountdown = 0}

{else if birthdayTime < 1 && birthdayTime > 0}
{birthdayCountdown = 1}

{else if birthdayTime < 0 && leapYear == false}
{birthdayCountdown = int(birthdayTime) + 365}
{birthdayPass= true}

{else if birthdayTime < 0 && leapYear == true}
{birthdayCountdown = int(birthdayTime) + 366}
{birthdayPass = true}

{birthdayCountdown = int(birthdayTime) +1}

In the Code:

{if birthdayCountdown == 0}
Happy birthday!
{else if birthdayCountdown == 1}
Your birthday is tomorrow!
{else if (birthdayCountdown == 364 && leapYear == false) || (birthdayCountdown == 365 && leapYear == true)}
Your birthday was yesterday!
{else if birthdayPass == true}
Your birthday passed this year, but the next one is in {birthdayCountdown} days!
Your birthday is in {birthdayCountdown} days!


Your birthday passed this year, but the next one is in 212 days!

Show/Hide Code Explanation

This script uses substr() to take a sub-string of a custom field, in this instance, the user’s birthday (stored as “birthday_date), to retrieve the day and month of the user’s birth, leaving out the year. Since the birthday value is stored as YYYY-MM-DD, the function takes the value of that custom field, and using the strpos() function (aka string position) finds the numerical position fo the first “-” and adds one, meaning to retrieve everything after the year and dash. For example, if it were stored as “1987-08-01”, subtr() and strpos() in conjunction would return “08-01” as the sub-string value. This value is stored as “birthdayNoYear”.

The date() function is then used to isolate the current year, and int() is used to turn in from a string to an integer, and finally the value is stored in the “currentYear” variable. A “currentBirthday” variable is created, which is the concatenation of the currentYear value plus a hypen plus the user’s birth month and day. For instance, using the same user example and if the current year is 2017, currentBirthday would equate to 2017-08-01. Next, the time() function is used to get the UNIX timestamp for the current start of the year, i.e. the value of “currentYear” plus “01-01”. The UNIX timestamp of the user’s current birthday is also needed, which is retrieved using the time() function on the “currentBirthday” value minus the UNIX timestamp of the current time, and finally dividing that value by 86400, i.e. the total number of seconds in a day. The value is stored as “birthdayTime”, and the value is the number of days left until the user’s birthday.

In order to determine if the upcoming year is a leap year, “1” is added to the current year and then divided by 4. The data type of the value is checked; if it equals “float”, the following year is not a leap year, and a variable called “leapYear” is set to “false”. Otherwise if the data type is not a float, leapYear is set to “true”. Note that leap years are wholly divisible by 4, meaning there’s no decimal place, and a “float” data type is one that contains a decimal place, so any value with a decimal was not wholly divisible, and thus not a leap year.

For the following conditional statement, int() will be used regularly to round to the nearest whole number for reader-friendliness later on. The “if” statement is used to determine if the user’s birthday is today, if it has passed for the year, or if it’s still upcoming for the year. The date() function checks to see if the current month and day is equal to the user’s “birthdayNoYear” value (their birth month and day). If so, it sets a “birthdayCountdown” variable to 0. Next it checks if checks if the value for “birthdayTime” is greater than 1 and less than 0 (which indicates that their birthday is the next day). If it is, it sets the “birthdayCountdown” variable to 1. For instance, for the example user, at 12PM on July 31st, their “birthdayTime” value would be “.5”. Setting it to 1 lets us know later on that the user’s birthday is tomorrow.

The next check is to see if their birthdayTime less than 0 (indicating that their birthday has passed this year). If it is and leapYear is false, then the “birthdayCountdown” variable is set to the value of the integer of their current “birthdayTime” (using the int() function) plus 365. A “birthdayPass” variable is also set to “true”. Next, we check the same criteria, except if “leapYear” evaluates to true, the “birthdayCountdown” variable is the value of the integer of the current “birthdayTime” (again using the int() function) plus 366. “birthdayPass” is likewise set to “true”. If none of these statements were true, then “birthdayCountdown” is set to the integer of the “birthdayTime” value plus 1. Since taking an integer rounds the value down (for example, {int(3.2)} becomes 3), adding one gives us the true number of days left until the user’s birthday.

Finally, in the code, another “if” statement evaluates the value of the “birthdayCountdown” variable. If it’s 0, indicating that there are zero days left until the user’s birthday, display a “Happy birthday!” message. If it’s 1, display a message telling the user their birthday is tomorrow. Next, if it’s not a leap year and there are 364 days left until the user’s birthday or if it is a leap year and there are 365 days left, these both indicate that the user’s birthday was yesterday, and a message saying their birthday was yesterday appears. Next, if the “birthdayPass” value evaluates to true, a message indicates as such and populates the number of days left until their next birthday. Finally, the last scenario is that their birthday hasn’t occurred yet this year. If that’s the case, a message displaying the number of days left until their birthday appears.

Converting Price (with a Decimal) from String to Number

Use Case: You have a field in a data feed you maintain with a price, but price is stored as a string and not a number. You need to do some mathematical operations, so it’s integral that the value is a number. The value has a decimal place. You’ll use map(), int(), strpos(), strrpos(), and substr() to successfully convert this value from a string to a number.


In the Setup:

{content = map(content, lambda c: c + { "newMembershipPrice": int(substr(c.vars.membership_price,0,strpos(c.vars.membership_price,"."))) + int(substr(c.vars.price,strrpos(c.vars.membership_price,".")+1))/100 })}

In the Code:

{if profile.vars.member == true}
 As a member, here are your savings on each item!
{foreach content as c}
 {if length(c.vars.membership_price) > 0}
 ${number(c.price/100 - c.newMembershipPrice,2)} on {c.title}!


As a member, here are your savings on each item!

$2.01 on To Kill a Mockingbird!

$1.84 on Salem’s Lot!

$124.25 on Women’s Leather Jacket!

$24.50 on Men’s Chelsea Boots!


This script uses the map() function to add a new parameter to a content object, in this instead a parameter called “newMembershipPrice,” which will be the numerical value of a price point currently being stored as a string. In order to determine the value for this parameter, the substr() function then takes a substring of the “membership_price” custom variable, using the strpos() function to start at the beginning of the string and finding the numerical string position of the decimal point as the endpoint. For instance, using the first item in the eComm feed as an example, “12.99” would become “12”. In order to convert this to a number, the int() function is used on that substring.

Since int() drops everything after a decimal place, the value of the cents is isolated in a similar fashion. Using substr() to isolate the value, strrpos() looks at the the same “membership_price” custom variable, finding the numerical position of the decimal point, and then adding one, isolating the “cents.” Like the first part of this script, int() is then used to convert this value to a number. In order to re-convert this number into to cents, it is the divided by 100, and going off the same example, would result in “.99”. The two numberical substrings are added together, producing “12.99”, now as a number instead of a string.

In order to leverage this new value in the Code, an “if” statement is used to check for a custom field called “member” (this can be anything of your choosing, however). If “member” equals “true”, then display the savings each user will receive as a member. Next, a foreach statement loops through each piece of content, and an “if” statement checks to see if the item has a “membership_price” field associated. If so (i.e., there’s a discounted price), the item’s price is divided by 100 as to convert it to a dollars/cents format and then the newMembershipPrice value is subtracted. The number() function is then used to convert this value to a standardized format, such as “2.01”.