<@script name="Basic"> Contains macros for handling basic data types, based on the XGL 2.0 specification. (c) SAP AG 2003-2006. All rights reserved. //////////////////////////////////////////////////////////////////// // STRING FUNCTIONS <@func name="ASC" also="CHR" group="I. String Functions"> Converts a character to its ASCII/unicode code The character to convert The code value function ASC(char) { if(!char) char=''; return char.charCodeAt(0); } <@func name="AT" also="MID"> Returns the character at the specified position A string Zero-based index of the desired character The character at position %1 in %0 function AT(s,pos) { if (typeof s != 'string') s=(s||'')+''; return s.charAt(pos); } <@func name="BEGINS"> Tests whether a given string begins with the specified pattern String to search The search pattern ~true if %0 begins with %1; ~false otherwise function BEGINS(str, pat) { if (!str || !pat) return false; str = (str+'').toUpperCase(); pat = (pat+'').toUpperCase(); return str.indexOf(pat) == 0; } <@func name="CAPITAL" also="LOWER UPPER CAPITALW"> Converts the string to a capitalized case A string The converted string function CAPITAL(s) { if (typeof s != 'string') s=(s||'')+''; return s.charAt(0).toUpperCase()+s.substring(1).toLowerCase(); } <@func name="CAPITALW" also="CAPITAL"> Capitalizes each word in a given string A string of words The converted string function CAPITALW(s) { if (typeof s != 'string') s=(s||'')+''; for (var i=0, A=(s || '').split(/[\s\_]+/), len=A.length; i Converts an ASCII/unicode code to a character The code to convert The character value function CHR(code) { return String.fromCharCode(code); } <@func name="COMPACT" also="TRIM"> Replaces consecutive whitespaces inside the string with a single space, and trims the whitespace around the string A string The compacted string function COMPACT(s) { if (typeof s != 'string') s=(s||'')+''; return s.replace(/^\s+|\s+$/g,'').replace(/\s+/g,' '); } <@func name="CONTAINS"> Tests whether a given string contains the specified pattern String to search The search pattern ~true if %0 contains %1; ~false otherwise function CONTAINS(str, pat) { if (!str || !pat) return false; str = (str+'').toUpperCase(); pat = (pat+'').toUpperCase(); return str.indexOf(pat) >= 0; } <@func name="ENDS"> Tests whether a given string ends with the specified pattern String to search The search pattern ~true if %0 ends with %1; ~false otherwise function ENDS(str, pat) { if (!str || !pat) return false; str = (str+'').toUpperCase(); pat = (pat+'').toUpperCase(); return str.lastIndexOf(pat) == (str.length-pat.length); } <@func name="FILL" also="LPAD RPAD"> Fills a string of a specified length with the given character(s) The character(s) sequence to use for filling The desired string length, after padding The filled string function FILL(s,len) { if (typeof s != 'string') s=(s||'')+''; if (!s) s = ' '; while (s.length < len) s += s; return s.slice(0, len); } <@func name="LEFT" also="MID RIGHT"> Returns the substring beginning on the left and having specified length A string The length of the desired substring The section of %0 between 0 (inclusive) and %1 (exclusive) function LEFT(s,len) { if (typeof s != 'string') s=(s||'')+''; return s.slice(0, len||1); } <@func name="LEN"> Returns the length of a specified string The string to test The requested string length function LEN(s) { if (typeof s != 'string') s=(s||'')+''; return s.length; } <@func name="LIKE"> Tests whether a pattern exists in a given string String to search The search pattern ~true if %1 pattern exists in %0; ~false otherwise function LIKE(str, re) { if (typeof re == 'string'){ re = new RegExp(re.replace(LIKE.re,LIKE.fn), 'im'); } return re.test(str||''); } LIKE.re = /(^(\*|\?|\.)((?=(\*|\?))))|(\.($|(?=[^\*\?\\])))|(([^\.\\])((?=(\*|\?))))/g; LIKE.fn = function($0,$1,$2){ return ($2=='*' || $2=='?') ? '.'+$2+'.' : ($0=='.' || $1=='.') ? '\\.' : $0+'.';} <@func name="LOWER" also="UPPER CAPITAL"> Converts the string to lower case A string The converted string function LOWER(s) { if (typeof s != 'string') s=(s||'')+''; return s.toLowerCase(); } <@func name="LPAD" also="RPAD FILL"> Pads the string on the left with a given character(s) until reaching a specified length A string The desired string length, after padding The character(s) sequence to use for padding The padded string function LPAD(s,len,pad) { if (typeof s != 'string') s=(s||'')+''; if (!pad) pad = ' '; while (pad.length Removes the whitespace on the left of the string A string The trimmed string function LTRIM(s) { if (typeof s != 'string') s=(s||'')+''; return s.replace(/^\s+/,''); } <@func name="MID" also="LEFT RIGHT"> Returns the substring beginning at the specified position and having specified length A string The starting position of the desired substring The length of the desired substring The section of %0 between %1 (inclusive) and %1+%2 (exclusive) If %2 is zero or negative, an empty string is returned If %2 is omitted, extraction continues to the end of %0 function MID(s,start,len) { if (typeof s != 'string') s=(s||'')+''; return s.substr(start,len); } <@func name="PREF" also="LEFT"> Returns the string prefix in upper case A string The length of the desired prefix The section of %0, converted to upper case, between 0 (inclusive) and %1 (exclusive) function PREF(s,len) { if (typeof s != 'string') s=(s||'')+''; return s.slice(0, len||1).toUpperCase(); } <@func name="REPLACE"> Replaces all occurences of a substring with a specified replacement substring A string The substring to replace The replacing string The given string after replacement function REPLACE(str, sub, rep) { if (!str) return ''; if (!sub) return str; if (!rep) rep = ''; var msk = (sub+'').replace(/([^\s\w])/g,'\\$1'); var reg = new RegExp(msk,'g'); return (str+'').replace(reg, rep+''); } <@func name="RIGHT" also="MID LEFT"> Returns the substring ending on the right and having specified length A string The length of the desired substring The section of %0 between %0.length-%1 (inclusive) and %0.length (exclusive) function RIGHT(s,len) { if (typeof s != 'string') s=(s||'')+''; return s.slice(-(len||1)); } <@func name="RPAD" also="LPAD FILL"> Pads the string on the right with a given character(s) until reaching a specified length A string The desired string length, after padding The character(s) sequence to use for padding The padded string function RPAD(s,len,pad) { if (typeof s != 'string') s=(s||'')+''; if (!pad) pad = ' '; while (pad.length Removes the whitespace on the right of the string A string The trimmed string function RTRIM(s) { if (typeof s != 'string') s=(s||'')+''; return s.replace(/\s+$/,''); } <@func name="TRIM" also="LTRIM RTRIM COMPACT"> Removes the whitespace on both sides of the string A string The trimmed string function TRIM(s) { if (typeof s != 'string') s=(s||'')+''; return s.replace(/^\s+|\s+$/g,''); } <@func name="UPPER" also="LOWER CAPITAL"> Converts the string to upper case A string The converted string function UPPER(s) { if (typeof s != 'string') s=(s||'')+''; return s.toUpperCase(); } <@func name="ZPAD" also="LPAD RPAD"> Pads the string on the left with zeroes until reaching a specified length, but only if the string contains an integer value A string The desired string length, after zero-padding The zero-padded string function ZPAD(s,len) { len = POS(len); if (!s || typeof s != 'string' || len == 0) return s; return (s.search(/\D/) < 0) ? LPAD(s, len, '000000') : s; } //////////////////////////////////////////////////////////////////// // NUMERIC FUNCTIONS Math.MAX = +Number.MAX_VALUE; Math.MIN = -Number.MAX_VALUE; <@func name="ABS" also="SIGN" group="II. Numeric Functions"> Returns the absolute value of a given number A number Returns -%0 if %0<0, otherwise, returns %0 ABS = Math.abs; <@func name="CEIL" also="FLOOR ROUND"> Truncates a number upward A number The truncation factor The number %0, truncated to the nearset multiple of %1 greater than or equal to %0 function CEIL(num, factor) { if (!factor || factor==1) return Math.ceil(num); if (Math.abs(factor) < 1) { factor = Math.round(1/factor); return Math.ceil(num*factor)/factor; } else { return Math.ceil(num/factor)*factor; } } <@func name="FLOAT" also="INT HEX POS"> Parses a string containing a floating-point number A numeric string Default value to use when the string is empty or invalid The parsed number function FLOAT(str, dflt) { if (typeof str == 'string') str=str.replace(/\,/g,'').replace(/^0+/,''); var num=parseFloat(str); return isNaN(num) ? (dflt||0) : num; } <@func name="FLOOR" also="CEIL ROUND"> Truncates a number downward A number The truncation factor The number %0, truncated to the nearset multiple of %1 smaller than or equal to %0 function FLOOR(num, factor) { if (!factor || factor==1) return Math.floor(num); if (Math.abs(factor) < 1) { factor = Math.round(1/factor); return Math.floor(num*factor)/factor; } else { return Math.floor(num/factor)*factor; } } <@func name="HEX" also="INT FLOAT POS"> Parses a string containing a hexadecimal number A hexadecimal string Default value to use when the string is empty or invalid The parsed number function HEX(str, dflt) { var num=parseInt(str,16); return isNaN(num) ? (dflt||0) : num; } <@func name="INT" also="HEX FLOAT POS"> Parses a string containing an integer number A numeric string Default value to use when the string is empty or invalid The parsed integer function INT(str, dflt) { if (typeof str == 'string') str=str.replace(/\,/g,'').replace(/^0+/,''); var num=parseInt(str); return isNaN(num) ? (dflt||0) : num; } <@func name="LIMIT" also="MIN MAX"> Constrains a number to the specified limits Lower bound A number Upper bound Returns %0 if %1<%0, %2 if %1>%2, otherwise, returns %1 function LIMIT(low, num, high) { return (numhigh ? high : num); } <@func name="MAX" also="MIN LIMIT"> Returns the maximum value among its arguments A variable list of numbers The maximum value of {%0} MAX = Math.max; <@func name="MIN" also="MAX LIMIT"> Returns the minimum value among its arguments A variable list of numbers The minimum value of {%0} MIN = Math.min; <@func name="NSTR" also="NVAL"> Returns a formatted string representation of the given number A number The number formatting mask (see remarks) Scaling factor to use for percentages The formatted numeric string The number formatting mask uses the following syntax: [-|+] [Z|P] [B] [C] [n][.m] [\@r | % | $ | \[CUR\] ] where (order is not significant): + | Display "+" for positive values and "-" for negative values - | Display space for positive values and "-" for negative values Z | Display insignificant digits as zeros P | Display insignificant digits as space B | Display blank when the value is zero, regardless of the other codes C | Insert thousands separators into the number n | Number of digits to display to the left of the decimal point. If omitted, then only the significant digits are displayed m | Number of digits to display to the right of the decimal point. If omitted, then only the significant digits are displayed \@r | Display numbers using radix r (2-36) % | Display numbers as percentage of 100 $ | Insert the locale-specific currency code [CUR] | Insert the given currency code. The currency code must be enclosed in brackets (e.g., [USD], [NIS]). NORMAL | Display number in natural format function NSTR(num, mask, scale) { try{ if (num == undefined || num == null) return ''; if (typeof num == 'string') num=num.replace(/\,/g,'').replace(/^0+/,''); num = parseFloat(num||0); if (isNaN(num)) return Number.NaN; if (!mask || mask.toUpperCase() == 'NORMAL') return num.toString(); // break the mask into its components var A = NMASK(mask); var SGN = ''; var PAD = (A[1] == 'Z' ? '0' : (A[1] == 'P' ? ' ' : '')); var BWZ = (A[2] == 'B'); var CMA = (A[3] == 'C'); var LFT = A[4]; var RGT = A[5]; var PCT = (A[6] == '%'); var CUR = A[7]; var RDX = A[8]; if (A[0] == '+') SGN = (num < 0) ? '-' : ( (num > 0) ? '+' : ' '); if (A[0] == '-') SGN = (num < 0) ? '-' : ' '; // build the formatted number string based on the mask components if (BWZ && num == 0) return ''; if (SGN == '' && num < 0) SGN='-'; if (RDX != 10) { PCT = false; CUR = ''; } num = Math.abs(PCT ? num/(scale?scale:100)*100 : num); if (RGT > 0) num = Math.round(num * Math.pow(10,RGT)) / Math.pow(10,RGT); var buf = num.toString(RDX).toUpperCase(); var i = buf.indexOf('.'); var L = (i < 0) ? buf : buf.substring(0,i); var R = (i < 0) ? '' : buf.substring(i+1); if (LFT > 0 && L.length > LFT) return Number.NaN; if (PAD == '0' && LFT > 0) L = SGN+LPAD(L, LFT, PAD); else if (PAD == ' ' && LFT > 0 && !CMA) L = SGN+LPAD(L, LFT+SGN.length, PAD); else L = SGN+L; if (RGT > 0) R = RPAD(R, RGT, PAD||'0'); R = (R == '' ? '' : '.') + R + (PCT ? '%' : CUR); if (!CMA) return L+R; for (var l='', str, i=L.length; i > 0; i-=3) { str = L.substring(Math.max(0, i-3), i); l = str + ((str=='+' || str=='-' || l=='') ? '' : ',') + l; } return l+R; function NMASK(mask) { var arr = ['','','','',0,0,'','',10]; if (!mask || mask.toUpperCase() == 'NORMAL') return arr; function token(tok) { switch (tok.charAt(0).toUpperCase()) { case '+': arr[0] = '+'; break; case '-': arr[0] = '-'; break; case 'Z': arr[1] = 'Z'; break; case 'P': arr[1] = 'P'; break; case 'B': arr[2] = 'B'; break; case 'C': arr[3] = 'C'; break; case '%': arr[6] = '%'; break; case '$': arr[7] = '$'; break; case '[': arr[7] = tok; break; case '@': arr[8] = parseInt(tok.substring(1), 10); break; case '.': arr[5] = parseInt(tok.substring(1), 10); break; default: arr[4] = parseInt(tok, 10); break; } return ''; } mask.replace(/\+|\-|Z|P|B|C|\d+|.\d+|\%|\$|\[\w+\]|\@\d+/gi, token); return arr; } }catch(e){ LOG("NSTR function error, incorrect radix input value, no action was preformed",$CTL.console.LOG_WARNING); TRACE("NSTR function error numValue= " + num + " radixValue=" + RDX +" scaleValue= "+scale+" e:"+ e.message,$CTL.console.TRC_DEBUG); } return num; } <@func name="NVAL" also="NSTR"> Parses a string containing a numeric value A numeric string The number radix (e.g., 2=binary, 8=octal, 10=decimal, 16=hexadecimal) The parsed number function NVAL(str,radix) { if (typeof str == 'number') return str; if (str === undefined || str === null || str === '') return 0; if (typeof str != 'string') { if (str instanceof Date) return str.getTime(); str += ''; } if (str.charAt(0) == '0') { if (str.charAt(1) == 'x') return parseInt(str.substring(2), 16); str = str.replace(/^\0+/,''); } if (str.indexOf(',') >= 0) str = str.replace(/,/g,''); if (radix) { return (parseInt(str, parseInt(radix)) || 0); } else { var num = (parseFloat(str) || 0); return (str.slice(-1) == '%' ? num/100 : num); } } <@func name="POS" also="INT HEX FLOAT"> Parses a string containing a positive number A numeric string Default value to use when the string is empty or invalid The parsed number; returns 0 if the number is negative function POS(str, dflt) { if (typeof str == 'string') str=str.replace(/\,/g,'').replace(/^0+/,''); var num=parseFloat(str); return Math.max(0, isNaN(num) ? (dflt||0) : num); } <@func name="RND"> Returns a random integer between 0 and %0 Maximum random value A random integer between 0 (inclusive) and %0 (exclusive) function RND(n) { return Math.floor(Math.random()*n); } <@func name="ROUND" also="FLOOR ROUND"> Rounds a number A number The rounding factor The number %0, rounded to the nearset multiple of %1 function ROUND(num, factor) { if (!factor || factor==1) return Math.round(num); if (Math.abs(factor) < 1) { factor = Math.round(1/factor); return Math.round(num*factor)/factor; } else { return Math.round(num/factor)*factor; } } <@func name="SIGN" also="ABS"> Returns the sign value of a given number A number Returns -1 if %0<0, +1 if %0>0, and 0 if %0=0 function SIGN(n) { return (n<0) ? -1 : ((n>0) ? 1 : 0); } //////////////////////////////////////////////////////////////////// // MATHEMATICAL FUNCTIONS Math.PI1_2 = 1.5707963267948965; Math.PI2 = 6.283185307179586; Math.D2R = 0.017453292519943295; Math.R2D = 57.29577951308232; <@func name="ACOS" also="COS ASIN ATAN" group="III. Mathematical Functions"> Returns the arccosine of a number A number Returns acos(%0) ACOS = Math.acos; <@func name="ASIN" also="SIN ACOS ATAN"> Returns the arcsine of a number A number Returns asin(%0) ASIN = Math.asin; <@func name="ATAN" also="TAN ATAN2"> Returns the arctangent of a number A number Returns atan(%0) ATAN = Math.atan; <@func name="ATAN2" also="TAN ATAN"> Returns the angle from the X axis to a specified point The cartesian y-coordinate The cartesian x-coordinate The angle (in radians) from the X axis to a point (y,x) ATAN2 = Math.atan2; <@func name="COS" also="SIN TAN ACOS"> Returns the cosine of a number Angle, in radians Returns cos(%0) COS = Math.cos; <@func name="EXP" also="LOG POW"> Returns ~e (the base of natural logarithms) raised to a power A number Returns e%0 EXP = Math.exp; <@func name="LOG" also="EXP POW"> Returns the natural logarithm of a number A number Returns loge(%0) LOGN = Math.log; <@func name="POW" also="SQ SQRT"> Returns the value of a base expression taken to a specified exponent The base value of the expression The exponent value of the expression Returns %0%1 POW = Math.pow; <@func name="SIN" also="COS TAN ASIN"> Returns the sine of a number Angle, in radians Returns sin(%0) SIN = Math.sin; <@func name="SQ" also="POW SQRT"> Returns the square value of a number A number Returns %02 function SQ(n) { return n*n; } <@func name="SQRT" also="POW SQ"> Returns the square root of a number A number Returns %00.5 SQRT = Math.sqrt; <@func name="TAN" also="SIN COS ATAN ATAN2"> Returns the tangent of a number Angle, in radians Returns tan(%0) TAN = Math.tan; ////////////////////////////////////////////////////////////////////////////////////// // DATE FUNCTIONS var DATETIME_UNITS = {Z:1, S:1000, N:60000, H:3600000, D:86400000, M:2592000000, Q:7776000000, Y:31536000000}; <@func name="DATE" also="TIME" group="IV. Date Functions"> Creates a specific date value The number of years The number of months The number of days The new date value function DATE(year, mon, day) { if (arguments.length==0) return new Date(); if (!(year instanceof Number)) year=NVAL(year); if (!(mon instanceof Number)) mon=NVAL(mon); if (!(day instanceof Number)) day=NVAL(day); return new Date(year, mon>0 ? mon-1 : 0, day||1); } <@func name="DADD" also="DSUB"> Increases/decreases a date value by a specified number of date units A date value Number to add to the date value The date unit in which %1 is expressed The new date value function DADD(date, num, unit) { var u=PREF(unit)||'D', d=DVAL(date); if (!d || 'DMQY'.indexOf(unit) < 0) return TADD(date, num, unit); var year=d.getFullYear()||0, mon=d.getMonth()||0, day=d.getDate()||0; switch (u) { case 'D': day += num; break; case 'M': mon += num; break; case 'Q': mon += num*3; break; case 'Y': year += num; break; } return new Date(year, mon, day); } <@func name="DGET" also="DSTR"> Returns the numeric value of a specified date part A date value The date part to extract The value of the specified date part function DGET(date, part) { return parseInt(DSTR(date,part)); } <@func name="DSTR" also="DVAL"> Returns a formatted string representation of the given date value A date value The date formatting mask (see remarks) The formatted date string The date formatting mask uses the following syntax: [date-part | embedded-chars]* | special-format The available date-part codes are listed in @DATE_PARTS. The available special formats are listed in @DATE_FORMATS. Any character codes other than the date-part codes listed above are embedded as is. To insert codes that are reserved as date-part codes you can use HTML espace sequences (e.g., use D for 'D'). function DSTR(date, mask) { if (!date) return ''; if (typeof date == 'string'){ date=DVAL(date,mask); } var YYYY=date.getFullYear(); var M=date.getMonth()+1, MM=('0'+M).slice(-2); var D=date.getDate(), DD=('0'+D).slice(-2); var H=date.getHours(), HH=('0'+H).slice(-2); var N=date.getMinutes(), NN=('0'+N).slice(-2); var S=date.getSeconds(), SS=('0'+S).slice(-2); if (!mask || mask == 'DATETIME') { return DD+'/'+MM+'/'+YYYY+' '+HH+':'+NN+':'+SS; } var Y=YYYY%100, YY=('0'+Y).slice(-2); var DNAME=date.toDateString(), DAY=DNAME.substring(0,3), MON=DNAME.substring(4,7); var MS=('00'+date.getMilliseconds()).slice(-3); var H12=H%12, HH12=('0'+H12).slice(-2), AM=(H < 12 ? 'AM' : 'PM'), PM=AM; var mask1 = mask.toUpperCase().replace('DATETIME', 'DATE'); var mask2 = mask.toUpperCase().replace('DATETIME', 'TIME'); var part1='', part2='', sp=' '; switch (mask1) { case 'SHORT_DATE': part1 = D+'.'+M+'.'+Y; break; case 'DATE': part1 = DD+'.'+MM+'.'+YYYY; break; case 'LONG_DATE': part1 = date.toDateString(); break; case 'XML_DATE': part1 = YYYY+'-'+MM+'-'+DD; sp = ''; break; case 'LOCALE_DATE': part1 = DAY+','+MON+' '+DD+','+YYYY; break; } switch (mask2) { case 'SHORT_TIME': part2 = H+':'+NN; break; case 'TIME': part2 = HH+':'+NN+':'+SS; break; case 'LONG_TIME': part2 = date.toTimeString(); break; case 'XML_TIME': part2 = 'T'+HH+':'+NN+':'+SS; sp = ''; break; case 'LOCALE_TIME': part2 = date.toLocaleTimeString(); break; } if (!part1 && !part2) { return mask.replace(/\w+/gi, token); } else if (part1 && part2) { return part1+sp+part2; } else { return part1+part2; } function token(tok) { try { return eval(tok.toUpperCase()); } catch (e) { return tok; } } } <@func name="DSUB" also="DADD"> Returns the difference between two date values in the specified date unit First date value Second date value The date unit in which the difference is expressed The difference %0-%1 expressed in %2 function DSUB(date1, date2, unit) { unit = DATETIME_UNITS[PREF(unit)||'D'] || 0; return !unit ? Number.NaN : ((date1 && date1.getTime() || 0)-(date2 && date2.getTime() || 0))/unit; } <@func name="DVAL" also="DSTR"> Parses a string containing a date value A date string The date parsing sequence (see remarks) The parsed date value The date string is converted based on the parsing sequence specified in %1: EUR (DD/MM/YYYY) USA (MM/DD/YYYY) XML (YYYY-MM-DD) FREE (free format) function DVAL(str, seq) { if (!str) return null; if (str == '0' || str == ' ') return new Date(); if (typeof str == 'object') return str; var type=0; switch ((seq+'').toUpperCase()) { case 'EUR': case '1': seq = 1; break; case 'USA': case '2': seq = 2; break; case 'XML': case 'XML_DATE': case '3': seq = 3; break; case 'FREE': case '4': seq = 4; break; default: seq = 1; break; } if (seq != 4) { var date = DVAL.regDate.exec(str); if (date) { var D, M, Y; switch (seq) { case 1: D = date[1]; M = date[2]; Y = date[3]; break; case 2: D = date[2]; M = date[1]; Y = date[3]; break; case 3: D = date[3]; M = date[2]; Y = date[1]; break; } Y = parseInt(Y); if (isNaN(Y)) Y = (new Date()).getFullYear(); if (Y<70) Y=2000+Y; else if (Y<100) Y=1900+Y; date = M+'/'+D+'/'+Y; type = type | 1; } var time = DVAL.regTime.exec(str); if (time) { time = time[0]; type = type | 2; } if (date){ switch (type) { case 1: str = date; break; case 2: str = '1/1/1970 '+time; break; case 3: str = date+' '+time; break; } } else { if(!DVAL.regUTC.test(str) && DVAL.reUDate.test(str)){ str = str.replace(DVAL.reUDate, DVAL.reUFunc); } else{ try{ var d=new Date(str); } catch(e){} if(ISNULL(d)||isNaN(d)){ str = '1/1/1970 '+ (time||''); } else return d; } } } var d = new Date(Date.parse(str)); if (!d) { #LOG[4, 'Warning- unknown date format: '+str]; return null; } d.type = type; return d; } DVAL.regDate = /(\d{1,4})(?:\-|\/|\.)(\d{1,2})(?:(?:\-|\/|\.)(\d{1,4})){0,1}/; // Parseable Date DVAL.regUTC = /UTC/g; DVAL.reUFunc = function(a,b,c,d){return a=='-'?',' : ''+ 01 + ','+c+(d ? ','+d :''); } DVAL.reUDate = /((^[a-zA-Z]{3}), (\d{1,4}))|(\-)/g; DVAL.regTime = /(\d{1,2}\:(?:\d{1,2}(?:\:\d{1,2}){0,1}){0,1})/; // Parseable Time <@func name="NOW"> Return the current date The current date function NOW() { return new Date(); } <@enum name="DATE_UNITS" also="DADD DSUB"> An enumeration of date units, used for date arithmetic operations The available date units are listed below: Code | Description | Example D | Days | 86,400,000ms M | Months | 2,592,000,000ms Q | Quarters | 7,776,000,000ms Y | Years | 31,536,000,000ms C | Centuries | 3,153,600,000,000ms <@enum name="DATE_PARTS" also="DSTR DGET"> An enumeration of date parts, used for date formatting operations The available date-part codes are listed below: Code | Description D | Days as 1-31 DD | Days as 01-31 DAY | Days as Sun-Sat M | Months as 1-12 MM | Months as 01-12 MON | Months as Jan-Dec Y | Years as 0-99 YY | Years as 00-99 YYYY | Years as 1900-9999 Any character codes other than the date-part codes listed above are embedded as is. To insert codes that are reserved as date-part codes you can use HTML espace sequences (e.g., use D for 'D'). <@enum name="DATE_FORMATS" also="DSTR"> An enumeration of special date formatting values The available special date formats are listed below: Code | Format | Example DATE | DD/MM/YYYY | 31/01/2001 SHORT_DATE | D/M/Y | 31/1/1 LONG_DATE | Long date format | Wed Jan 31 2001 XML_DATE | YYYY-MM-DD | 2001-01-31 LOCALE_DATE | Locale-specific date format | Jan 31, 2001 //////////////////////////////////////////////////////////////////// // TIME FUNCTIONS <@func name="TIME" also="DATE" group="V. Time Functions"> Creates a specific time value The number of hours The number of minutes The number of seconds The new time value function TIME(hour, min, sec) { if (!(hour instanceof Number)) hour=NVAL(hour); if (!(min instanceof Number)) min=NVAL(min); if (!(sec instanceof Number)) sec=NVAL(sec); return new Date(0, 0, 0, hour, min, sec); } <@func name="TADD" also="TSUB"> Increases/decreases a time value by a specified number of time units A time value Number to add to the time The time unit in which %1 is expressed The new time object function TADD(date, num, unit) { unit = DATETIME_UNITS[PREF(unit)||'D'] || 0; var d=DVAL(date), ms=0; if (d) ms=d.getTime(); return new Date((ms || 0)+num*unit); } <@func name="TGET" also="TSTR"> Returns the numeric value of a specified time part A time value The time part to extract The time part value function TGET(time, part) { return DGET(time, part); } <@func name="TSTR" also="TVAL"> Returns a formatted string representation of the given time value A time value The time formatting mask (see remarks) The formatted time string The time formatting mask uses the following syntax: [time-part | embedded-chars]* | special-format The available time-part codes are listed in @TIME_PARTS. The available special formats are listed in @TIME_FORMATS. Any character codes other than the time-part codes listed above are embedded as is. To insert codes that are reserved as time-part codes you can use HTML espace sequences (e.g., use D for 'D'). function TSTR(time, mask) { return DSTR(time, mask || 'TIME'); } <@func name="TSUB" also="TADD"> Returns the difference between two time values in the specified time unit First time value Second time value The time unit in which the difference is expressed The difference %0-%1 expressed in %2 function TSUB(time1, time2, unit) { return DSUB(time1, time2, unit || 'S'); } <@func name="TVAL" also="TSTR"> Parses a string containing a time value A time string The parsed time value function TVAL(str) { return DVAL(str); } <@func name="TNOW"> Return the current time The current time function TNOW() { return new Date(); } <@enum name="TIME_UNITS" also="TADD TSUB"> An enumeration of time units, used for time arithmetic operations The available time units are listed below: Code | Description | Example Z | Milliseconds | 1ms S | Seconds | 1,000ms N | Minutes | 60,000ms H | Hours | 3,600,000ms <@enum name="TIME_PARTS" also="TSTR TGET"> An enumeration of time parts, used for time formatting operations The available time-part codes are listed below: Code | Description MS | Milliseconds as 000-999 SS | Seconds as 00-59 NN | Minutes as 00-59 H | Hours as 0-23 HH | Hours as 00-23 H12 | Hours as 0-12 HH12 | Hours as 00-12 AM | AM meridian indicator PM | PM meridian indicator Any character codes other than the time-part codes listed above are embedded as is. To insert codes that are reserved as time-part codes you can use HTML espace sequences (e.g., use D for 'D'). <@enum name="TIME_FORMATS" also="TSTR"> An enumeration of special time formatting values The available special time formats are listed below: Code | Format | Example TIME | HH:NN:SS | 02:39:40 SHORT_TIME | H:NN | 2:39 LONG_TIME | Long time format | 02:39:40 UTC+0200 XML_TIME | THH:NN:SS | T02:39:40 LOCALE_TIME | Locale-specific time format | 2:39:40 //////////////////////////////////////////////////////////////////// // BOOLEAN FUNCTIONS <@func name="BOOL" also="IF" group="VI. Boolean Functions"> Evaluates an expression to a Boolean value Any expression Value to return when ~test is ~null or ~undefined The evaluated Boolean value (see remarks) The %1 expression is evaluated according to: A boolean evaluates to itself A number is ~true when it is non-zero A string is ~true when it is equal (ignoring case) to: "true", "T", "yes", "Y", or "1" An ~undefined or ~null value evaluates to %1 argument Any other expression value is ~true function BOOL(test, nvl) { if ((typeof nvl == 'boolean') && (test === null || test === undefined)) return nvl; if (typeof test != 'string') return (test == true); var str = test.charAt(0).toUpperCase(); return (str == 'T' || str == 'Y' || parseInt(str) > 0); } <@func name="IF" also="BOOL"> Returns one of two expressions depending on a condition Any expression An expression returned if ~test is ~true An expression returned if ~test is ~false Returns %1 when %0 is true; otherwise, returns %2 The %0 expression is considered ~true if it evaluates to any value other than ~false. Therefore, a ~null or ~undefined value is also considered ~true by this function. function IF(test, e1, e2) { if (e1 == undefined) e1=true; if (e2 == undefined) e2=false; return ((typeof test == 'boolean') && !test) ? e2 : e1; } <@func name="BVAL" also="Basic!BOOL" scope="private"> Evaluates an expression to a Boolean value, or to ~undefined if the expression doesn't evaluate to a boolean Any expression Value to return when ~test is ~null or ~undefined The evaluated Boolean value (see remarks) The %1 expression is evaluated according to the same rules as in @Basic!BOOL, but if the expression cannot be precisely evaluated to ~true or ~false, ~undefined is returned function BVAL(test, dflt) { if (test === null || test === undefined) return dflt; if (typeof test != 'string') return (test == true); var str = UPPER(test); if (str == 'TRUE' || str == 'YES' || str == '1') return true; if (str == 'FALSE' || str == 'NO' || str == '0') return false; return dflt; } <@func name="ISNULL"> Tests whether an expression is ~null, ~undefined, ~false, or an empty string Expression to test An expression returned if %0 is ~null The test result function ISNULL(a) { return (a === null || a === '' || a === false || a === undefined); } <@func name="NVL"> Returns the first non-null expression among its arguments Variable arguments list Returns en where en is the first non-null expression function NVL() { for (var i=0, len=arguments.length; i Returns a unique id to a text text unique id function MD5(u) { function mtd5(ad,ac){ return(ad<>>(32-ac)); } function mtd1(bp,bo){ var bb,bc,ai,ah,s; ai=(bp&0x80000000); ah=(bo&0x80000000); bb=(bp&0x40000000); bc=(bo&0x40000000); s=(bp&0x3FFFFFFF)+(bo&0x3FFFFFFF); if(bb&bc)return(s^0x80000000^ai^ah); if(bb|bc){ if(s&0x40000000)return(s^0xC0000000^ai^ah); else return(s^0x40000000^ai^ah); }else return(s^ai^ah); } function mtd4(h,bn,bk){return(h&bn)|((~h)&bk);} function mtd3(h,bn,bk){return(h&bk)|(bn&(~bk));} function mtd2(h,bn,bk){return(h^bn^bk);} function mtd12(h,bn,bk){return(bn^(h|(~bk)));} function mtd10(b,d,f,e,h,bd,g){ b=mtd1(b,mtd1(mtd1(mtd4(d,f,e),h),g)); return mtd1(mtd5(b,bd),d); } function mtd9(b,d,f,e,h,bd,g){ b=mtd1(b,mtd1(mtd1(mtd3(d,f,e),h),g)); return mtd1(mtd5(b,bd),d); } function mtd8(b,d,f,e,h,bd,g){ b=mtd1(b,mtd1(mtd1(mtd2(d,f,e),h),g)); return mtd1(mtd5(b,bd),d); } function mtd7(b,d,f,e,h,bd,g){ b=mtd1(b,mtd1(mtd1(mtd12(d,f,e),h),g)); return mtd1(mtd5(b,bd),d); } function mtd6(u){ var l; var k=u.length; var o=k+8; var v=(o-(o%64))/64; var q=(v+1)*16; var i=Array(q-1); var n=0; var c=0; while(c>>29; return i; } function mtd11(ad){ var p="",j="",ba,bted; for(bted=0;bted<=3;bted++){ ba=(ad>>>(bted*8))&255; j="0"+ba.toString(16); p=p+j.substr(j.length-2,2); } return p; } var h=Array(); var m,bx,bw,bv,bu,b,d,f,e var az=7,ay=12,ax=17,aw=22; var av=5,au=9,at=14,as=20; var ar=4,aq=11,ap=16,ao=23; var an=6,am=10,al=15,ak=21; // Steps 1 and 2. Append padding bits and length and convert to words h=mtd6(u); // Step 3. Initialise b=0x67452301;d=0xEFCDAB89;f=0x98BADCFE;e=0x10325476; // Step 4. Process the message in 16-word blocks for(m=0;m Tests whether the string is a Date. A string to check The string or undefined function STRTODATE(str){ if (!str || typeof str != 'string') return undefined; if (str.match(/^(\d+)[\/\.\-](\d+)[\/.\-](\d+)/)) { var dd=parseInt(RegExp.$1,10), mm=parseInt(RegExp.$2,10), yy=parseInt(RegExp.$3,10); if (yy < 70) yy += 2000; else if (yy < 100) yy += 1900; if (mm<1 || mm>12 || dd<1 || dd>31 || (dd>30 && (mm==4||mm==6||mm==9||mm==11)) || (mm==2 && ((yy%4==0 && dd>29) || (yy%4!=0 && dd>28)))) return undefined; return '#Date@'+str; } else return undefined; } <@func name="STRTOTIME"> Tests whether the string is a Time. A string to check The string or undefined function STRTOTIME(str){ if (!str || typeof str != 'string') return undefined; if (str.match(/^(\d+)\:(\d+)(\:\d+)?/)) { var hh=parseInt(RegExp.$1,10), min=parseInt(RegExp.$2,10), sec=parseInt((RegExp.$3||'').slice(1), 10)||0; if (hh>23 || min>59 || sec>59) return undefined; return '#Time@'+str; } else return undefined; } <@func name="STRTONUM"> Tests whether the string is a Number and return it's value. A string to check Number or undefined function STRTONUM(str){ if (!str || typeof str != 'string') return undefined; var value = parseInt(str, 10); if (isNaN(value)) return undefined; else { if ((value+'').length == str.length) return value; value = parseFloat(str); if ((value+'').length == str.length) return value; return undefined; } } <@func name="STRTOBOOL"> Tests whether the string is a Boolean and return it's value. A string to check Boolean or undefined function STRTOBOOL(str){ if (!str || typeof str != 'string') return undefined; if (str.match(/^true$/i)) return true; else if (str.match(/^false$/i)) return false; else return undefined; }