- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
01-12-2023 06:53 AM
Within a catalog item, I have a need to set a planned_start_date(date/time variable) to either the 8th or the 20th of the current month based on the current date/time. For example: if today is 1/12/2023, I need the planned_start_date to be set to 1/20/2023. If the current date was 1/22/2023 I'd need the planned_start_date to be 2/8/2023. We will only be setting it to the 8th or the 20th of the month. I'd like this to be within the workflow in a RUN Script activity if possible, but a client script is also an option. Below is what I tried but it's not working. Any ideas?
var gdt = new GlideDateTime();
var dayOfMonth = gdt.getDayOfMonthLocalTime();
if( dayOfMonth > 8 ) {
current.variables.planned_start_date = dayOfMonth(20);
}
else {
current.variables.planned_start_date = dayOfMonth(8);
}
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
01-12-2023 10:42 PM
Hi @booher04 ,
Below should work:
(function executeRule(current, previous /*null when async*/) {
var gdt = new GlideDate;
var date = gdt.getByFormat("yyyy-MM-dd");
var dateInMonth = gdt.getDayOfMonthUTC();
var findDaysDifference = 0;
var futureDate = 0;
if(dateInMonth > 8 && dateInMonth <= 19) {
findDaysDifference = 20 - dateInMonth;
gdt.addDays(findDaysDifference);
} else if(dateInMonth <= 20 && dateInMonth >= 31) {
findDaysDifference = dateInMonth - 8;
gdt.addMonthsLocalTime(1);
gdt.addDays(findDaysDifference);
} else {
findDaysDifference = 8 - dateInMonth;
gdt.addDays(findDaysDifference);
}
futureDate = gdt.getDisplayValue();
gs.info("Todays date is "+ date)
gs.info("Todays date number is "+ dateInMonth);
gs.info("Count until future date is "+ findDaysDifference);
gs.info("Set future date to "+ futureDate);
})(current, previous);
If my answer has helped with your question, please mark my answer as accepted solution and give a thumb up.
Best regards
Anders
If my answer has helped with your question, please mark my answer as the accepted solution and give a thumbs up.
Best regards
Anders
Rising star 2024
MVP 2025
linkedIn: https://www.linkedin.com/in/andersskovbjerg/
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
01-13-2023 09:03 AM
I just realize that planned_start_date looks to actually be a Date/time (not a Date), so the correct code is
current.variables.planned_start_date = setForThe8th(nowGDT, dayOfMonthNow) ||
setForThe20th(nowGDT, dayOfMonthNow) ||
setForNextMonth(nowGDT);
not
current.variables.planned_start_date = (setForThe8th(nowGDT, dayOfMonthNow) ||
setForThe20th(nowGDT, dayOfMonthNow) ||
setForNextMonth(nowGDT)).getDate();
There is no need to convert the resultant GlideDateTime into a GlideDate.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
01-23-2023 07:11 AM
Perfect. That's what I was kind of thinking but I couldn't get it to work correctly. I appreciate your help with it.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
01-23-2023 07:55 AM - edited 01-23-2023 07:56 AM
This should work:
(function executeRule (previous, current, dayFirstHalf, daySecondHalf) {
var nowGDT = new GlideDateTime(),
localTZ = Packages.java.util.TimeZone.getTimeZone('EST');
nowGDT.setTZ(localTZ);
nowGDT.setDisplayValueInternal(getDisplayValueInternal(nowGDT));
current.variables.planned_start_date = nowGDT;
function getDisplayDateInternal (nowGDT, dayOfMonth) {
return setForFirstHalf(nowGDT, dayOfMonth) ||
setForSecondHalf(nowGDT, dayOfMonth) ||
setForNextMonth(nowGDT, nowGDT.getMonthLocalTime());
}
function getDisplayTimeInternal () {
return '21:00:00';
}
function getDisplayValueInternal (nowGDT) {
return [getDisplayDateInternal(nowGDT, nowGDT.getDayOfMonthLocalTime()),
getDisplayTimeInternal()].join(' ');
}
function setForFirstHalf (nowGDT, dayOfMonth) {
if (dayOfMonth < dayFirstHalf) {
nowGDT.setDayOfMonthLocalTime(dayFirstHalf);
return nowGDT.getLocalDate().getValue();
}
}
function setForSecondHalf (nowGDT, dayOfMonth) {
if (dayOfMonth < daySecondHalf) {
nowGDT.setDayOfMonthLocalTime(daySecondHalf);
return nowGDT.getLocalDate().getValue();
}
}
function setForNextMonth (nowGDT, currentMonth) {
nowGDT.setMonthLocalTime(currentMonth + 1);
nowGDT.setDayOfMonthLocalTime(dayFirstHalf);
return nowGDT.getLocalDate().getValue();
}
})(previous, current, 8, 20);
While working with local and UTC values and GlideDateTime is pretty str8 fwd, the same cannot be said about GlideDate and GlideDateTime.
In case of GlideDateTime the rules are simple:
- to set or get the value in UTC, one calls the not-display methods (setValue(), getValue());
- to set or get the value in Local TZ (rather the current user's preferred TZ) one calls the display methods (setDisplayValue(), setDisplayValueInternal(), getDisplayValue(), getDisplayValueInternal(), etc.)
In case of GlideDate and GlideTime this no longer applies. E.g. in case of GlideDate, both category of methods returns the same thing. If the GlideDate is obtained by calling the getLocalDate() method of a GlideDateTime, both categories of methods still return the same thing, but this time the local time. But it is even more complicated in case of GlideTime, cause context (the date "portion" of a GlideTime) also influences what time it will return. Cause it seems it honors DST, so getting the local time from a GlideTime that has been created from scratch returns one thing and if created by calling the getTime() method of a GlideDateTime in a different DST returns another thing.
And this is only server side; client side is also murky to handle; client side one deals with 3 TZs: UTC, the current user's preferred TZ and the device's "real" TZ. Usually the latter two will be the same, but there is nothing stopping a user from selecting a preferred TZ that is different from the device's TZ, e.g. if working for the west cost, but on the east coast.
😵
ServiceNow could easily create a 3-4 days long course just on how GlideDate, GlideTime and GlideDateTime work 🙂
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
01-23-2023 08:16 AM
This worked! Thank you for your help!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
01-23-2023 10:00 AM
You're welcome! 🙂
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
01-20-2023 09:26 AM
Anders - thanks for all of your help. I have an extra requirement from the customer now. They want the time to be set to 9:00:00 PM for the planned_start_date and 10:00:00 PM for the planned_end_date. I have the code you helped with working except for this new requirement. I haven't been able to get it to work.
(function executeRule(current, previous /*null when async*/) {
var gdt = new GlideDateTime;
var date = gdt.getByFormat('yyyy-MM-dd HH:mm:ss');
var dateInMonth = gdt.getDayOfMonthUTC();
var findDaysDifference = 0;
var futureDate = 0;
if(dateInMonth > 8 && dateInMonth <= 19) {
findDaysDifference = 20 - dateInMonth;
gdt.addDays(findDaysDifference);
} else if(dateInMonth <= 20 && dateInMonth >= 31) {
findDaysDifference = dateInMonth - 8;
gdt.addMonthsLocalTime(1);
gdt.addDays(findDaysDifference);
} else {
findDaysDifference = 8 - dateInMonth;
gdt.addDays(findDaysDifference);
}
futureDate = gdt.getDisplayValue();
var arrDate = [];
arrDate = futureDate.toString().split(' ');
current.variables.planned_start_date.setDisplayValue(arrDate[0]+ '21:00:00', 'yyyy-MM-dd HH:mm:ss');
current.variables.planned_end_date = arrDate[0].addSeconds(3600);
})(current, previous);