How to convert general time to cronjob time using nodejs? - node.js

A cronjob time syntax such as "* * * * * *" followed cron npm
I want convert time from "2017-05-09T01:30:00.123Z" to cron job time format. Have library or method can implement it?

const dateToCron = (date) => {
const minutes = date.getMinutes();
const hours = date.getHours();
const days = date.getDate();
const months = date.getMonth() + 1;
const dayOfWeek = date.getDay();
return `${minutes} ${hours} ${days} ${months} ${dayOfWeek}`;
};
const dateText = '2017-05-09T01:30:00.123Z';
const date = new Date(dateText);
const cron = dateToCron(date);
console.log(cron); //30 5 9 5 2
FYI, you've mentioned "* * * * * *" as a syntax/format of cron which is incorrect. The correct format consists of 5 values separated with spaces (instead of 6 values).

I don't know if there is any library for it or not. But you can simply implement it using simple date functions.
var date=new Date("2017-05-09T01:30:00.123Z");
var mins=date.getMinutes();
//mins variable for the 1st * and so on
var secs=date.getSeconds();
var dayofmonth=date.getDate();
var month=date.getMonth();
var dayofweek=date.getDay();
You can then build a string and use those values in the cron module.

Related

NPM cronJob - dynamically set time

here is my code for scheduling a task. i have used separate routes for starting,stopping and changing the time as given below. please tell me if its correct. and also im getting an error for changing the time frequency.please help me.
const cronjob=require('cron').CronJob
var first='* * * * * *'
var task=function() {
console.log('last'+job.lastDate()+' next '+job.nextDates(1));
}
var complete=function(){
console.log('the end.........')
}
var job = new cronjob(first,task, complete, false, 'Asia/Kolkata');
app.get('/start',(req,res)=>{
job.start()
console.log('is job running? ', job.running);
res.send('cron started')
})
app.get('/set',(req,res)=>{
var time=req.headers.time /* input taken from user for changing the frequency*/
time='30 5 1-31 0-11 1-7' /*hard-coded temporary for testing*/
console.log(time)
job.setTime(time)
})
/set api is throwing an error
/Error: time must be an instance of CronTime./
we have to use instance of a cronTime i.e.
const CronTime = require('cron').CronTime
.
.
.
var time=req.query.time
//time='*/5 * * * * *'
job.setTime(new CronTime(time))
res.send('time changes')

How to specify rotated file location by using rotating-file-stream

I have writtten code like below to log express logs.
const rfs = require("rotating-file-stream");
function formatDate() {
var d = new Date(),
month = '' + (d.getMonth() + 1),
day = '' + d.getDate(),
year = d.getFullYear();
hour = d.getHours();
if (month.length < 2)
month = '0' + month;
if (day.length < 2)
day = '0' + day;
if (hour.length < 2)
hour = '0' + hour
return [year, month, day, hour].join('-');
}
let log_directory = '/../logs/';
let log_date = formatDate()
let log_file_name = path.normalize(__dirname + log_directory + log_date, 'access.log');
let accessLogStream = rfs.createStream(log_file_name, {
size: "300M",
interval: "1d",
})
app.use(morgan(':date[iso] :method :url :body :headers :remote-addr :req[content-length] - :status :response-time ms - :res[content-length] ', { stream: accessLogStream }));
logs are getting stored out side of the project as expected.
But after rotation, the logs are storing inside the project with the below folder names
20200507-0943-01-
20200508-0943-01-
20200509-0943-01-
20200510-0943-01-
20200511-0943-01-
20200512-0943-01-
20200513-0944-01-
package.json
package-lock.json
public
routes
scripts
services
app.js
I don't want these folders created inside the project. Is there any way to handle this?
First of all you are using a static file name as filename parameter of createStream function and you are doing some computation on date to have your resulting file name.
Please note that the computation on date happens only once, before calling the createStream function. In order to do computation on date happening at each rotation you should use a filename generator function. Details can be found in readme.
More than this it seems there is a bug in this line: path.normalize accepts only one parameter.
let log_file_name = path.normalize(__dirname + log_directory + log_date, 'access.log');
Last, to specify a directory for logging, path option should be enough.
If I argued correctly your intentions, following code should solve all the problems
const rfs = require("rotating-file-stream");
function formatDate(d) {
var month = '' + (d.getMonth() + 1),
day = '' + d.getDate(),
year = d.getFullYear(),
hour = d.getHours();
if (month.length < 2)
month = '0' + month;
if (day.length < 2)
day = '0' + day;
if (hour.length < 2)
hour = '0' + hour;
return [year, month, day, hour].join('-');
}
function log_file_name(time, index) {
if (!time) return 'access.log';
return [formatDate(time), index, 'access.log'].join('-');
}
let accessLogStream = rfs.createStream(log_file_name, {
size: "300M",
interval: "1d",
path: '/../logs/'
});

