Redwood Expression Language Functions

Redwood Expression Language (or REL) is a simple expression language that supports basic arithmetic and comparison operators, and some predefined functions. Different scripting contexts have different predefined objects, the functions on this page are available in all contexts. Not all functions are listed here

You can create your own functions for use in REL and RedwoodScript using a library with REL entry points, see Libraries for more information.

The REL can be used to specify:

  • Job definition parameter default values
  • Job definition return code mappings
  • Job chain step preconditions
  • Job chain job preconditions
  • Job chain job parameter mappings
  • Job chain job scheduling parameters
  • Event raiser comments
  • ...

See the scripting contexts topic for more information.

Expressions in REL are designed to be very similar to expressions in RedwoodScript, and the predefined functions are the same.

Operators

Redwood Expression Language provides support for the basic arithmetic operators:

  • + - addition and string concatenation
  • - - subtraction
  • * - multiplication
  • / - division
  • % - integer modulus
  • && - logical AND
  • || - logical OR
  • ! - NOT

It also supports comparison:

  • === - equal to
  • !== - not equal to
  • > - greater than
  • >= - greater than or equal
  • < - less than
  • <= - less than or equal

Escape Character

  • \ - escape character, and thus must be escaped if the literal is meant to be used. This means that a UNC path would be specified as follows:
    \\\\server\\share\\folder\\file

Built in functions

String

Functions for working with Strings.

Function Name Signature Description Example
getSystemId String getSystemId() Get the current system id. =getSystemId() Returns redwood-university_test in this system.
replace */ replace(String search, String replaceBy) Replace search in the given currentString with replaceBy. ='abc def ghi'.replace('def', '123') Returns [abc 123 ghi].
currentString.charAt String currentString.charAt(int pos) Get character at pos in currentString. Note that the position is 0-based, the first character is at position 0. ='Hello World!'.charAt(4) Returns o.
currentString.concat String currentString.concat(String s1, ...) Concatenate strings to currentString. Any number of other objects may be passed as arguments. ='Hello'.concat(' World', '!') Returns Hello World!.
currentString.contains boolean currentString.contains(Object[] args) Return if the string searchFor is contained in currentString. ='Hello'.contains('l') Returns true. ='Hello'.contains('lol') Returns false.
currentString.indexOf int currentString.indexOf(String searchFor, [int startIndex]) Get the first index of the string searchFor in currentString, optionally starting at startIndex (default=0). ='Hello World!'.indexOf('o') Returns 4. ='Hello World!'.indexOf('o', 5) Returns 7.
currentString.lastIndexOf int currentString.lastIndexOf(String searchFor, [int endIndex]) Get the last index of the string searchFor in the currentString, optionally ending at endIndex, defaults to end of string. ='Hello World!'.lastIndexOf('o') Returns 7. ='Hello World!'.lastIndexOf('o', 5) Returns 4.
currentString.length int currentString.length() Get the length of currentString ='HeLLo WorLd!'.length() Returns 12.
currentString.split String[] currentString.split(String separator, int limit) Split currentString into an array using the specified separator. Limit the length of the array to limit elements. ='1 2 3 4 5 6 7 8 9 10'.split(' ', 5) Returns [1, 2, 3, 4, 5].
currentString.startsWith boolean currentString.startsWith(Object[] args) Return if currentString starts with the string searchFor. ='Hello'.startsWith('He') Returns true. ='Hello'.startsWith('llo') Returns false.
currentString.substring String currentString.substring([int startIndex] [, int endIndex]) Get a substring of currentString, starting at startIndex and ending at endIndex - 1, thus returning a string of length endIndex - startIndex. If endIndex is not set, then the rest of the string will be returned. ='Hello World!'.substring(0) Returns Hello World!. ='Hello World!'.substring(6) Returns World!. ='Hello World!'.substring(1, 3) Returns el.
currentString.toLowerCase String currentString.toLowerCase() Convert currentString to lower case. ='HeLLo WorLd!'.toLowerCase() Returns hello world!.
currentString.toString String currentString.toString() Convert currentString to a string. ='123'.toString() Returns 123, it can be used as a string.
currentString.toUpperCase String currentString.toUpperCase() Convert currentString to upper case ='HeLLo WorLd!'.toUpperCase() Returns HELLO WORLD!.
currentString.trim String currentString.trim(Object[] args) Return the currentString with all leading and trailing space removed. ='Hello '.trim() Returns 'Hello'. =' Hello'.trim() Returns 'Hello'. =' Hello '.trim() Returns 'Hello'. ='Hel lo'.trim() Returns 'Hel lo'.

Cast

Change a data type to another.

Function Name Signature Description Example
ToBoolean Object ToBoolean(Object arg) Convert arg to a boolean (true/false) if possible. =ToBoolean('true') Returns true.
ToInteger Object ToInteger(Object arg) Convert arg to an integer if possible. =ToInteger('123') Returns 123.
ToNumber Object ToNumber(Object arg) Convert arg to a number if possible. =ToNumber('123') Returns 123.
ToString Object ToString(Object arg) Convert arg to a string. =ToString(true) Returns true.
ToYN Object ToYN(Object arg) Convert arg to Y for true and N for any other value. =ToYN('true') Returns Y.

Math

Mathematical functions for use with Numbers.

Function Name Signature Description Example
Math.abs BigDecimal Math.abs(BigDecimal x) Calculate the absolute value of x. =Math.abs(-12.12) Returns 12.12.
Math.ceil BigDecimal Math.ceil(BigDecimal x) Calculate the ceiling (least integer greater than) of x. =Math.ceil(-12.12) Returns -12.
Math.floor BigDecimal Math.floor(BigDecimal x) Calculate the floor (greatest integer less than) of x. =Math.floor(-12.12) Returns -13.
Math.getInstance BaseMath Math.getInstance()
Math.round BigDecimal Math.round(BigDecimal x) Round x. If x ends in .5, it will be rounded up. =Math.round(12.49) Returns 12.

StringPrefix

Functions for use with Strings.

Functions in the String package for working with Strings.

