Comparing version 0.9.13 to 0.9.14
{ | ||
"name": "timexe", | ||
"version": "0.9.13", | ||
"version": "0.9.14", | ||
"description": "Yet another cron clone – but this one is better :o) - new improved syntax – milliseconds resolution – both for node JS and browser", | ||
@@ -5,0 +5,0 @@ "main": "timexe.js", |
@@ -10,5 +10,5 @@ # Timexe - Timer and scheduler | ||
* Written for both node JS and browser inclusion | ||
* Time expressions include ranges, sets, timestamps, weekdays, yeardays and more | ||
* Time expressions include ranges, sets, timestamps, weekdays, yeardays and more | ||
Timexe is based on the setTimeout function. | ||
Timexe is based on the setTimeout function. | ||
@@ -57,9 +57,9 @@ ### Precission | ||
## Note: | ||
## Note: | ||
- Time expression are in local time where as time stamps are in UTC | ||
- Month and weekday use another offset then the javascript Date function: | ||
- Month 1 is January | ||
- Week day 1-7 starting with Monday | ||
- Month 1 is January | ||
- Week day 1-7 starting with Monday | ||
### Examples: | ||
@@ -113,3 +113,3 @@ | Every hour| * * * *| | ||
This is the minimum time resolution for an expression. Minimum value is 1 ms. default is 2 ms. | ||
This should be more the the execution time and delays do to load, of the intepreter. | ||
This should be more the the execution time and delays do to load, of the intepreter. | ||
@@ -157,2 +157,3 @@ ##### timexe.maxTimerDelay (integer) | ||
## Change log | ||
0.9.14 A quick code review. No bugs repported for 2 years. | ||
0.9.13 Minor changes to timex.js | ||
@@ -165,7 +166,6 @@ 0.9.12 Minor changes to comments and reamne.md | ||
####Help | ||
Please don't hesitate to submit an issue on github! It's the only way to make it better. | ||
Please don't hesitate to submit an issue on github! It's the only way to make it better. | ||
But please be prepared to present a test case. | ||
Contributions of almost any kind are welcome. | ||
Contributions of almost any kind are welcome. |
194
timexe.js
@@ -7,3 +7,3 @@ /*============================================================================*\ | ||
Call with a time expression string and a callback function. | ||
Call with a time expression string and a callback function. | ||
The time expression can produce a more complex reoccurring time pattern or a one-time shot, within years, seconds or even milliseconds. | ||
@@ -21,6 +21,5 @@ | ||
Chronos are based on the setTimeout function. It is not very precise. At present it seems to have an accuracy within 25 ms, without significant process load. However it seems to defer execution time, during process load. In some cases that I preferable, but it makes the timing less precise. | ||
Chronos are based on the setTimeout function. It is not very precise. At present it seems to have an accuracy within 25 ms, without significant process load. However it seems to defer execution time, during process load. In some cases that I preferable, but it makes the timing less precise. | ||
To increase precision, you would have to rewrite the function with some form of correction to real time. | ||
To add a timed job every day at noon: | ||
@@ -54,14 +53,14 @@ | ||
w: day of week 1-7 (1 is Monday) | ||
Unspecified minor fields are assumed to have the lowest possible value | ||
Note!: | ||
Note!: | ||
- Time expression are in local time where as time stamps are in UTC | ||
- Month and weekday use another offset then the javascript Date function: | ||
- Month 1 is January | ||
- Week day 1-7 starting with Monday | ||
- In the current implementation, using javascripts settimeout, the accuracy is | ||
- Month 1 is January | ||
- Week day 1-7 starting with Monday | ||
- In the current implementation, using javascripts settimeout, the accuracy is | ||
likely within 25 ms. | ||
Examples: | ||
@@ -75,4 +74,4 @@ | ||
At a specific epoch time: @1422821601.123 | ||
At a specific epoch time: @1422821601.123 | ||
At a specific time: 2014 5 13 18 53 7 300 230 | ||
@@ -86,7 +85,7 @@ | ||
Every morning at 7:30 but not on a weekend: * * !6-7 7 30 | ||
Every morning at 7:30 but not on a weekend: * * !6-7 7 30 | ||
every 10 minutes in the day time: * * * 8-18 /10 | ||
Functions: | ||
@@ -114,3 +113,3 @@ | ||
\*============================================================================*/ | ||
@@ -150,3 +149,3 @@ process.versions.timexe='0.9.7 - No late sundays'; | ||
error: error text | ||
id: new job ID | ||
id: new job ID | ||
@@ -161,5 +160,5 @@ Parameter is an associative array: | ||
// validate parameters | ||
if(typeof timex !== 'string') | ||
if(typeof timex !== 'string') | ||
return {"result":"failed","error":"time expression not a string","id":""}; | ||
if(typeof action !== 'function') | ||
if(typeof action !== 'function') | ||
return {"result":"failed","error":"Action is not a function","id":""}; | ||
@@ -172,3 +171,3 @@ | ||
,timeoutShortened: false // Define the timeout Shortened flag | ||
}) -1; | ||
}) -1; | ||
@@ -180,3 +179,3 @@ // Start timed execution | ||
return {"result":"ok","error":"","id":id}; | ||
} | ||
} | ||
@@ -207,3 +206,3 @@ timexe.remove=function(id){ | ||
,[1, 12] | ||
,[1, 31] | ||
,[1, 31] | ||
,[0, 23] | ||
@@ -216,3 +215,3 @@ ,[0, 59] | ||
,[0, 999] | ||
,[1, 7] // Week day | ||
,[1, 7] // Week day | ||
,[1, 366] // Day of year | ||
@@ -232,3 +231,3 @@ ,[1, 53] // Week number | ||
// Get now | ||
var now = (new Date).getTime()/1000; | ||
var now = (new Date).getTime()/1000; | ||
var starFromTime=now; | ||
@@ -239,8 +238,8 @@ var delay; | ||
if(!timexe.list[id].timeoutShortened){ | ||
// To avoid multiple hits and getting out of sync: set time to after last | ||
// To avoid multiple hits and getting out of sync: set time to after last | ||
// execution time (do to timing errors) | ||
if(typeof timexe.list[id].next !== 'undefined') | ||
if(starFromTime <= timexe.list[id].next) | ||
if(starFromTime <= timexe.list[id].next) | ||
starFromTime = timexe.list[id].next+timexe.timeResolution; | ||
// get next execution time | ||
@@ -252,7 +251,7 @@ var result=timexe.nextTime(timexe.list[id].timex,starFromTime); | ||
if(result.time < now){ | ||
if(result.time < now){ | ||
timexe.remove(id); | ||
return "time expression did not produce a valid future time"; | ||
} | ||
timexe.list[id].next=result.time; | ||
@@ -266,4 +265,4 @@ } | ||
// In some engines, the delay can not be above 32 bit integer | ||
if (delay>timexe.maxTimerDelay){ | ||
delay=timexe.maxTimerDelay; | ||
if (delay>timexe.maxTimerDelay){ | ||
delay=timexe.maxTimerDelay; | ||
// Let the _run function know | ||
@@ -287,7 +286,7 @@ timexe.list[id].timeoutShortened=true; | ||
console.error("Schedule timer fired with null id."); | ||
return; | ||
return; | ||
} | ||
if(typeof timexe.list[id] !== 'object'){ | ||
console.error("Schedule timer fired with invalid id: " + id); | ||
return; | ||
return; | ||
} | ||
@@ -314,8 +313,8 @@ | ||
Timestamp: epoch timestamp to use instead of current time | ||
Return an associative array: | ||
Return an associative array: | ||
time: Epoch timestamp in seconds since 1970-01-01 UTC with fractions of second as decimal part | ||
error: <any error message> | ||
time expression fields: | ||
time expression fields: | ||
<Year> <Month> <day> <Hour> <Minute> <Second> <Millisesond> ... | ||
@@ -326,4 +325,4 @@ Unspecified minor fields are assumed to have the lowest posible value | ||
Note!: Month and weekday use another offset then the javascript Date function: | ||
Month 1 is January | ||
Week day 1-7 starting with Monday | ||
Month 1 is January | ||
Week day 1-7 starting with Monday | ||
@@ -336,7 +335,7 @@ Field syntax: [!][-]<value>[-<value>]|[,<value>] | ||
w: Week day 1-7 where 1 is monday | ||
The epoch timestamp is seconds since 1970-01-01 UTC with fractions of second as decimal part | ||
@<epoch>[.<milliseconds>] | ||
" " : field separator | ||
@@ -355,4 +354,4 @@ * : all values. Flags will be ignored. | ||
y : day of year 1-366 (month field are ignored, but must be valid) | ||
w : day of week 1-7 | ||
w : day of week 1-7 | ||
Examples: | ||
@@ -366,4 +365,4 @@ | ||
At a specific epoch time: @1422821601.123 | ||
At a specific epoch time: @1422821601.123 | ||
At a specific time: 2014 5 13 18 53 7 300 230 | ||
@@ -377,10 +376,10 @@ | ||
Every morning at 7:30 but not on a weekend: * * !6-7 7 30 | ||
Every morning at 7:30 but not on a weekend: * * !6-7 7 30 | ||
every 10 minutes in the day time: * * * 8-18 /10 | ||
every 3th thuesday at 18, execpt in the summer: * * w2 18 & * 21-28 & * !6-8 | ||
This code is optimised for performance rather then readability. | ||
This code is optimised for performance rather then readability. | ||
Please make good test cases that coveres all changes made here. | ||
@@ -419,3 +418,3 @@ \*============================================================================*/ | ||
var maxCarry=nt.length-2; | ||
//console.log(ct.getTime(),(new Date(nt[0],nt[1]-1,nt[2],nt[3],nt[4],nt[5],nt[6])).getTime()); | ||
@@ -453,3 +452,3 @@ | ||
// Set special index | ||
if(f[i]=='w') tp=10; | ||
if(f[i]=='w') tp=10; | ||
else tp=11; | ||
@@ -459,3 +458,3 @@ | ||
}else if(f[i]==',' && field[fpc].val.length>0 && field[fpc].range.length==0){ | ||
continue; | ||
continue; | ||
@@ -480,3 +479,3 @@ // Allow decimal point in epoch time | ||
field[fpc].range=[]; // Drop range | ||
// Values | ||
@@ -494,6 +493,6 @@ }else if(/\d$/.test(f[i]) ){ | ||
"error":"Can't intrepret \""+f[i]+'" at '+l + "\n" + tex + "\n" + " ".repeat(l) + '^' | ||
} | ||
} | ||
// Move field pointer to next position | ||
if( i+1 <f.length | ||
if( i+1 <f.length | ||
&& f[i+1]!=',' | ||
@@ -512,3 +511,3 @@ && f[i+1]!='-' | ||
} | ||
// sum length for displaying error mesage | ||
@@ -522,3 +521,3 @@ l+=f[i].length; | ||
// Loop through fields and assign time | ||
// When time for a field exceeds limits; skip back one field and preset lower values to 0 | ||
// When time for a field exceeds limits; skip back one field and preset lower values to 0 | ||
for(fpc=0; fpc<field.length; fpc++){ | ||
@@ -538,8 +537,8 @@ tp=fpc; | ||
if(field[fpc].flags.indexOf('w')>=0){ | ||
tp=10; | ||
tp=10; | ||
last=7; | ||
lastdom=new Date(date.getFullYear(),date.getMonth()+1,0).getDate(); | ||
// Get week day of current next time | ||
// convert week day 0-6: sunday - saturday to 1-7: monday - sunday | ||
nt[10]=(((date.getDay()+6)%7)+1); | ||
// Get week day of current next time | ||
// convert week day 0-6: sunday - saturday to 1-7: monday - sunday | ||
nt[10]=(((date.getDay()+6)%7)+1); | ||
//nt[10]=((date.getDay()+7)%8+1); | ||
@@ -551,7 +550,7 @@ | ||
last=((new Date(date.getFullYear()+1, 1, 1) - new Date(date.getFullYear(), 1, 1)) / 86400000); | ||
// Get yearday of current next time | ||
// Get yearday of current next time | ||
nt[tp]=Math.ceil((date - new Date(date.getFullYear(), 0, 0)) / 86400000); | ||
if(nt[11]==0) nt[1]=1; | ||
} | ||
} | ||
} | ||
@@ -566,7 +565,7 @@ // day of month | ||
if(field[fpc].val[0]=='*'){ | ||
// If last field; Preset unused fields to low contraint. | ||
// If last field; Preset unused fields to low contraint. | ||
if(fpc==field.length-1){ | ||
for(i=fpc+1;i<nt.length-2;i++) | ||
for(i=fpc+1;i<nt.length-2;i++) | ||
if(nt[i]>limit[i][0]){ | ||
nt[i]=limit[i][0]; | ||
nt[i]=limit[i][0]; | ||
carry=true; | ||
@@ -585,3 +584,3 @@ } | ||
if(!carry && fpc==field.length-1) | ||
for(i=fpc+1;i<maxCarry;i++) | ||
for(i=fpc+1;i<maxCarry;i++) | ||
if(nt[i]>limit[i][0]){ | ||
@@ -594,6 +593,6 @@ next++; | ||
if(next>last){ | ||
if(fpc==0) | ||
if(fpc==0) | ||
return {"time":0,"error":"Out of range time expression: "+tex}; | ||
carry=true | ||
}else{ | ||
@@ -610,3 +609,3 @@ // Test that values are within limits | ||
valid=false; | ||
// Not a number? | ||
// Not a number? | ||
if(isNaN(field[fpc][key][i])) break; | ||
@@ -619,4 +618,4 @@ // Cahch epoch | ||
// Test i minus sign. (Might be -0) | ||
sign=(field[fpc][key][i]<0 | ||
// Test i minus sign. (Might be -0) | ||
sign=(field[fpc][key][i]<0 | ||
|| (typeof field[fpc][key][i]==='string' && field[fpc][key][i].indexOf('-')>=0)); | ||
@@ -628,3 +627,3 @@ // Make integer | ||
// Year: Set to maximum | ||
if(fpc==0) field[fpc][key][i]=limit[tp][1]; | ||
if(fpc==0) field[fpc][key][i]=limit[tp][1]; | ||
// count back from last | ||
@@ -638,7 +637,7 @@ else field[fpc][key][i]=last+(fpc>2?1:0)+field[fpc][key][i]; | ||
// Range: Set to minimum | ||
if(key=='range') field[fpc][key][i]=limit[tp][0]; | ||
if(key=='range') field[fpc][key][i]=limit[tp][0]; | ||
// Value set: delete invalid value | ||
else if(field[fpc][key].length>1) delete field[fpc][key][i]; | ||
// value: Invalid result | ||
else break; | ||
else break; | ||
} | ||
@@ -650,7 +649,7 @@ } | ||
// Range: Set to maximum | ||
if(key=='range') field[fpc][key][i]=limit[tp][1]; | ||
if(key=='range') field[fpc][key][i]=limit[tp][1]; | ||
// Value set: delete invalid value | ||
else if(field[fpc][key].length>1) delete field[fpc][key][i]; | ||
// value: invalid result | ||
else break; | ||
else break; | ||
} | ||
@@ -668,3 +667,3 @@ valid=true; | ||
+field[fpc][key][i]+'" ('+key+')' | ||
} | ||
} | ||
@@ -685,3 +684,3 @@ // Phase 4: Find next time | ||
if(fpc==0){ | ||
// reverse range | ||
// reverse range | ||
val=field[fpc].range[1]; | ||
@@ -692,7 +691,7 @@ field[fpc].range[1]=field[fpc].range[0]; | ||
// Toggle ! flag | ||
if(field[fpc].flags.indexOf('!')>=0) | ||
if(field[fpc].flags.indexOf('!')>=0) | ||
field[fpc].flags=field[fpc].flags.replace('!',''); | ||
else | ||
field[fpc].flags+='!'; | ||
// reverse range | ||
// reverse range | ||
var val=field[fpc].range[1]; | ||
@@ -712,3 +711,3 @@ field[fpc].range[1]=field[fpc].range[0]-1; | ||
// Out of range; set next time (unless ! flag) | ||
}else{ | ||
}else{ | ||
// If ! flag: its a hit | ||
@@ -718,3 +717,3 @@ if(field[fpc].flags.indexOf('!')<0){ | ||
if(next>field[fpc].range[1]) carry=true; | ||
next=field[fpc].range[0]; | ||
next=field[fpc].range[0]; | ||
} | ||
@@ -729,7 +728,7 @@ } | ||
val=next%field[fpc].val[0]; | ||
next+=(val?field[fpc].val[0]-val:0); | ||
next+=(val?field[fpc].val[0]-val:0); | ||
} | ||
// Regular value and value set | ||
}else if(field[fpc].val.length>=1){ | ||
}else if(field[fpc].val.length>=1){ | ||
// order values | ||
@@ -740,8 +739,8 @@ if(field[fpc].val.length>1) field[fpc].val.sort(); | ||
if(field[fpc].val[i]==next && field[fpc].flags.indexOf('!')<0) break; | ||
// Over | ||
// Over | ||
if(field[fpc].val[i]>next){ | ||
// ! flag; loop until hole in values | ||
// ! flag; loop until hole in values | ||
if(field[fpc].flags.indexOf('!')>=0){ | ||
if( i>0 && field[fpc].val[i]-1==field[fpc].val[i]) continue; | ||
}else{ | ||
}else{ | ||
next=field[fpc].val[i]; | ||
@@ -766,3 +765,3 @@ } | ||
"error":'(3) Unable to interpret time expression field '+fieldName[fpc]+' as:'+field[fpc] | ||
}; | ||
}; | ||
@@ -773,13 +772,13 @@ // if next has changed: clear smaller fields | ||
if(tp==10){ | ||
next=nt[2]+next-nt[10]; | ||
next=nt[2]+next-nt[10]; | ||
tp=2; | ||
last=lastdom; | ||
last=lastdom; | ||
} | ||
// Check if next is over limits | ||
if(next<=last){ | ||
for(var ii=fpc+1; ii<maxCarry;ii++) | ||
nt[ii]=limit[ii][0]; | ||
for(var ii=fpc+1; ii<maxCarry;ii++) | ||
nt[ii]=limit[ii][0]; | ||
nt[tp]=next; | ||
}else{ | ||
carry=true; | ||
carry=true; | ||
} | ||
@@ -798,4 +797,4 @@ } | ||
// if Year day, skip month | ||
if(tp==11) | ||
// if Year day, skip month | ||
if(tp==11) | ||
fpc=0; | ||
@@ -806,8 +805,8 @@ | ||
fpc--; | ||
else | ||
else | ||
// if just incrementing same field, it dosent count as a real carry | ||
maxCarry=fpc+1; | ||
// Preset rest of fields to minimum value | ||
for(var i=fpc+1; i<lastMaxCarry;i++) | ||
for(var i=fpc+1; i<lastMaxCarry;i++) | ||
nt[i]=limit[i][0]; | ||
@@ -825,3 +824,3 @@ | ||
// Convert next date to an epoch timestamp | ||
// Date function parameters are: year, month, day, hours, minutes, seconds, milliseconds | ||
// Date function parameters are: year, month, day, hours, minutes, seconds, milliseconds | ||
// NB: months start with 0 for january! | ||
@@ -837,3 +836,2 @@ if(!nt[11]) | ||
return {"time":Math.floor(time/1000)+"."+("00"+time%1000).slice(-3),"error":''}; | ||
} | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
46273
8