why momentjs returns a wrong minutes from a diff?

I try to calculate a diff between hours and minutes using moment.
for example I want to calculate the diff between: 8:00 and 18:00 (should be 10:00).
But in my code it come out totalMinutes = 600. why?
const xin = '8:00';
const xout = '18:00';
const a = moment(xin, 'HH:mm');
const b = moment(xout, 'HH:mm');
const totalHours = moment.duration(b.diff(a)).asHours();
const totalMinutes = moment.duration(b.diff(a)).asMinutes();
console.log({ r: `${totalHours}:${totalMinutes}` });
// 10:600
You are trying to get diff in hours and minutes which wouldn't give the expected result as they are same thing in different unit. convert them to milisecond, wrap them in moment and format.
const moment = require("moment");
const xin = "8:00";
const xout = "18:00";
const a = moment(xin, "HH:mm");
const b = moment(xout, "HH:mm");
const duration = moment.utc(moment.duration(b.diff(a)).asMilliseconds()).format("HH:mm");
console.log(duration);

Difference between two dates including the first and last day in JS

i have two dates, where the first one is the date start and the second one is the date end.
I have to translate this in number of Years, Months and Days.
Example:
const start = moment(new Date('2021-03-03'))
const end = moment(new Date('2022-03-03'))
const difference = moment.duration(end.diff(start))
const days = difference.days() //30
const months = difference.months() // 11
const years = difference.years() // 0
the result is:
{"days":30,"months":11,"years":0}
But my expected behavior is:
{"days":0,"months":0,"years":1}
How can I reach this?
To achieve your expected behavior just simply change your code:
from this:
const end = moment(new Date('2022-03-03'))
to this:
const end = moment(new Date('2022-03-03')).add('1', 'days')
This will give: {"days":0,"months":0,"years":1}
Final full updated code:
const start = moment(new Date('2021-03-03'))
const end = moment(new Date('2022-03-03')).add('1', 'days')
const difference = moment.duration(end.diff(start))
const days = difference.days() // 0
const months = difference.months() // 0
const years = difference.years() // 1
I think it is because at 03/03 it will always remain at least a millisecond to complete the year.
For example i try to use .startOf('d') and .endOf('d') and this is the results:
const start = moment(new Date('2021-03-03')).startOf('d')
const end = moment(new Date('2022-03-03')).endOf('d')
moment("2021-03-03T00:00:00.000")
moment("2022-03-03T23:59:59.999")
Alex.

How to create application level variable in node.js

In my project I have running more than 100 cron jon using npm cron. My problem is I need to stop any cron job at run time.
my code is
in app.js file
var cronJobRunner =require('cronJobHandle.js');
global.jobManager = {};
cronJobRunner.startServiceFromCronJobManager("service 1")
in cronJobHandle.js
var CronJob = require('cron').CronJob;
module.exports = {
startServiceFromCronJobManager: function (scheduleServiceName) {
var serviceList =['service1','service2','service3','service4']
serviceList.forEach(function(service){
var job = new CronJob('* * * * * *', function(){
console.log("Service running");
}, function () {
// This function is executed when the job stops
},
true /* Start the job right now */,
timeZone /* Time zone of this job. */
);
global.jobManager.service = job;
});
},
stopServiceFromCronJobManager: function (scheduleServiceName) {
console.log(global.jobManager);
global.jobManager[scheduleServiceName].stop();
}
};
router.js
var cronJobRunner =require('cronJobHandle.js');
app.route('/stopservice',function(req,res){
cronJobRunner.stopServiceFromCronJobManager("service1");
}
When I call http://localhost:9999/stopservice
I am getting undefine in console.log(global.jobManager);
Please help me how to maintain cron jobManager variable comman for all server side js files
It is global but there's two bugs in your code.
1) you're calling the property called "service" instead of the one whose name is in service.
Change
global.jobManager.service = job;
to
global.jobManager[service] = job;
2) you're pottentially using global.jobManager in cronJobHandle.js before to declare it in app.js
There's a better solution. you don't need and should use global. Just declare a standard variable in cronJobHandle.js instead (so that it isn't accessed by other modules):
var jobManager = {};
...
jobManager[service] = job;
...
jobManager[scheduleServiceName].stop();

Resources