Function Name Signature Description Example
String.charAt String String.charAt(String instance, int pos) Get character at pos in instance. =String.charAt('Hello John', 4) Returns o.
String.concat String String.concat(String instance, [String s1,] ...) Concatenate strings to instance. Any number of other objects may be passed as arguments. =String.concat(Time.now('Europe/Paris'), ', Rue Toulouse-Lautrec') Returns 2022/08/01 13:08:36,946 Europe/Paris, Rue Toulouse-Lautrec.
String.contains boolean String.contains(String instance, String searchFor) Return if the string searchFor is contained in instance. =String.contains('Hello', 'l') Returns true. =String.contains('Hello', 'lol') Returns false.
String.getSystemId String String.getSystemId() Get the current system id. =String.getSystemId() Returns redwood-university_test on this system.
String.indexOf int String.indexOf(String instance, String searchFor, [int startIndex]) Get the first index of the string searchFor in instance, optionally starting at startIndex (default=0). =String.indexOf('Hello', 'l', '3') Returns 3.
String.lastIndexOf int String.lastIndexOf(String instance, String searchFor, [int startIndex]) Get the last index of the string searchFor in the instance, optionally starting at startIndex (default=0). =String.lastIndexOf('Hello', 'l', '3') Returns 3.
String.length int String.length(String instance) Get the length of instance =String.length('but I like it dry.') Returns 18.
String.replace String String.replace(String input, String search, String replaceBy) Replace search in the given input with replaceBy. =String.replace('abc def ghi', 'def', '123') Returns [abc 123 ghi].
String.split String[] String.split(String instance, String separator, int limit) Split instance into an array using the specified separator. Limit the length of the array to limit elements. =String.split('Some people like', ' ', '3') Returns [Some, people, like].
String.startsWith boolean String.startsWith(String instance, String searchFor) Return if the instance starts with the string searchFor. =String.startsWith('Hello', 'He') Returns true. =String.startsWith('Hello', 'llo') Returns false.
String.substring String String.substring(String instance, [int startIndex] [, int endIndex]) Get a substring of instance, starting at startIndex and ending at endIndex - 1, thus returning a string of length endIndex - startIndex. If endIndex is not set, then the rest of the string will be returned. =String.substring('like it on ice', 8, 14) Returns on ice.
String.toLowerCase String String.toLowerCase(String instance) Convert instance to lower case. =String.toLowerCase('but I like it dry.') Returns but i like it dry..
String.toString String String.toString(String instance) Convert instance to a string. =String.toString(123) Returns 123 as a String.
String.toUpperCase String String.toUpperCase(String instance) Convert instance to upper case =String.toUpperCase('I like it dry.') Returns I LIKE IT DRY..
String.trim String String.trim(String instance) Return the instance with all leading and trailing space removed. =String.trim('Hello ') Returns 'Hello'. =String.trim(' Hello') Returns 'Hello'. =String.trim(' Hello ') Returns 'Hello'. =String.trim('Hel lo') Returns 'Hel lo'.

Array

Create an array from several elements.

Function Name Signature Description Example
Array.get Object Array.get(Object[] array, int index) Retrieve the element from the array at the specified index. This will throw an exception if array is null or the index is out of bounds (index < 0 or index >= array.length). =Array.get(['Apples', 'Oranges', 'Bananas', 'Lemons'], 0) Returns "Apples".
Array.toDateTimeZoneArray RelObject Array.toDateTimeZoneArray(final Object[] values) Create an array of DateTimeZones. =Array.toDateTimeZoneArray(Time.now(),Time.parse('20220803100236','yyyyMMddhhmmss')) Returns an array with 2 date/times elements.
Array.toNumberArray RelObject Array.toNumberArray(final Object[] values) Create an array of BigDecimals from a group of numbers. =Array.toNumberArray(1, 2, 3, 4) Returns an array with 4 numbers.
Array.toString String Array.toString(Object[] values, String delimiter) Create a String with all elements of the array, separated by delimiter. =Array.toString(['Apples', 'Oranges', 'Bananas', 'Lemons'], ',') Returns "Apples,Oranges,Bananas,Lemons".
Array.toStringAffix String Array.toStringAffix(Object[] values, String delimiter, String prefix, String suffix) Create a String with all elements of the array, separated by delimiter and surrounded by prefix and suffix. =Array.toStringAffix(['Apples', 'Oranges', 'Bananas', 'Lemons'], ',', '[', ']',) Returns "[Apples,Oranges,Bananas,Lemons]".
Array.toStringArray RelObject Array.toStringArray(final Object[] values) Change a group of Strings to a String array. =Array.toStringArray('Apples', 'Oranges', 'Bananas', 'Lemons') Returns an array with 4 fruity elements.
Array.toTimeArray RelObject Array.toTimeArray(final Object[] values) Create an array of BigDecimal from DateTime elements (elements evaluated as epoch time). =Array.toTimeArray(Time.now(),Time.parse('20220803100236','yyyyMMddhhmmss')) Returns an array with 3 epoch time elements.

Cast

Change a data type to another.

Function Name Signature Description Example
Casts.ToBoolean Object Casts.ToBoolean(Object arg) Convert arg to a boolean (true/false) if possible. =ToBoolean('true') Returns true.
Casts.ToInteger Object Casts.ToInteger(Object arg) Convert arg to an integer if possible. =ToInteger('123') Returns 123.
Casts.ToNumber Object Casts.ToNumber(Object arg) Convert arg to a number if possible. =ToNumber('123') Returns 123.
Casts.ToString Object Casts.ToString(Object arg) Convert arg to a string. =ToString(true) Returns true.
Casts.ToYN Object Casts.ToYN(Object arg) Convert arg to Y for true and N for any other value. =ToYN('true') Returns Y.

JobChainParameters

Job chain job names

Job chain job names take the form Step name, job job number. For example: Step 2, job 3 or Data load, job 2. This expression is not zero-based, so the first job is Job 1.

