Leap year calculation

Hafsa1
Mega Sage

I have a scheduled job below which will send email every 5, 10,15.....years. Here we want to implement leap year too.

Like user joined on 29th feb 2012 which was leap year and he should receive 5 years completion email on 29th feb 2017 but since 2017 was not leap year, hence there was no 29th feb 2017 and no email trigger. Now, we are in 2022 which is not a leap year and email should trigger to almost 70+ employee on 29th feb which will not get trigger as per code below.

We need to trigger email on next available date which is 1st march 2022. How can we adjust below code to calculate leap year too?

***********

function autoEmail() {
var i;

for (i = 5; i < 40; i= i+5) {
var gdt = new GlideDateTime();
gdt.addYearsUTC(-i);
var queryTime = gdt.getDate();
var gr = new GlideRecord('sn_hr_core_profile');
gr.addQuery('user.u_business_unit', 'US');
gr.addQuery('u_joining_date', queryTime);
gr.query();
while(gr.next()) {
if (gr.user.email.toString() == ""){
gs.eventQueue('sn_hr_core.completion_milestone',gr,i,gr.user.manager.toString());
}else{
gs.eventQueue('sn_hr_core.completion_milestone',gr,i,gr.user.toString());
}
gs.info("Employee : "+ gr.user.name + " completed year "+i);
}}}

 

1 ACCEPTED SOLUTION

Hi,

There was small mistake in code, please try below,

function autoEmail() {
var i;

for (i = 5; i < 40; i= i+5) {
var gdt_today=new GlideTime();
gdt_today.addDaysUTC(-1);
var currentMonth=gdt_today.getMonthLocalTime();
var currentDay=gdt_today.getDayOfMonthLocalTime();
var gdt = new GlideDateTime();
gdt.addYearsUTC(-i);
gdt.addDaysUTC(-1);
var month = gdt.getMonthLocalTime();
var date = gdt.getDayOfMonthLocalTime();
if(month==2 && date==29){
if(!(currentMonth==2 && currentDay==29)){
queryTime = gdt.getDate();
}
}
else{
gdt.addDaysUTC(1);
queryTime = gdt.getDate();
}
var gr = new GlideRecord('sn_hr_core_profile');
gr.addQuery('user.u_business_unit', 'US');
gr.addQuery('u_joining_date', queryTime);
gr.query();
while(gr.next()) {
if (gr.user.email.toString() == ""){
gs.eventQueue('sn_hr_core.completion_milestone',gr,i,gr.user.manager.toString());
}else{
gs.eventQueue('sn_hr_core.completion_milestone',gr,i,gr.user.toString());
}
gs.info("Employee : "+ gr.user.name + " completed year "+i);
}}}

Please mark this as Correct or Helpful if it helps.

Thanks and Regards,
Abhijit

By marking my response as correct or helpful, you contribute to helping future readers with similar issues.
Regards,
Abhijit
ServiceNow MVP

View solution in original post

19 REPLIES 19

is  queryString correct? what it actually says?

var queryString = "u_joingnON" + queryTime + "@javascript:gs.dateGenerate('" + queryTime + "','start')@javascript:gs.dateGenerate('" + queryTime + "','end')^ORsys_created_onON" + nDate + "@javascript:gs.dateGenerate('" + nDate + "','start')@javascript:gs.dateGenerate('" + nDate + "','end')";

My bad. Forgot to paste the function.

function isLeapYear(year) {
  return ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
}

I just the query from setting up a filter. In the filter below, I'm setting Created to Today or Tomorrow. Variable "Created" is a DateTime field. After copying the query, I replace "Created" with u_joining and Today and Yesterday with queryTime and nDate respectively.

find_real_file.png

Abhijit4
Mega Sage

Hi,

Here is little hack to get to your solution. When you directly add -5 years then addYearsUTC function is not really considering the leap years.

However, we can use below trick to get even 29th Feb considering exact 5 years.

var gdt = new GlideDateTime("2025-02-28 11:00:00"); // 2025-02-28 11:00:00->this dat is exact 5 five from 29th Feb 2020
gdt.addDaysUTC(1);
gdt.addYearsUTC(-5);
gdt.addDaysUTC(-1);
var queryTime = gdt.getDate();
gs.print(queryTime);

Output :

find_real_file.png

This works fine for other normal dates as well. see below validated example,

find_real_file.png

Output :

find_real_file.png

Let me know if you have any further queries.

Please mark this as Correct or Helpful if it helps.

Thanks and Regards,
Abhijit

 

By marking my response as correct or helpful, you contribute to helping future readers with similar issues.
Regards,
Abhijit
ServiceNow MVP

Your updated script for the same,

function autoEmail() {
var i;

for (i = 5; i < 40; i= i+5) {
var gdt = new GlideDateTime();
gdt.addDaysUTC(1);
gdt.addYearsUTC(-i);
gdt.addDaysUTC(-1);
var queryTime = gdt.getDate();
var gr = new GlideRecord('sn_hr_core_profile');
gr.addQuery('user.u_business_unit', 'US');
gr.addQuery('u_joining_date', queryTime);
gr.query();
while(gr.next()) {
if (gr.user.email.toString() == ""){
gs.eventQueue('sn_hr_core.completion_milestone',gr,i,gr.user.manager.toString());
}else{
gs.eventQueue('sn_hr_core.completion_milestone',gr,i,gr.user.toString());
}
gs.info("Employee : "+ gr.user.name + " completed year "+i);
}}}
By marking my response as correct or helpful, you contribute to helping future readers with similar issues.
Regards,
Abhijit
ServiceNow MVP