UNPKG

elife

Version:

Express life // jump start your web application with express

1,421 lines (1,275 loc) 69.8 kB
Type = require('type-of-is'); //https://github.com/kvz/phpjs/tree/master/functions pathinfo = function(path, options) { // discuss at: http://phpjs.org/functions/pathinfo/ // original by: Nate // revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) // improved by: Brett Zamir (http://brett-zamir.me) // input by: Timo // note: Inspired by actual PHP source: php5-5.2.6/ext/standard/string.c line #1559 // note: The way the bitwise arguments are handled allows for greater flexibility // note: & compatability. We might even standardize this code and use a similar approach for // note: other bitwise PHP functions // note: php.js tries very hard to stay away from a core.js file with global dependencies, because we like // note: that you can just take a couple of functions and be on your way. // note: But by way we implemented this function, if you want you can still declare the PATHINFO_* // note: yourself, and then you can use: pathinfo('/www/index.html', PATHINFO_BASENAME | PATHINFO_EXTENSION); // note: which makes it fully compliant with PHP syntax. // depends on: basename // example 1: pathinfo('/www/htdocs/index.html', 1); // returns 1: '/www/htdocs' // example 2: pathinfo('/www/htdocs/index.html', 'PATHINFO_BASENAME'); // returns 2: 'index.html' // example 3: pathinfo('/www/htdocs/index.html', 'PATHINFO_EXTENSION'); // returns 3: 'html' // example 4: pathinfo('/www/htdocs/index.html', 'PATHINFO_FILENAME'); // returns 4: 'index' // example 5: pathinfo('/www/htdocs/index.html', 2 | 4); // returns 5: {basename: 'index.html', extension: 'html'} // example 6: pathinfo('/www/htdocs/index.html', 'PATHINFO_ALL'); // returns 6: {dirname: '/www/htdocs', basename: 'index.html', extension: 'html', filename: 'index'} // example 7: pathinfo('/www/htdocs/index.html'); // returns 7: {dirname: '/www/htdocs', basename: 'index.html', extension: 'html', filename: 'index'} var opt = '', optName = '', optTemp = 0, tmp_arr = {}, cnt = 0, i = 0; var have_basename = false, have_extension = false, have_filename = false; // Input defaulting & sanitation if (!path) { return false; } if (!options) { options = 'PATHINFO_ALL'; } // Initialize binary arguments. Both the string & integer (constant) input is // allowed var OPTS = { 'PATHINFO_DIRNAME': 1, 'PATHINFO_BASENAME': 2, 'PATHINFO_EXTENSION': 4, 'PATHINFO_FILENAME': 8, 'PATHINFO_ALL': 0 }; // PATHINFO_ALL sums up all previously defined PATHINFOs (could just pre-calculate) for (optName in OPTS) { OPTS.PATHINFO_ALL = OPTS.PATHINFO_ALL | OPTS[optName]; } if (typeof options !== 'number') { // Allow for a single string or an array of string flags options = [].concat(options); for (i = 0; i < options.length; i++) { // Resolve string input to bitwise e.g. 'PATHINFO_EXTENSION' becomes 4 if (OPTS[options[i]]) { optTemp = optTemp | OPTS[options[i]]; } } options = optTemp; } // Internal Functions var __getExt = function(path) { var str = path + ''; var dotP = str.lastIndexOf('.') + 1; return !dotP ? false : dotP !== str.length ? str.substr(dotP) : ''; }; // Gather path infos if (options & OPTS.PATHINFO_DIRNAME) { var dirName = path.replace(/\\/g, '/') .replace(/\/[^\/]*\/?$/, ''); // dirname tmp_arr.dirname = dirName === path ? '.' : dirName; } if (options & OPTS.PATHINFO_BASENAME) { if (false === have_basename) { have_basename = this.basename(path); } tmp_arr.basename = have_basename; } if (options & OPTS.PATHINFO_EXTENSION) { if (false === have_basename) { have_basename = this.basename(path); } if (false === have_extension) { have_extension = __getExt(have_basename); } if (false !== have_extension) { tmp_arr.extension = have_extension; } } if (options & OPTS.PATHINFO_FILENAME) { if (false === have_basename) { have_basename = this.basename(path); } if (false === have_extension) { have_extension = __getExt(have_basename); } if (false === have_filename) { have_filename = have_basename.slice(0, have_basename.length - (have_extension ? have_extension.length + 1 : have_extension === false ? 0 : 1)); } tmp_arr.filename = have_filename; } // If array contains only 1 element: return string cnt = 0; for (opt in tmp_arr) { cnt++; } if (cnt == 1) { return tmp_arr[opt]; } // Return full-blown array return tmp_arr; }; var_dump = function() { // discuss at: http://phpjs.org/functions/var_dump/ // original by: Brett Zamir (http://brett-zamir.me) // improved by: Zahlii // improved by: Brett Zamir (http://brett-zamir.me) // depends on: echo // note: For returning a string, use var_export() with the second argument set to true // test: skip // example 1: var_dump(1); // returns 1: 'int(1)' var output = '', pad_char = ' ', pad_val = 4, lgth = 0, i = 0; var _getFuncName = function(fn) { var name = (/\W*function\s+([\w\$]+)\s*\(/) .exec(fn); if (!name) { return '(Anonymous)'; } return name[1]; }; var _repeat_char = function(len, pad_char) { var str = ''; for (var i = 0; i < len; i++) { str += pad_char; } return str; }; var _getInnerVal = function(val, thick_pad) { var ret = ''; if (val === null) { ret = 'NULL'; } else if (typeof val === 'boolean') { ret = 'bool(' + val + ')'; } else if (typeof val === 'string') { ret = 'string(' + val.length + ') "' + val + '"'; } else if (typeof val === 'number') { if (parseFloat(val) == parseInt(val, 10)) { ret = 'int(' + val + ')'; } else { ret = 'float(' + val + ')'; } } // The remaining are not PHP behavior because these values only exist in this exact form in JavaScript else if (typeof val === 'undefined') { ret = 'undefined'; } else if (typeof val === 'function') { var funcLines = val.toString() .split('\n'); ret = ''; for (var i = 0, fll = funcLines.length; i < fll; i++) { ret += (i !== 0 ? '\n' + thick_pad : '') + funcLines[i]; } } else if (val instanceof Date) { ret = 'Date(' + val + ')'; } else if (val instanceof RegExp) { ret = 'RegExp(' + val + ')'; } else if (val.nodeName) { // Different than PHP's DOMElement switch (val.nodeType) { case 1: if (typeof val.namespaceURI === 'undefined' || val.namespaceURI === 'http://www.w3.org/1999/xhtml') { // Undefined namespace could be plain XML, but namespaceURI not widely supported ret = 'HTMLElement("' + val.nodeName + '")'; } else { ret = 'XML Element("' + val.nodeName + '")'; } break; case 2: ret = 'ATTRIBUTE_NODE(' + val.nodeName + ')'; break; case 3: ret = 'TEXT_NODE(' + val.nodeValue + ')'; break; case 4: ret = 'CDATA_SECTION_NODE(' + val.nodeValue + ')'; break; case 5: ret = 'ENTITY_REFERENCE_NODE'; break; case 6: ret = 'ENTITY_NODE'; break; case 7: ret = 'PROCESSING_INSTRUCTION_NODE(' + val.nodeName + ':' + val.nodeValue + ')'; break; case 8: ret = 'COMMENT_NODE(' + val.nodeValue + ')'; break; case 9: ret = 'DOCUMENT_NODE'; break; case 10: ret = 'DOCUMENT_TYPE_NODE'; break; case 11: ret = 'DOCUMENT_FRAGMENT_NODE'; break; case 12: ret = 'NOTATION_NODE'; break; } } return ret; }; var _formatArray = function(obj, cur_depth, pad_val, pad_char) { var someProp = ''; if (cur_depth > 0) { cur_depth++; } var base_pad = _repeat_char(pad_val * (cur_depth - 1), pad_char); var thick_pad = _repeat_char(pad_val * (cur_depth + 1), pad_char); var str = ''; var val = ''; if (typeof obj === 'object' && obj !== null) { if (obj.constructor && _getFuncName(obj.constructor) === 'PHPJS_Resource') { return obj.var_dump(); } lgth = 0; for (someProp in obj) { lgth++; } str += 'array(' + lgth + ') {\n'; for (var key in obj) { var objVal = obj[key]; if (typeof objVal === 'object' && objVal !== null && !(objVal instanceof Date) && !(objVal instanceof RegExp) && ! objVal.nodeName) { str += thick_pad + '[' + key + '] =>\n' + thick_pad + _formatArray(objVal, cur_depth + 1, pad_val, pad_char); } else { val = _getInnerVal(objVal, thick_pad); str += thick_pad + '[' + key + '] =>\n' + thick_pad + val + '\n'; } } str += base_pad + '}\n'; } else { str = _getInnerVal(obj, thick_pad); } return str; }; output = _formatArray(arguments[0], 0, pad_val, pad_char); for (i = 1; i < arguments.length; i++) { output += '\n' + _formatArray(arguments[i], 0, pad_val, pad_char); } var isNode = typeof module !== 'undefined' && module.exports; if (isNode) { return '<pre >'+output+'</pre>'; } var d = this.window.document; if (d.body) { this.echo(output); } else { try { d = XULDocument; // We're in XUL, so appending as plain text won't work this.echo('<pre xmlns="http://www.w3.org/1999/xhtml" style="white-space:pre;">' + output + '</pre>'); } catch (e) { this.echo(output); // Outputting as plain text may work in some plain XML } } } //EQUIVALENT OF PHP is_string count = function(v){ if(is_array(v)) return v.length; else if(is_number(v)) return (''+v).length; var c = 0; for(var i in v) c++; return c; }; /* * FROM http://stackoverflow.com/questions/10645994/node-js-how-to-format-a-date-string-in-utc */ dateFormat = function(date, fstr, utc) { utc = utc ? 'getUTC' : 'get'; return fstr.replace (/%[YmdHMS]/g, function (m) { switch (m) { case '%Y': return date[utc + 'FullYear'] (); // no leading zeros required case '%m': m = 1 + date[utc + 'Month'] (); break; case '%d': m = date[utc + 'Date'] (); break; case '%H': m = date[utc + 'Hours'] (); break; case '%M': m = date[utc + 'Minutes'] (); break; case '%S': m = date[utc + 'Seconds'] (); break; default: return m.slice (1); // unknown code, remove % } // add leading zero if required return ('0' + m).slice (-2); }); }; empty = function(mixed_var){ var undef, key, i, len; var emptyValues = [undef, null, false, 0, '', '0']; for (i = 0, len = emptyValues.length; i < len; i++) { if (mixed_var === emptyValues[i]) { return true; } } if (typeof mixed_var === 'object') { for (key in mixed_var) { // TODO: should we check for own properties only? //if (mixed_var.hasOwnProperty(key)) { return false; //} } return true; } return false; }; array_int = function(a){ var v = true; for(var i in a){ if(!is_number(a[i])){ v = false; break; } } return v; }; object_merge = function(target, source){ /* * * Merges two (or more) objects, * giving the last one precedence * */ if ( typeof target !== 'object' ) { target = {}; } for (var property in source) { if ( source.hasOwnProperty(property) ) { var sourceProperty = source[ property ]; if ( typeof sourceProperty === 'object' ) { target[ property ] = object_merge( target[ property ], sourceProperty ); continue; } target[ property ] = sourceProperty; } } for (var a = 2, l = arguments.length; a < l; a++) { merge(target, arguments[a]); } return target; }; is_string = function(variable){ return Type.string(variable) == 'String'; }; is_bool = function(variable){ return Type.string(variable) == 'Boolean'; }; is_number = function(variable){ return Type.string(variable) == 'Number'; }; is_object = function(variable){ return Type.string(variable) == 'Object'; }; is_null = function(variable){ return Type.string(variable) == 'Null'; }; is_undefined = function(variable){ return Type.string(variable) == 'Undefined'; }; is_regexp = function(variable){ return Type.string(variable) == 'RegExp'; }; is_array = function(variable){ return Type.string(variable) == 'Array'; }; is_function = function(variable){ return Type.string(variable) == 'Function'; }; is_date = function(variable){ return Type.string(variable) == 'Date'; }; is_error = function(variable){ return Type.string(variable) == 'Error'; }; array_map = function(callback) { // discuss at: http://phpjs.org/functions/array_map/ // original by: Andrea Giammarchi (http://webreflection.blogspot.com) // improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) // improved by: Brett Zamir (http://brett-zamir.me) // input by: thekid // note: If the callback is a string (or object, if an array is supplied), it can only work if the function name is in the global context // example 1: array_map( function (a){return (a * a * a)}, [1, 2, 3, 4, 5] ); // returns 1: [ 1, 8, 27, 64, 125 ] var argc = arguments.length, argv = arguments, glbl = this.window, obj = null, cb = callback, j = argv[1].length, i = 0, k = 1, m = 0, tmp = [], tmp_ar = []; while (i < j) { while (k < argc) { tmp[m++] = argv[k++][i]; } m = 0; k = 1; if (callback) { if (typeof callback === 'string') { cb = glbl[callback]; } else if (typeof callback === 'object' && callback.length) { obj = typeof callback[0] === 'string' ? glbl[callback[0]] : callback[0]; if (typeof obj === 'undefined') { throw 'Object not found: ' + callback[0]; } cb = typeof callback[1] === 'string' ? obj[callback[1]] : callback[1]; } tmp_ar[i++] = cb.apply(obj, tmp); } else { tmp_ar[i++] = tmp; } tmp = []; } return tmp_ar; } array_merge = function() { // discuss at: http://phpjs.org/functions/array_merge/ // original by: Brett Zamir (http://brett-zamir.me) // bugfixed by: Nate // bugfixed by: Brett Zamir (http://brett-zamir.me) // input by: josh // example 1: arr1 = {"color": "red", 0: 2, 1: 4} // example 1: arr2 = {0: "a", 1: "b", "color": "green", "shape": "trapezoid", 2: 4} // example 1: array_merge(arr1, arr2) // returns 1: {"color": "green", 0: 2, 1: 4, 2: "a", 3: "b", "shape": "trapezoid", 4: 4} // example 2: arr1 = [] // example 2: arr2 = {1: "data"} // example 2: array_merge(arr1, arr2) // returns 2: {0: "data"} var args = Array.prototype.slice.call(arguments), argl = args.length, arg, retObj = {}, k = '', argil = 0, j = 0, i = 0, ct = 0, toStr = Object.prototype.toString, retArr = true; for (i = 0; i < argl; i++) { if (toStr.call(args[i]) !== '[object Array]') { retArr = false; break; } } if (retArr) { retArr = []; for (i = 0; i < argl; i++) { retArr = retArr.concat(args[i]); } return retArr; } for (i = 0, ct = 0; i < argl; i++) { arg = args[i]; if (toStr.call(arg) === '[object Array]') { for (j = 0, argil = arg.length; j < argil; j++) { retObj[ct++] = arg[j]; } } else { for (k in arg) { if (arg.hasOwnProperty(k)) { if (parseInt(k, 10) + '' === k) { retObj[ct++] = arg[k]; } else { retObj[k] = arg[k]; } } } } } return retObj; } array_keys = function(input, search_value, argStrict) { // discuss at: http://phpjs.org/functions/array_keys/ // original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) // input by: Brett Zamir (http://brett-zamir.me) // input by: P // bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) // bugfixed by: Brett Zamir (http://brett-zamir.me) // improved by: jd // improved by: Brett Zamir (http://brett-zamir.me) // example 1: array_keys( {firstname: 'Kevin', surname: 'van Zonneveld'} ); // returns 1: {0: 'firstname', 1: 'surname'} var search = typeof search_value !== 'undefined', tmp_arr = [], strict = !! argStrict, include = true, key = ''; if (input && typeof input === 'object' && input.change_key_case) { // Duck-type check for our own array()-created PHPJS_Array return input.keys(search_value, argStrict); } for (key in input) { if (input.hasOwnProperty(key)) { include = true; if (search) { if (strict && input[key] !== search_value) { include = false; } else if (input[key] != search_value) { include = false; } } if (include) { tmp_arr[tmp_arr.length] = key; } } } return tmp_arr; } array_sum = function(array) { // discuss at: http://phpjs.org/functions/array_sum/ // original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) // bugfixed by: Nate // bugfixed by: Gilbert // improved by: David Pilia (http://www.beteck.it/) // improved by: Brett Zamir (http://brett-zamir.me) // example 1: array_sum([4, 9, 182.6]); // returns 1: 195.6 // example 2: total = []; index = 0.1; for (y=0; y < 12; y++){total[y] = y + index;} // example 2: array_sum(total); // returns 2: 67.2 var key, sum = 0; if (array && typeof array === 'object' && array.change_key_case) { // Duck-type check for our own array()-created PHPJS_Array return array.sum.apply(array, Array.prototype.slice.call(arguments, 0)); } // input sanitation if (typeof array !== 'object') { return null; } for (key in array) { if (!isNaN(parseFloat(array[key]))) { sum += parseFloat(array[key]); } } return sum; } count = function(mixed_var, mode) { // discuss at: http://phpjs.org/functions/count/ // original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) // input by: Waldo Malqui Silva // input by: merabi // bugfixed by: Soren Hansen // bugfixed by: Olivier Louvignes (http://mg-crea.com/) // improved by: Brett Zamir (http://brett-zamir.me) // example 1: count([[0,0],[0,-4]], 'COUNT_RECURSIVE'); // returns 1: 6 // example 2: count({'one' : [1,2,3,4,5]}, 'COUNT_RECURSIVE'); // returns 2: 6 var key, cnt = 0; if (mixed_var === null || typeof mixed_var === 'undefined') { return 0; } else if (mixed_var.constructor !== Array && mixed_var.constructor !== Object) { return 1; } if (mode === 'COUNT_RECURSIVE') { mode = 1; } if (mode != 1) { mode = 0; } for (key in mixed_var) { if (mixed_var.hasOwnProperty(key)) { cnt++; if (mode == 1 && mixed_var[key] && (mixed_var[key].constructor === Array || mixed_var[key].constructor === Object)) { cnt += this.count(mixed_var[key], 1); } } } return cnt; } in_array = function(needle, haystack, argStrict) { // discuss at: http://phpjs.org/functions/in_array/ // original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) // improved by: vlado houba // improved by: Jonas Sciangula Street (Joni2Back) // input by: Billy // bugfixed by: Brett Zamir (http://brett-zamir.me) // example 1: in_array('van', ['Kevin', 'van', 'Zonneveld']); // returns 1: true // example 2: in_array('vlado', {0: 'Kevin', vlado: 'van', 1: 'Zonneveld'}); // returns 2: false // example 3: in_array(1, ['1', '2', '3']); // example 3: in_array(1, ['1', '2', '3'], false); // returns 3: true // returns 3: true // example 4: in_array(1, ['1', '2', '3'], true); // returns 4: false var key = '', strict = !! argStrict; //we prevent the double check (strict && arr[key] === ndl) || (!strict && arr[key] == ndl) //in just one for, in order to improve the performance //deciding wich type of comparation will do before walk array if (strict) { for (key in haystack) { if (haystack[key] === needle) { return true; } } } else { for (key in haystack) { if (haystack[key] == needle) { return true; } } } return false; } range = function(low, high, step) { // discuss at: http://phpjs.org/functions/range/ // original by: Waldo Malqui Silva // example 1: range ( 0, 12 ); // returns 1: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] // example 2: range( 0, 100, 10 ); // returns 2: [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100] // example 3: range( 'a', 'i' ); // returns 3: ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'] // example 4: range( 'c', 'a' ); // returns 4: ['c', 'b', 'a'] var matrix = []; var inival, endval, plus; var walker = step || 1; var chars = false; if (!isNaN(low) && !isNaN(high)) { inival = low; endval = high; } else if (isNaN(low) && isNaN(high)) { chars = true; inival = low.charCodeAt(0); endval = high.charCodeAt(0); } else { inival = (isNaN(low) ? 0 : low); endval = (isNaN(high) ? 0 : high); } plus = ((inival > endval) ? false : true); if (plus) { while (inival <= endval) { matrix.push(((chars) ? String.fromCharCode(inival) : inival)); inival += walker; } } else { while (inival >= endval) { matrix.push(((chars) ? String.fromCharCode(inival) : inival)); inival -= walker; } } return matrix; } time = function() { // discuss at: http://phpjs.org/functions/time/ // original by: GeekFG (http://geekfg.blogspot.com) // improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) // improved by: metjay // improved by: HKM // example 1: timeStamp = time(); // example 1: timeStamp > 1000000000 && timeStamp < 2000000000 // returns 1: true return Math.floor(new Date() .getTime() / 1000); } strtotime = function(text, now) { // discuss at: http://phpjs.org/functions/strtotime/ // version: 1109.2016 // original by: Caio Ariede (http://caioariede.com) // improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) // improved by: Caio Ariede (http://caioariede.com) // improved by: A. Matías Quezada (http://amatiasq.com) // improved by: preuter // improved by: Brett Zamir (http://brett-zamir.me) // improved by: Mirko Faber // input by: David // bugfixed by: Wagner B. Soares // bugfixed by: Artur Tchernychev // note: Examples all have a fixed timestamp to prevent tests to fail because of variable time(zones) // example 1: strtotime('+1 day', 1129633200); // returns 1: 1129719600 // example 2: strtotime('+1 week 2 days 4 hours 2 seconds', 1129633200); // returns 2: 1130425202 // example 3: strtotime('last month', 1129633200); // returns 3: 1127041200 // example 4: strtotime('2009-05-04 08:30:00 GMT'); // returns 4: 1241425800 var parsed, match, today, year, date, days, ranges, len, times, regex, i, fail = false; if (!text) { return fail; } // Unecessary spaces text = text.replace(/^\s+|\s+$/g, '') .replace(/\s{2,}/g, ' ') .replace(/[\t\r\n]/g, '') .toLowerCase(); // in contrast to php, js Date.parse function interprets: // dates given as yyyy-mm-dd as in timezone: UTC, // dates with "." or "-" as MDY instead of DMY // dates with two-digit years differently // etc...etc... // ...therefore we manually parse lots of common date formats match = text.match( /^(\d{1,4})([\-\.\/\:])(\d{1,2})([\-\.\/\:])(\d{1,4})(?:\s(\d{1,2}):(\d{2})?:?(\d{2})?)?(?:\s([A-Z]+)?)?$/); if (match && match[2] === match[4]) { if (match[1] > 1901) { switch (match[2]) { case '-': { // YYYY-M-D if (match[3] > 12 || match[5] > 31) { return fail; } return new Date(match[1], parseInt(match[3], 10) - 1, match[5], match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000; } case '.': { // YYYY.M.D is not parsed by strtotime() return fail; } case '/': { // YYYY/M/D if (match[3] > 12 || match[5] > 31) { return fail; } return new Date(match[1], parseInt(match[3], 10) - 1, match[5], match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000; } } } else if (match[5] > 1901) { switch (match[2]) { case '-': { // D-M-YYYY if (match[3] > 12 || match[1] > 31) { return fail; } return new Date(match[5], parseInt(match[3], 10) - 1, match[1], match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000; } case '.': { // D.M.YYYY if (match[3] > 12 || match[1] > 31) { return fail; } return new Date(match[5], parseInt(match[3], 10) - 1, match[1], match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000; } case '/': { // M/D/YYYY if (match[1] > 12 || match[3] > 31) { return fail; } return new Date(match[5], parseInt(match[1], 10) - 1, match[3], match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000; } } } else { switch (match[2]) { case '-': { // YY-M-D if (match[3] > 12 || match[5] > 31 || (match[1] < 70 && match[1] > 38)) { return fail; } year = match[1] >= 0 && match[1] <= 38 ? +match[1] + 2000 : match[1]; return new Date(year, parseInt(match[3], 10) - 1, match[5], match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000; } case '.': { // D.M.YY or H.MM.SS if (match[5] >= 70) { // D.M.YY if (match[3] > 12 || match[1] > 31) { return fail; } return new Date(match[5], parseInt(match[3], 10) - 1, match[1], match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000; } if (match[5] < 60 && !match[6]) { // H.MM.SS if (match[1] > 23 || match[3] > 59) { return fail; } today = new Date(); return new Date(today.getFullYear(), today.getMonth(), today.getDate(), match[1] || 0, match[3] || 0, match[5] || 0, match[9] || 0) / 1000; } return fail; // invalid format, cannot be parsed } case '/': { // M/D/YY if (match[1] > 12 || match[3] > 31 || (match[5] < 70 && match[5] > 38)) { return fail; } year = match[5] >= 0 && match[5] <= 38 ? +match[5] + 2000 : match[5]; return new Date(year, parseInt(match[1], 10) - 1, match[3], match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000; } case ':': { // HH:MM:SS if (match[1] > 23 || match[3] > 59 || match[5] > 59) { return fail; } today = new Date(); return new Date(today.getFullYear(), today.getMonth(), today.getDate(), match[1] || 0, match[3] || 0, match[5] || 0) / 1000; } } } } // other formats and "now" should be parsed by Date.parse() if (text === 'now') { return now === null || isNaN(now) ? new Date() .getTime() / 1000 | 0 : now | 0; } if (!isNaN(parsed = Date.parse(text))) { return parsed / 1000 | 0; } date = now ? new Date(now * 1000) : new Date(); days = { 'sun': 0, 'mon': 1, 'tue': 2, 'wed': 3, 'thu': 4, 'fri': 5, 'sat': 6 }; ranges = { 'yea': 'FullYear', 'mon': 'Month', 'day': 'Date', 'hou': 'Hours', 'min': 'Minutes', 'sec': 'Seconds' }; function lastNext(type, range, modifier) { var diff, day = days[range]; if (typeof day !== 'undefined') { diff = day - date.getDay(); if (diff === 0) { diff = 7 * modifier; } else if (diff > 0 && type === 'last') { diff -= 7; } else if (diff < 0 && type === 'next') { diff += 7; } date.setDate(date.getDate() + diff); } } function process(val) { var splt = val.split(' '), // Todo: Reconcile this with regex using \s, taking into account browser issues with split and regexes type = splt[0], range = splt[1].substring(0, 3), typeIsNumber = /\d+/.test(type), ago = splt[2] === 'ago', num = (type === 'last' ? -1 : 1) * (ago ? -1 : 1); if (typeIsNumber) { num *= parseInt(type, 10); } if (ranges.hasOwnProperty(range) && !splt[1].match(/^mon(day|\.)?$/i)) { return date['set' + ranges[range]](date['get' + ranges[range]]() + num); } if (range === 'wee') { return date.setDate(date.getDate() + (num * 7)); } if (type === 'next' || type === 'last') { lastNext(type, range, num); } else if (!typeIsNumber) { return false; } return true; } times = '(years?|months?|weeks?|days?|hours?|minutes?|min|seconds?|sec' + '|sunday|sun\\.?|monday|mon\\.?|tuesday|tue\\.?|wednesday|wed\\.?' + '|thursday|thu\\.?|friday|fri\\.?|saturday|sat\\.?)'; regex = '([+-]?\\d+\\s' + times + '|' + '(last|next)\\s' + times + ')(\\sago)?'; match = text.match(new RegExp(regex, 'gi')); if (!match) { return fail; } for (i = 0, len = match.length; i < len; i++) { if (!process(match[i])) { return fail; } } // ECMAScript 5 only // if (!match.every(process)) // return false; return (date.getTime() / 1000); } microtime = function(get_as_float) { // discuss at: http://phpjs.org/functions/microtime/ // original by: Paulo Freitas // example 1: timeStamp = microtime(true); // example 1: timeStamp > 1000000000 && timeStamp < 2000000000 // returns 1: true var now = new Date() .getTime() / 1000; var s = parseInt(now, 10); return (get_as_float) ? now : (Math.round((now - s) * 1000) / 1000) + ' ' + s; } date = function(format, timestamp) { // discuss at: http://phpjs.org/functions/date/ // original by: Carlos R. L. Rodrigues (http://www.jsfromhell.com) // original by: gettimeofday // parts by: Peter-Paul Koch (http://www.quirksmode.org/js/beat.html) // improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) // improved by: MeEtc (http://yass.meetcweb.com) // improved by: Brad Touesnard // improved by: Tim Wiel // improved by: Bryan Elliott // improved by: David Randall // improved by: Theriault // improved by: Theriault // improved by: Brett Zamir (http://brett-zamir.me) // improved by: Theriault // improved by: Thomas Beaucourt (http://www.webapp.fr) // improved by: JT // improved by: Theriault // improved by: Rafał Kukawski (http://blog.kukawski.pl) // improved by: Theriault // input by: Brett Zamir (http://brett-zamir.me) // input by: majak // input by: Alex // input by: Martin // input by: Alex Wilson // input by: Haravikk // bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) // bugfixed by: majak // bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) // bugfixed by: Brett Zamir (http://brett-zamir.me) // bugfixed by: omid (http://phpjs.org/functions/380:380#comment_137122) // bugfixed by: Chris (http://www.devotis.nl/) // note: Uses global: php_js to store the default timezone // note: Although the function potentially allows timezone info (see notes), it currently does not set // note: per a timezone specified by date_default_timezone_set(). Implementers might use // note: this.php_js.currentTimezoneOffset and this.php_js.currentTimezoneDST set by that function // note: in order to adjust the dates in this function (or our other date functions!) accordingly // example 1: date('H:m:s \\m \\i\\s \\m\\o\\n\\t\\h', 1062402400); // returns 1: '09:09:40 m is month' // example 2: date('F j, Y, g:i a', 1062462400); // returns 2: 'September 2, 2003, 2:26 am' // example 3: date('Y W o', 1062462400); // returns 3: '2003 36 2003' // example 4: x = date('Y m d', (new Date()).getTime()/1000); // example 4: (x+'').length == 10 // 2009 01 09 // returns 4: true // example 5: date('W', 1104534000); // returns 5: '53' // example 6: date('B t', 1104534000); // returns 6: '999 31' // example 7: date('W U', 1293750000.82); // 2010-12-31 // returns 7: '52 1293750000' // example 8: date('W', 1293836400); // 2011-01-01 // returns 8: '52' // example 9: date('W Y-m-d', 1293974054); // 2011-01-02 // returns 9: '52 2011-01-02' var that = this; var jsdate, f; // Keep this here (works, but for code commented-out below for file size reasons) // var tal= []; var txt_words = [ 'Sun', 'Mon', 'Tues', 'Wednes', 'Thurs', 'Fri', 'Satur', 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ]; // trailing backslash -> (dropped) // a backslash followed by any character (including backslash) -> the character // empty string -> empty string var formatChr = /\\?(.?)/gi; var formatChrCb = function(t, s) { return f[t] ? f[t]() : s; }; var _pad = function(n, c) { n = String(n); while (n.length < c) { n = '0' + n; } return n; }; f = { // Day d: function() { // Day of month w/leading 0; 01..31 return _pad(f.j(), 2); }, D: function() { // Shorthand day name; Mon...Sun return f.l() .slice(0, 3); }, j: function() { // Day of month; 1..31 return jsdate.getDate(); }, l: function() { // Full day name; Monday...Sunday return txt_words[f.w()] + 'day'; }, N: function() { // ISO-8601 day of week; 1[Mon]..7[Sun] return f.w() || 7; }, S: function() { // Ordinal suffix for day of month; st, nd, rd, th var j = f.j(); var i = j % 10; if (i <= 3 && parseInt((j % 100) / 10, 10) == 1) { i = 0; } return ['st', 'nd', 'rd'][i - 1] || 'th'; }, w: function() { // Day of week; 0[Sun]..6[Sat] return jsdate.getDay(); }, z: function() { // Day of year; 0..365 var a = new Date(f.Y(), f.n() - 1, f.j()); var b = new Date(f.Y(), 0, 1); return Math.round((a - b) / 864e5); }, // Week W: function() { // ISO-8601 week number var a = new Date(f.Y(), f.n() - 1, f.j() - f.N() + 3); var b = new Date(a.getFullYear(), 0, 4); return _pad(1 + Math.round((a - b) / 864e5 / 7), 2); }, // Month F: function() { // Full month name; January...December return txt_words[6 + f.n()]; }, m: function() { // Month w/leading 0; 01...12 return _pad(f.n(), 2); }, M: function() { // Shorthand month name; Jan...Dec return f.F() .slice(0, 3); }, n: function() { // Month; 1...12 return jsdate.getMonth() + 1; }, t: function() { // Days in month; 28...31 return (new Date(f.Y(), f.n(), 0)) .getDate(); }, // Year L: function() { // Is leap year?; 0 or 1 var j = f.Y(); return j % 4 === 0 & j % 100 !== 0 | j % 400 === 0; }, o: function() { // ISO-8601 year var n = f.n(); var W = f.W(); var Y = f.Y(); return Y + (n === 12 && W < 9 ? 1 : n === 1 && W > 9 ? -1 : 0); }, Y: function() { // Full year; e.g. 1980...2010 return jsdate.getFullYear(); }, y: function() { // Last two digits of year; 00...99 return f.Y() .toString() .slice(-2); }, // Time a: function() { // am or pm return jsdate.getHours() > 11 ? 'pm' : 'am'; }, A: function() { // AM or PM return f.a() .toUpperCase(); }, B: function() { // Swatch Internet time; 000..999 var H = jsdate.getUTCHours() * 36e2; // Hours var i = jsdate.getUTCMinutes() * 60; // Minutes var s = jsdate.getUTCSeconds(); // Seconds return _pad(Math.floor((H + i + s + 36e2) / 86.4) % 1e3, 3); }, g: function() { // 12-Hours; 1..12 return f.G() % 12 || 12; }, G: function() { // 24-Hours; 0..23 return jsdate.getHours(); }, h: function() { // 12-Hours w/leading 0; 01..12 return _pad(f.g(), 2); }, H: function() { // 24-Hours w/leading 0; 00..23 return _pad(f.G(), 2); }, i: function() { // Minutes w/leading 0; 00..59 return _pad(jsdate.getMinutes(), 2); }, s: function() { // Seconds w/leading 0; 00..59 return _pad(jsdate.getSeconds(), 2); }, u: function() { // Microseconds; 000000-999000 return _pad(jsdate.getMilliseconds() * 1000, 6); }, // Timezone e: function() { // Timezone identifier; e.g. Atlantic/Azores, ... // The following works, but requires inclusion of the very large // timezone_abbreviations_list() function. /* return that.date_default_timezone_get(); */ throw 'Not supported (see source code of date() for timezone on how to add support)'; }, I: function() { // DST observed?; 0 or 1 // Compares Jan 1 minus Jan 1 UTC to Jul 1 minus Jul 1 UTC. // If they are not equal, then DST is observed. var a = new Date(f.Y(), 0); // Jan 1 var c = Date.UTC(f.Y(), 0); // Jan 1 UTC var b = new Date(f.Y(), 6); // Jul 1 var d = Date.UTC(f.Y(), 6); // Jul 1 UTC return ((a - c) !== (b - d)) ? 1 : 0; }, O: function() { // Difference to GMT in hour format; e.g. +0200 var tzo = jsdate.getTimezoneOffset(); var a = Math.abs(tzo); return (tzo > 0 ? '-' : '+') + _pad(Math.floor(a / 60) * 100 + a % 60, 4); }, P: function() { // Difference to GMT w/colon; e.g. +02:00 var O = f.O(); return (O.substr(0, 3) + ':' + O.substr(3, 2)); }, T: function() { // Timezone abbreviation; e.g. EST, MDT, ... // The following works, but requires inclusion of the very // large timezone_abbreviations_list() function. /* var abbr, i, os, _default; if (!tal.length) { tal = that.timezone_abbreviations_list(); } if (that.php_js && that.php_js.default_timezone) { _default = that.php_js.default_timezone; for (abbr in tal) { for (i = 0; i < tal[abbr].length; i++) { if (tal[abbr][i].timezone_id === _default) { return abbr.toUpperCase(); } } } } for (abbr in tal) { for (i = 0; i < tal[abbr].length; i++) { os = -jsdate.getTimezoneOffset() * 60; if (tal[abbr][i].offset === os) { return abbr.toUpperCase(); } } } */ return 'UTC'; }, Z: function() { // Timezone offset in seconds (-43200...50400) return -jsdate.getTimezoneOffset() * 60; }, // Full Date/Time c: function() { // ISO-8601 date. return 'Y-m-d\\TH:i:sP'.replace(formatChr, formatChrCb); }, r: function() { // RFC 2822 return 'D, d M Y H:i:s O'.replace(formatChr, formatChrCb); }, U: function() { // Seconds since UNIX epoch return jsdate / 1000 | 0; } }; this.date = function(format, timestamp) { that = this; jsdate = (timestamp === undefined ? new Date() : // Not provided (timestamp instanceof Date) ? new Date(timestamp) : // JS Date() new Date(timestamp * 1000) // UNIX timestamp (auto-convert to int) ); return format.replace(formatChr, formatChrCb); }; return this.date(format, timestamp); } function_exists = function(func_name) { // discuss at: http://phpjs.org/functions/function_exists/ // original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) // improved by: Steve Clay // improved by: Legaev Andrey // improved by: Brett Zamir (http://brett-zamir.me) // example 1: function_exists('isFinite'); // returns 1: true if (typeof func_name === 'string') { try { func_name = this.window[func_name]; }catch(e){} } return typeof func_name === 'function'; } rand = function(min, max) { // discuss at: http://phpjs.org/functions/rand/ // original by: Leslie Hoare // bugfixed by: Onno Marsman // note: See the commented out code below for a version which will work with our experimental (though probably unnecessary) srand() function) // example 1: rand(1, 1); // returns 1: 1 var argc = arguments.length; if (argc === 0) { min = 0; max = 2147483647; } else if (argc === 1) { throw new Error('Warning: rand() expects exactly 2 parameters, 1 given'); } return Math.floor(Math.random() * (max - min + 1)) + min; /* // See note above for an explanation of the following alternative code // + reimplemented by: Brett Zamir (http://brett-zamir.me) // - depends on: srand // % note 1: This is a very possibly imperfect adaptation from the PHP source code var rand_seed, ctx, PHP_RAND_MAX=2147483647; // 0x7fffffff if (!this.php_js || this.php_js.rand_seed === undefined) { this.srand(); } rand_seed = this.php_js.rand_seed; var argc = arguments.length; if (argc === 1) { throw new Error('Warning: rand() expects exactly 2 parameters, 1 given'); } var do_rand = function (ctx) { return ((ctx * 1103515245 + 12345) % (PHP_RAND_MAX + 1)); }; var php_rand = function (ctxArg) { // php_rand_r this.php_js.rand_seed = do_rand(ctxArg); return parseInt(this.php_js.rand_seed, 10); }; var number = php_rand(rand_seed); if (argc === 2) { number = min + parseInt(parseFloat(parseFloat(max) - min + 1.0) * (number/(PHP_RAND_MAX + 1.0)), 10); } return number; */ } md5 = function(str) { // discuss at: http://phpjs.org/functions/md5/ // original by: Webtoolkit.info (http://www.webtoolkit.info/) // improved by: Michael White (http://getsprink.com) // improved by: Jack // improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) // input by: Brett Zamir (http://brett-zamir.me) // bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) // depends on: utf8_encode // example 1: md5('Kevin van Zonneveld'); // returns 1: '6e658d4bfcb59cc13f96c14450ac40b9' var xl; var rotateLeft = function(lValue, iShiftBits) { return (lValue << iShiftBits) | (lValue >>> (32 - iShiftBits)); }; var addUnsigned = function(lX, lY) { var lX4, lY4, lX8, lY8, lResult; lX8 = (lX & 0x80000000); lY8 = (lY & 0x80000000); lX4 = (lX & 0x40000000); lY4 = (lY & 0x40000000); lResult = (lX & 0x3FFFFFFF) + (lY & 0x3FFFFFFF); if (lX4 & lY4) {