Function Name Signature Description Example
JobChainParameters.getInValueArray Object[] JobChainParameters.getInValueArray(String jobName, String parameterName) Get the value of the Array input parameter parameterName of the job named jobName in the current job chain. =JobChainParameters.getInValueArray('Step 1, Job 1', 'Parameter') Returns the Array In value of the parameter named "Parameter" of the first job (Job 1) in step Step 1.
JobChainParameters.getInValueDate DateTimeZone JobChainParameters.getInValueDate(String jobName, String parameterName) Get the value of the Date input parameter parameterName of the job named jobName in the current job chain. =JobChainParameters.getInValueDate('Step 1, Job 1', 'Parameter') Returns the Date In value of the parameter named "Parameter" of the first job (Job 1) in step Step 1.
JobChainParameters.getInValueNumber BigDecimal JobChainParameters.getInValueNumber(String jobName, String parameterName) Get the value of the Number input parameter parameterName of the job named jobName in the current job chain. =JobChainParameters.getInValueNumber('Step 1, Job 1', 'Parameter') Returns the Number In value of the parameter named "Parameter" of the first job (Job 1) in step Step 1.
JobChainParameters.getInValueString String JobChainParameters.getInValueString(String jobName, String parameterName) Get the value of the String input parameter parameterName of the job named jobName in the current job chain. =JobChainParameters.getInValueString('Step 1, Job 1', 'Parameter') Returns the String In value of the parameter named "Parameter" of the first job (Job 1) in step Step 1.
JobChainParameters.getJobFilePath String JobChainParameters.getJobFilePath(String jobName, String jobFileName) Get the full path of the job file with short name jobFileName on the job named jobName in the current job chain. =JobChainParameters.getJobFilePath('Step 1, Job 1', 'stdout.log') Returns the path to the output file of the first job (Job 1) of the step Step 1.
JobChainParameters.getJobId Long JobChainParameters.getJobId(String jobName) Get the job id of the job named jobName in the current job chain. =JobChainParameters.getJobId('Step 1, Job 1') Returns the job id of the first job (Job 1) of the step Step 1.
JobChainParameters.getJobReturnCode Long JobChainParameters.getJobReturnCode(String jobName) Get the job return code of the job named jobName in the current job chain. =JobChainParameters.getJobReturnCode('Step 2, Job 1') Returns the job return code of the first job (Job 1) of the step Step 2.
JobChainParameters.getJobStatus String JobChainParameters.getJobStatus(String jobName) Get the job status of the job named jobName in the current job chain. =JobChainParameters.getJobStatus('Step 2, Job 1') Returns the job status of the first job (Job 1) of the step Step 2.
JobChainParameters.getOutValueArray Object[] JobChainParameters.getOutValueArray(String jobName, String parameterName) Get the value of the Array output parameter parameterName of the job named jobName in the current job chain. =JobChainParameters.getOutValueArray('Step 1, Job 1', 'Parameter') Returns the Array Out value of the parameter named "Parameter" of the first job (Job 1) in step Step 1.
JobChainParameters.getOutValueDate DateTimeZone JobChainParameters.getOutValueDate(String jobName, String parameterName) Get the value of the Date output parameter parameterName of the job named jobName in the current job chain. =JobChainParameters.getOutValueDate('Step 1, Job 1', 'Parameter') Returns the Date Out value of the parameter named "Parameter" of the first job (Job 1) in step Step 1.
JobChainParameters.getOutValueNumber BigDecimal JobChainParameters.getOutValueNumber(String jobName, String parameterName) Get the value of the Number output parameter parameterName of the job named jobName in the current job chain. =JobChainParameters.getOutValueNumber('Step 1, Job 1', 'Parameter') Returns the Number Out value of the parameter named "Parameter" of the first job (Job 1) in step Step 1.
JobChainParameters.getOutValueString String JobChainParameters.getOutValueString(String jobName, String parameterName) Get the value of the String output parameter parameterName of the job named jobName in the current job chain. When you create a step, add two jobs to it and then delete the first job (Job 1), the second job will become Step 1, Job 1. This means that when you delete a job, you must verify your Relative Job expressions. =JobChainParameters.getOutValueString('Step 1, Job 1', 'Parameter') Returns the String Out value of the parameter named "Parameter" of the first job (Job 1) in step Step 1.
JobChainParameters.jobFileExists boolean JobChainParameters.jobFileExists(String jobName, String jobFileName) Returns if a job file with short name jobFileName on the job named jobName in the current job chain exists and can be read. =JobChainParameters.jobFileExists('Step 1, Job 1', 'stdout.log') Returns true if the output file of the first job (Job 1) of the step Step 1 exists and can be read.

Query

Functions for querying the data model.

Function Name Signature Description Example
Query.getNumber BigDecimal Query.getNumber(String query [, Object [] bindVariables [, String bindTypes]]) Get the first column of the first row of the query query with optional bind variables bindVariables. Bind variable place holders are specified as ? in the query. On some databases it may be required to specify the type of the parameter, as the database will not convert to and from all types. If this is required, then for each parameter specify either a "s", for string, or an "n", for number. If a parameter type is not specified, then it will be passed as a string. =Query.getNumber('select Job.JobId from Job where Job.Description=\'My Job\'') Returns 21 on this system. . =Query.getNumber('select Job.ReturnCode from Job where Job.JobId = ?', [JobChainParameters.getJobId('Step 1,job 1')], 'n') Returns 0 on this system.
Query.getRelativeJob BigDecimal Query.getRelativeJob(String jobName) Get the job id of the job named jobName in the current job chain. Note that job chain job numbers are incremented and never changed. This means that when you create a step, add two jobs to it and then delete the first job, the second job will still remain Step 1, Job 1. Note that this function is 1-based and the job chain editor is zero-based. So Step 1, Job 1 will be displayed as Step 1, Job 0 in the job chain editor. =Query.getRelativeJob('Step 1, Job 1') - get the job id of the first job of the job chain step named Step 1.
Query.getString String Query.getString(String query [, Object [] bindVariables [, String bindTypes]]) Get the first column of the first row of the query query with optional bind variables bindVariables. Bind variable place holders are specified as ? in the query. On some databases it may be required to specify the type of the parameter, as the database will not convert to and from all types. If this is required, then for each parameter specify either a "s", for string, or an "n", for number. If a parameter type is not specified, then it will be passed as a string. =Query.getString('select Job.Description from Job where Job.Queue in (select q.UniqueId from Queue q where q.Name=?) order by Job.JobId DESC', ['System']) Returns My Job on this system. =Query.getString('select Job.Description from Job where Job.JobId=?', [parameters.JOBID]) Returns My Job on this system; note that the job has a JOBID parameter of type Number that holds the actual job id. =Query.getString('select Job.Description from Job where Job.JobId=?', [parameters.JOBID], 'n') Returns My Job on this system; note that the job has a JOBID parameter of type String that holds the actual job id, so in this case casting is required. =Query.getString('select Job.Description from Job where Job.JobId = ?', [Query.getRelativeJob('Step 1,job 1')], 'n') - First Job on this system.

Variable

Functions for querying the System_Variables table.

Function Name Signature Description Example
Variable.getNumber BigDecimal Variable.getNumber(String key) Retrieve a Number from the System_Variables table. =Variable.getNumber('CCOP') Returns 13100 on this system.
Variable.getString String Variable.getString(String key) Retrieve a String value from the System_Variables table. =Variable.getString('2') Returns EMEA on this system.

Table

Functions for querying a table.

You use the $ placeholder to specify the partition of the object you are editing, in job definitions and job chains.

Function Name Signature Description Example
Table.formatRow String Table.formatRow(String table, String key, String rowStart, String columnFormat, String columnSeparator, String rowEnd) Retrieve a row from a table and format it. columnFormat accepts strings as well as the following substitution parameters to specify the position of the elements: {0} - column header {1} - value {2} - columnSeparator (should always be the first) =Table.formatRow('System_Variables', 2, '<row><entry>', '{1}', '</entry><entry>', '</entry></row>') Returns <row><entry>EMEA</entry></row> on this system. =Table.formatRow('$.Countries', 49, '#', '{2}{0}={1}', '|', '#') Returns #Abbreviation=De|Conversion_Rate=1.0|Name=Germany|Translation=Deutschland# . =Table.formatRow('$.Countries', 31, '<row><entry>', '{2}{1}', '</entry><entry>', '</entry></row>') - returns <row><entry>NL</entry><entry>1.0</entry><entry>The Netherlands</entry><entry>Nederland</entry></row>
Table.getColumnNumber BigDecimal Table.getColumnNumber(String table, String key, String column) Retrieve a Number value from a table. =Table.getColumnNumber('System_Variables', 'CCOP') Returns 13100 on this system.
Table.getColumnString String Table.getColumnString(String tableName, String key, String column) Retrieve a String value from a table. =Table.getColumnString('System_Variables', '2', 'SystemValue') Returns EMEA on this system.
Table.getRow String Table.getRow(String table, String key) Retrieve the row of a table, all values are concatenated. =Table.getRow('System_Variables', 2) Returns EMEA on this system.
Table.l String Table.l(Object[] parameters/*String partitionName, String tableName, String key, String columnName*/) Short hand for lookup. See lookup
Table.lookup String Table.lookup(Object[] parameters/*String partitionName, String tableName, String key, String columnName*/) Retrieve the value of a column for a specified row in a table. If no partition is specified, the table is looked for in the GLOBAL partition. =Table.lookup('PROD', 'CustomTable', 'Identifier10', 'ColumnA') Returns the value from the table 'CustomTable' (table is in partition 'PROD') from the row with key 'Identifier10', and from that row the value of 'ColumnA'. =Table.lookup('CustomTable', 'Identifier10', 'ColumnA') Returns the value from the table 'CustomTable' (table is in partition 'GLOBAL', as partitionName is not specified) from the row with key 'Identifier10', and from that row the value of 'ColumnA'.

Constraint

The following methods are used in the ''Simple Constraint Data'' field, the simple constraint type must be set to ''Expression''.

Function Name Signature Description Example
Constraint.listConstraint boolean Constraint.listConstraint(Object[] args /*String title, String list[, boolean valid[, String separator]]*/) Create a drop-down with a list of values. The mandatory first parameter (title) is a title. For this type of constraint only one title is needed. The mandatory second parameter (list) is a comma separated list of values, which will be presented as a drop down list during submit. The optional third parameter (valid) is a boolean expression which says if the entered value is correct. You can use here the value variable for the value, entered by the user. The optional fourth parameter (separator) is a String, which is a regular expression to split the elements in the list. By default it is a comma (,) When you do not supply the third parameter, or it is null, then only values from this list are allowed to be entered. =Constraint.listConstraint('Country', 'de,nl,gt', value !== '') This will show a drop down list with the values de, gt and nl. However you can fill in any non-empty value, e.g. also mx =Constraint.listConstraint('Country', 'de,nl,gt') This will show a drop down list with the values de, gt and nl. You can only choose values from this list. =Constraint.listConstraint('Ciphers or letters', '1,2,3,...|a,b,c,...', null, '\\|') This will show a drop down list with the values 1,2,3,... and a,b,c,.... Note, the commas in the values. Also note, that the bar here is a special character in regular expressions and therefore it needs to be escaped with two slashes. You can only choose values from this list.
Constraint.pairListConstraint boolean Constraint.pairListConstraint(Object[] args /*String titles, String list[, boolean valid]*/) Create a drop-down with a list of values. The mandatory first parameter (titles) is a, comma separated, list of titles. For this type of constraint only two titles are needed. The mandatory second parameter (list) is a comma separated list of value=description pairs, which will be presented as a drop down list during submit. The optional third parameter (valid) is a boolean expression which says if the entered value is correct. You can use here the value variable for the value, entered by the user. When you do not supply the third parameter, or it is null, then only values from this list are allowed to be entered. =Constraint.pairListConstraint('Country, Code', 'de=49,nl=31,gt=502', value !== ''). This will show a drop down list, like CountryCode de49 gt502 nl31 However, you can fill in any non-empty value, e.g. also mx. =Constraint.pairListConstraint('Country Code, Country', 'de=Deutschland,nl=Nederland,gt=Guatemala') . This will show a drop down list, like CountryCode deDeutschland gtGuatemala nlNederland You can only choose one of the the values de, nl, or gt. =Constraint.pairListConstraint('Code|Various symbols', 'C:1,2,3,...|L:a,b,c,...|O:=-*+/', null, '\\|', ':') . This will show a drop down list, like: CodeVarious symbols C1,2,3,... La,b,c,... O=-*+/| Note, the commas and equal sign in the values. Also note, that the bar here is a special character in regular expressions and therefore it needs to be escaped with two slashes. You can only choose values from this list.

ExtendedTime

Advanced time functions.

In previous releases, you used sysdate and systimestamp to retrieve the current date and date-time-offset, respectively. You can use the following REL functions to retrieve the data:

  • sysdate - =Time.format(Time.now(), 'dd-MM-yyyy')
  • systimestamp - =Time.format(Time.now(), 'dd-MM-yyyy hh.mm.ss.SSS a XXXXX')

The time zone used by default is the JVM time zone. The examples use the Europe/Amsterdam time zone by default.

Function Name Signature Description Example
Time.addOpenDays DateTimeZone Time.addOpenDays(Object date, String timeWindow, int days) Adds a number of days to a date according to the given time window.
Time.addOpenDaysFromNow DateTimeZone Time.addOpenDaysFromNow(String timeWindow, int days) Adds a number of days to the current date according to the given time window. =Time.addOpenDaysFromNow('System_Week_WorkDays', 10) Returns the date with 10 added days to the current date according to the time window 'System_Week_WorkDays'.
Time.format String Time.format(Object date, String format) Format the date according to the specified Simple Date Format in the default locale. =Time.format(Time.now(), 'yyyy-MM-dd') Returns the date in the yyyy-MM-dd format, as in 2022-08-14.
Time.formatDuration String Time.formatDuration(BigDecimal duration) Format a duration in milliseconds using the standard format: |1 week, |# weeks, |1 day, |# days, |#|:#|:#|.# =Time.formatDuration(100000) Returns 0:01:40.000.
Time.formatDurationEx String Time.formatDurationEx(BigDecimal duration, String format) Format a duration using a custom format. The format is specified as: |1 week, |# weeks, |1 day, |# days, |#|:#|:#|.#| The first element is used for 1 week. The second element is used for n weeks, where n > 1. The third element is used for 1 day. The fourth element is used for n days, where n > 1. The fifth element is used for hours. The sixth element is used for minutes. The seventh element is used for seconds. The eighth element is used for milliseconds. In all elements but the first and third, # is replaced with the actual number. If an element is empty it is omitted. If the first element is empty, weeks are not printed and days may be greater than 7. If the third element is empty, days are not printed and hours may be greater than 24. If the first and third elements are empty, neither weeks nor days are printed and hours may be greater than 168 (24 * 7). =Time.formatDurationEx(10000000000, '|1 week, |# weeks, |1 day, |# days, |#|:#|:#|.#|') Returns 16 weeks, 3 days, 17:46:40.000. =Time.formatDurationEx(10000000000, '|1 semaine, |# semaines, |1 jour, |# jours, |#|:#|:#|.#|') Returns 16 semaines, 3 jours, 17:46:40.000. =Time.formatDurationEx(10000000000, '|||1 day,|# days, |#|:#|:#|.#|') Returns 115 days, 17:46:40.000. =Time.formatDurationEx(10000000000, '||||# days, |#|:#|:#|.#|') Returns 2777:46:40.000, which is the duration in hours, minutes, seconds, and milliseconds. The first and third elements were empty, causing the second which was empty and the fourth which was # days, to be discarded.
Time.formatLocale String Time.formatLocale(Object date, String format, String localeName) Format the date according to the specified Simple Date Format, in the specified locale. The locale is language[_country[_variant]]. For example 'en' for English, fr_CA for French (Canada), or TH_TH_th (Thai with Thai Digits). =Time.formatLocale(Time.now(), 'yyyy-MM-dd', 'de_DE') Returns the date in the yyyy-MM-dd format, as in 2022-08-14 using the German/Germany locale.
Time.formatNow String Time.formatNow(String format) Format the current date according to the specified Simple Date Format. =Time.formatNow('yyyyMMddhhmmss') Returns 20221117193123.
Time.getUTCMilliseconds BigDecimal Time.getUTCMilliseconds(Object date) Get the number of milliseconds since midnight on January 1 1970 for the specified time. =Time.getUTCMilliseconds(Time.now()) Returns the milliseconds since January 1 1970, for example 1668713483 on 2022/11/17 19:31:23 Europe/Amsterdam.
Time.getUTCMillisecondsNow BigDecimal Time.getUTCMillisecondsNow() Get the number of milliseconds since midnight on January 1 1970 for the current time. =Time.getUTCMillisecondsNow() Returns the milliseconds since January 1 1970, for example 1668713483 on 2022/11/17 19:31:23 Europe/Amsterdam.
Time.isDayInRange boolean Time.isDayInRange(Object date, String dayRange) Is the day of the month of date in the range dayRangeSet. =Time.isDayInRange(Time.now('Europe/Bratislava'), '4-7') Returns true if the day of the month in the time expression is between 4 and 7.
Time.isDayInRangeNow boolean Time.isDayInRangeNow(String dayRange) Is the current day of the month in the range dayRangeSet. =Time.isDayInRangeNow('4-7') Returns true if the current day of the month is between 4 and 7.
Time.isDayOfWeekInSet boolean Time.isDayOfWeekInSet(Object date, String weekSet) Is the day of the week of date in the set weekSet. =Time.isDayOfWeekInSet(Time.now('Europe/Paris'), '_X_X_X_') Returns true if the day falls on a Monday, Wednesday, or Friday.
Time.isDayOfWeekInSetNow boolean Time.isDayOfWeekInSetNow(String weekSet) Is the current day of the week in weekSet. =Time.isDayOfWeekInSetNow('_X_X_X_') Returns true if the current day is Monday, Wednesday, or Friday.
Time.isLastDayInMonth boolean Time.isLastDayInMonth(Object date) Is the date specified the last day of that month? =Time.isLastDayInMonth(Time.expressionNow('add 2 days')) - return true if the current day is two days before the end of the month.
Time.isLastDayInMonthNow boolean Time.isLastDayInMonthNow() Is it currently the last day of the month? =Time.isLastDayInMonthNow() Returns true if the current day is the last day of the month.
Time.isMonthInSet boolean Time.isMonthInSet(Object date, String monthRange) Is the month of the specified date in the range monthRange? =Time.isMonthInSet(Time.expression(Time.now(), 'add 1 month'), '_X_X_X_X_X_X') - return true if the current month has an uneven number.
Time.isMonthInSetNow boolean Time.isMonthInSetNow(String monthSet) Is the month of the current date in the set monthSet? =Time.isMonthInSetNow('_X_X_X_X_X_X') - return true if the current month has an even number.
Time.nextTimeWindowClosing DateTimeZone Time.nextTimeWindowClosing(Object date, String timeWindow) Next closing of timeWindow after the specified date. Note that you can only call this function on currently open time windows. =Time.nextTimeWindowClosing(Time.parse('20221117193123', 'yyyyMMddhhmmss'), 'GLOBAL.System_Week_Thu') Returns 2022/11/18 00:00:00,000 Europe/Amsterdam.
Time.nextTimeWindowClosingNow DateTimeZone Time.nextTimeWindowClosingNow(String timeWindow) Next closing of timeWindow after now. =Time.nextTimeWindowClosingNow('GLOBAL.System_Week_Thu') Returns 2022/11/18 00:00:00,000 Europe/Amsterdam.
Time.nextTimeWindowOpening DateTimeZone Time.nextTimeWindowOpening(Object date, String timeWindow) Next opening of timeWindow after the specified date. In a JobDefinition or JobChain, you can specify $ as a partition in your REL expression; this will be replaced by the partition of the JobDefinition or JobChain. This is especially helpful in combination with the Promotion module, as long as you keep the objects referencing themselves in one partition. Ensure the time window exists in the partition before you use the JobDefinition or JobChain. =Time.nextTimeWindowOpening(Time.parse('20221117193123', 'yyyyMMddhhmmss'), 'GLOBAL.System_Week_Thursday') Returns 2022/11/24 00:00:00,000 Europe/Amsterdam .
Time.nextTimeWindowOpeningNow DateTimeZone Time.nextTimeWindowOpeningNow(String timeWindow) Next opening of timeWindow after now. In a JobDefinition or JobChain, you can specify $ as a partition in your REL expression; this will be replaced by the partition of the definition or chain. This is especially helpful in combination with the Promotion module, as long as you keep the objects referencing themselves in one partition. Ensure the time window exists in the partition before you use the JobDefinition or JobChain. =Time.nextTimeWindowOpeningNow('GLOBAL.System_Week_Thursday') Returns 2022/11/24 00:00:00,000 Europe/Amsterdam. =Time.nextTimeWindowOpeningNow('$.SomeTimeWindow') Returns 2022/11/17 00:00:00,000 Europe/Amsterdam.
Time.parse DateTimeZone Time.parse(Object string, String format) Parse the string into a date according to the specified Simple Date Format. =Time.parse('20221117193123', 'yyyyMMddhhmmss') Returns 2022/11/17 19:31:23 Europe/Amsterdam.

ExtendedRange

Extended Range function with notification.

Function Name Signature Description Example
Range.inRangeWarning boolean Range.inRangeWarning(int candidate, String trueRange, String warningRange, int severity, String message) Return true if candidate is in the range specified by trueRange. Return true, but log a warning operator message if candidate is in the range warningRange. The operator message is specified by the message and severity parameters. =Range.inRangeWarning(52, '10-50', '51-100', 50, 'Warning: range exceeded') Returns true and creates an operator message.

Sap

Ranges are sent as a long string in the form [<sign><option><low><high>]+ where

  • <sign> is a single character I or E
  • <option> a select option, e.g. EQ, BT
  • <low> the low value of the range
  • <high> the high value of the range

All fields are always sent, regardless of the value of the <option>. If the value is shorter than the length of the field, it is padded with blanks.

Such ranges are known to be sent by Closing Cockpit.

Function Name Signature Description Example
SAP.convertJobParameterRangesToExpression String SAP.convertJobParameterRangesToExpression(String jobName, String parameterName, int fieldLength) Get the value of the String output parameter parameterName of the job named jobName in the current job chain. Convert ranges to a selopt expression. =SAP.convertJobParameterRangesToExpression('Step 1, Job 1', 'Parameter', 32) Returns a select option.
SAP.convertRangesToExpression String SAP.convertRangesToExpression(String rangesString, int fieldLength) Convert ranges to a selopt expression. =SAP.convertRangesToExpression('IBTAAZZ', 2) Returns AA - ZZ.

Logic

Function Name Signature Description Example
Logic.case String Logic.case(String expression[, String match1, String result1,] ... [ String matchN, String resultN] [, String resultNoMatch] ) Run and map an expression. Execute the expression, if the result matches matchN return resultN, otherwise return resultNoMatch. =Logic.case(getSystemId(), 'redwood-university_test', 'test', 'redwood-university_prod', 'prod', 'Not Matched') Returns test on this system.
Logic.if String Logic.if(String expression, String trueValue, String falseValue) Run an expression and return trueValue if it is true, otherwise falseValue. This function does not support else, if you want to use else, use ''Logic.case'' instead. =Logic.if(getSystemId() === 'redwood-university_test', 'test', 'Not Matched') Returns test on this system.
Logic.nvl String Logic.nvl(String o, String nullValue) If the first argument is not null, return it, otherwise return the second argument. =Logic.nvl(getSystemId(), 'Not null') Returns redwood-university_test on this system.

ExtendedRepository

Functions for accessing the data model.

Function Name Signature Description Example
Repository.getParentJobId String Repository.getParentJobId(String jobId) Get the parent job id of the specified job id, or null if the job id is null or its parent is null. =Repository.getParentJobId('27') Returns 21 on this system.
Repository.getSystemId String Repository.getSystemId() Get the current system id. =Repository.getSystemId() Returns redwood-university_test on this system.
Repository.queryCSV int Repository.queryCSV(String query [, Object [] bindVariables]) Produce CSV output on stdout for the query query with optional bind variables bindVariables. Bind variable place holders are specified as ? in the query. =Repository.queryCSV('select Job.Description from Job where Job.JobId = 21') Returns My Job on this system.
Repository.queryHTMLTable int Repository.queryHTMLTable(String query [, Object [] bindVariables]) Produce HTML output on stdout for the query query with optional bind variables bindVariables. Bind variable place holders are specified as ? in the query. =Repository.queryHTMLTable('select Job.Description from Job where Job.JobId = 21') Returns My Job on this system.

PLSQL

Function Name Signature Description Example
PLSQL.booleanExpr Boolean PLSQL.booleanExpr(Object[] args /*) Evaluate a boolean PL/SQL expression in an Oracle database. The first parameter is string with connection info, in the form [user=<user>] [endpoint=<endpoint>] [cache=[<number>[s|m|h|d|w|M|y]\]], where <user> is the database user to connect with and <endpoint> the name of the database object for the database to connect to. When the cache keyword is used, caching of the results is used. The optional time specification is a number in seconds (default or when suffixed by 's'), minutes ('m'), hours ('h'), days ('d'), weeks ('w'), months ('M') or years ('y'). This time specification means that the cached result is not allowed to be older than specified. Thus the maximum cache age is not defined by the setter, but by the getter of the cache result! The second parameter is the boolean PL/SQL expression as a String. The rest of the parameters are optional bind variables. Bind variable place holders are specified as ? in the expression. =PLSQL.booleanExpr('user=scott endpoint=xe', '? > 0', 1) Returns true. Do not use a cached value of the result. =PLSQL.booleanExpr('user=scott endpoint=xe cache=0', '? > 0', 1) Returns true. Do not use a cached value of the result, but do cache the result for a next time. =PLSQL.booleanExpr('user=scott endpoint=xe cache=60', '? > 0', 1) Returns true. Do use a cached value of the result, but only when the cached value is not older than 60 seconds. =PLSQL.booleanExpr('user=scott endpoint=xe cache=1m', '? > 0', 1) Returns true. Do use a cached value of the result, but only when the cached value is not older than 1 minute. =PLSQL.booleanExpr('user=scott endpoint=xe cache', '? > 0', 1) Returns true. Do use a cached value of the result, but only when the cached value is not older than the number of seconds as specified in the registry key /configuration/REL/PLSQL/DefaultMaxCacheAge. =PLSQL.booleanExpr('user=scott cache=1m', '? > ?', parameters.param1, parameters.param2) - compares two numbers defined in parameters param1 and param2. Note that this uses the System_Oracle endpoint (default)
PLSQL.dateExpr DateTimeZone PLSQL.dateExpr(Object[] args /*) See booleanExpr
PLSQL.numberExpr BigDecimal PLSQL.numberExpr(Object[] args /*) See booleanExpr
PLSQL.stringExpr String PLSQL.stringExpr(Object[] args /*) See booleanExpr

JDBC

Function Name Signature Description Example
JDBC.clearCache String JDBC.clearCache() Clears the result cache. It always returns an empty String.
JDBC.constraint boolean JDBC.constraint(Object[] args /*) Create a constraint, with LOV support, based on a query on database tables/views. The first parameter is string with connection info, in the form [user=<user>] [endpoint=<endpoint>] [cache=[<number>[s|m|h|d|w|M|y]\]], where <user> is the database user to connect with and <endpoint> the name of the database object for the database to connect to. When the cache keyword is used, caching of the results is used. The optional time specification is a number in seconds (default or when suffixed by 's'), minutes ('m'), hours ('h'), days ('d'), weeks ('w'), months ('M') or years ('y'). This time specification means that the cached result is not allowed to be older than specified. Thus the maximum cache age is not defined by the setter, but by the getter of the cache result! The second parameter is the query as a String. The rest of the parameters are optional bind variables. Bind variable place holders are specified as ? in the expression. =JDBC.constraint('user=scott endpoint=xe', 'select name "City", state "State/province" from cities where country = ?', parameters.Country) - Implements a constraint, showing two columns. The first column has the title "City", the second column has the title "State/province". The data in the drop down list is a list of cities from the country as defined in the parameter Country, where the data comes from the database table cities. The actual value that is chosen is the city. The other column is only informational.
JDBC.query Object JDBC.query(Object[] args /*) Execute a database query and return the first column from the first row. The first parameter is string with connection info, in the form [user=<user>] [endpoint=<endpoint>] [cache=[<number>[s|m|h|d|w|M|y]\]], where <user> is the database user to connect with and <endpoint> the name of the database object for the database to connect to. When the cache keyword is used, caching of the results is used. The optional time specification is a number in seconds (default or when suffixed by 's'), minutes ('m'), hours ('h'), days ('d'), weeks ('w'), months ('M') or years ('y'). This time specification means that the cached result is not allowed to be older than specified. Thus the maximum cache age is not defined by the setter, but by the getter of the cache result! The second parameter is the query as a String. The rest of the parameters are optional bind variables. Bind variable place holders are specified as ? in the query. =JDBC.query('user=scott endpoint=xe', 'select global_name from global_name where rownum <= ?', 1) - returns the global name of the Oracle database. Do not use a cached value of the result. =JDBC.query('user=scott endpoint=xe cache=0', 'select global_name from global_name where rownum <= ?', 1) - returns the global name of the Oracle database. Do not use a cached value of the result, but do cache the result for a next time. =JDBC.query('user=scott endpoint=xe cache=60', 'select global_name from global_name where rownum <= ?', 1) Returns the global name of the Oracle database. Do use a cached value of the result, but only when the cached value is not older than 60 seconds. =JDBC.query('user=scott endpoint=xe cache=1m', 'select global_name from global_name where rownum <= ?', 1) - returns the global name of the Oracle database. Do use a cached value of the result, but only when the cached value is not older than 1 minute. =JDBC.query('user=scott endpoint=xe cache', 'select global_name from global_name where rownum <= ?', 1) Returns the global name of the Oracle database. Do use a cached value of the result, but only when the cached value is not older than the number of seconds as specified in the registry key /configuration/REL/JDBC/DefaultMaxCacheAge.

UserMessage

Function Name Signature Description Example
UserMessage.renderHistoryAsHTML String UserMessage.renderHistoryAsHTML(String userMessageId, String cssPrefix) Render an HTML table with the history of a user message. =UserMessage.renderHistoryAsHTML(parameters.UserMessage_UniqueId, 'aCssPrefix').
UserMessage.renderHistoryAsText String UserMessage.renderHistoryAsText(String userMessageId) Render a Text table with the history of a user message. =UserMessage.renderHistoryAsText(parameters.UserMessage_UniqueId).

Credential

Function Name Signature Description Example
Credential.getProtectedPassword String Credential.getProtectedPassword(String endpoint, String realUser) Obtain encrypted credential for the default partition and login protocol, if present and accessible. =Credential.getProtectedPassword('host', 'root').
Credential.getProtectedPasswordByProtocolRealUser String Credential.getProtectedPasswordByProtocolRealUser(String partition, String credentialProtocol, String endpoint, String realUser) Obtain encrypted credential if present and accessible. =Credential.getProtectedPasswordByProtocolRealUser('GLOBAL', 'login', 'host', 'root') or. =Credential.getProtectedPasswordByProtocolRealUser('$', 'login', 'host', 'root') where '$' represents the partition of the Process Definition the parameter is in.
Credential.getProtectedPasswordByProtocolVirtualUser String Credential.getProtectedPasswordByProtocolVirtualUser(String partition, String credentialProtocol, String endpoint, String virtualUser) Obtain encrypted credential if present and accessible. =Credential.getProtectedPasswordByProtocolVirtualUser('GLOBAL', 'login', 'host', 'appowner').

Loop

Function Name Signature Description Example
Loop.formatBigDecimal String Loop.formatBigDecimal(String columnName, String outputFormat) Retrieve and format a value for the named table column, using the specified formatting. The column may be of any type, but needs to be parseable as a BigDecimal. =Loop.formatBigDecimal('price', '$#.00') - retrieves the value of the column named price as a BigDecimal and formats it as specified and returns it as a String.
Loop.formatDate String Loop.formatDate(String columnName, String dateFormat) Retrieve and format a value for the named table column, using the specified formatting. The column may be of any type, but needs to be parseable as a DateTimeZone. =Loop.formatDate('date', 'dd-MM-yyyy') - retrieves the value of the date column named date, formats it using dd-MM-yyyy and returns it as a String.
Loop.getBigDecimal BigDecimal Loop.getBigDecimal(String columnName) Retrieve a BigDecimal value for the named table column. =Loop.getBigDecimal('price') Returns the value of the column named price as a BigDecimal.
Loop.getDate DateTimeZone Loop.getDate(String columnName) Retrieve a DateTimeZone value for the named table column. =Loop.getString('date') Returns the value of the column named date as a DateTimeZone.
Loop.getString String Loop.getString(String columnName) Retrieve a String value for the named table column. =Loop.getString('symbol') Returns the value of the column named symbol as a String.
Loop.reformatStringAsBigDecimal String Loop.reformatStringAsBigDecimal(String columnName, String inputFormat, String outputFormat) Retrieve the string value of a column, parse it using the input format and format it using the output format. The column is assumed to be a number in a string column. =Loop.reformatStringAsBigDecimal('price', '$#.00', '#,00') - retrieves the value of the column named price parses it using $#.00 and formats it using #,00 and returns it as a String.
Loop.reformatStringAsDate String Loop.reformatStringAsDate(String columnName, String inputFormat, String outputFormat) Retrieve the string value of a column, parse it using the input format and format it using the output format. The column is assumed to be a date in a string column. =Loop.reformatStringAsDate('date', 'yyyy-MM-dd', 'dd-MM-yyyy') - retrieves the value of the string column named date, parses it using yyyy-MM-dd, formats it using dd-MMM-yyyy, and returns it as a String.

Event

Function Name Signature Description Example
Event.isEventRaised boolean Event.isEventRaised(String name) Get the status of an event. =Event.isEventRaised('MyPartition.MyEvent') Returns true on this system as the event is currently raised.

Time

Time expressions

Time expressions are a sequence of operations, applied in order to a time (generally now, but may be a specified date). They may be:

  • set <specifier> <value> - set <specifier> to <value>
  • add <value> <specifier> - add <value> to <specifier> (This may propagate)
  • subtract <value> <specifier> - subtract <value> from <specifier> (This may propagate)
  • truncate <specifier> - truncate at <specifier> (This will zero everything below <specifier>).

The <value> is always a number:

  • The days of the week start at 1 for Sunday.
  • The days of the year start at 1 for 1 January.

The <specifier> is one of:

  • add/subtract: second, minute, hour, day, week, month, year
  • truncate: second, minute, hour, day, month
  • set: second, minute, hour, day, day_of_week, day_of_year, week_of_month, month

Plurals with an additional 's' are accepted (eg. days, weeks, ...). The day is always the day of the month. English names are accepted for day of week (day_of_week) and month; for example set day_of_week Monday or set month January, three letter abbreviations are accepted as well.

Example time expressions:

  • add 1 minute
  • add 3 seconds
  • set hour 1
  • set day_of_week Mon
  • truncate day
  • subtract 2 days

The time zone used by default is the JVM time zone. The examples use the Europe/Amsterdam time zone by default.

Function Name Signature Description Example
Time.expression DateTimeZone Time.expression(Object date, String expression) Apply time expression expression to the date specified. =Time.expression(Time.now('Europe/Amsterdam'), 'add 1 day') Returns tomorrow, Europe/Amsterdam time.
Time.expressionNow DateTimeZone Time.expressionNow(String expression) Apply time expression expression to the current time. =Time.expressionNow('truncate day') Returns 2022/08/01 00:00:00,000 Europe/Amsterdam.
Time.isTimeWindowOpen boolean Time.isTimeWindowOpen(Object date, String timeWindow) Return true if the time window timeWindow is open on the specified date, false otherwise. In a JobDefinition or JobChain, you can specify $ as a partition in your REL expression; this will be replaced by the partition of the JobDefinition or JobChain. This is especially helpful in combination with the Promotion module, as long as you keep the objects referencing themselves in one partition. Ensure the time window exists in the partition before you use the job definition or job chain. =Time.isTimeWindowOpen(Time.expressionNow('subtract 1 day'), 'GLOBAL.System_Week_Monday') - boolean function which returns true if today is Tuesday . =Time.isTimeWindowOpen(Time.expressionNow('truncate day add 3 hours add 25 minutes'), '$.SomeTimeWindow') - this example illustrates the use of the $ identifier for the partition.
Time.isTimeWindowOpenNow boolean Time.isTimeWindowOpenNow(String timeWindow) Return true if the time window timeWindow is open now, false otherwise. =Time.isTimeWindowOpenNow('GLOBAL.System_Week_Monday') - boolean functions which returns true if today is Monday.
Time.now DateTimeZone Time.now([String timeZoneName]) Return the time in the context time zone (generally the time zone of the job). This can be optionally overridden by specifying the Olson name of a time zone as timeZoneName. =Time.now() Returns the current time with time zone.

Range

Functions for working with sets and ranges.

Sets

Set is written as "XXXXXXX" where X is either '_' or a letter and the first X represents 0 (or Sunday for days of the week, or January for months). Any letter is in the set, and '_' is not in the set.

Example sets:

Set X's English
First month of the quarter X__X__X__X__ J__A__M__O__
Last month of the quarter __X__X__X__X __M__J__S__D
Not last month of the quarter XX_XX_XX_XX_ JF_AM_JA_ON_
Monday, Wednesday, Friday _X_X_X_ _M_W_F_
Saturday, Sunday X_____X S_____S

Ranges

Ranges are made up of comma separated sections, each of which is a number (eg. 1) or a range of numbers (eg. 4-7). All numbers specified are in the range, other numbers are not.

Function Name Signature Description Example
Range.inRange boolean Range.inRange(int candidate, String trueRange) Return true if candidate is in the range specified by trueRange. The following example uses the Time.format function. This boolean function checks if the current day of the month is between 1 and 7. =Range.inRange(Time.format(Time.now('Europe/Berlin'), 'd'), '1-7').
Range.inSet boolean Range.inSet(int candidate, String trueSet) Return true if candidate is in the set specified by trueRange. The following example uses the Time.format function. This boolean function checks if the current month is the first month of a quarter. =Range.inSet(Time.format(Time.now('Europe/Berlin'), 'M'), ' X__X__X__X__'). Note the leading space in trueRange to convert from the 1-based month to the 0-based trueRange.