Conditional formatting for dates - date

I'm trying to come up with a simple conditional format formula for highlighting cells that have a date that is greater than three months older than today's date. It seems though that the "Date is before" option only gives a few options, none of them seem to allow what I'm looking for. Is there a custom formula that could accomplish this?
Edit: attaching a snip of the column in question:

Formula :
=DAYS(now(),B2)>90

Go to the custom formula in the conditional formating rules and use this:
=DATEDIF(A1,TODAY(),"D")<90

try:
=1*C2>DATE(YEAR(TODAY()), MONTH(TODAY())+3, DAY(TODAY()))
also make sure you have valid dates and not plain text dates. you can test this with ISDATE formula

You can use Apps Script and a Custom Menu in order to solve your issue with setting the color in the cell depending on the date. Go to Tools->Script Editor and paste this code:
function onOpen() {
var ui = SpreadsheetApp.getUi();
ui.createMenu('Custom Menu')
.addItem('Check Difference', 'dateDifference')
.addToUi();
}
function dateDifference(){
var sheet = SpreadsheetApp.getActiveSheet().getActiveRange(); // Get the selected range on the sheet
var dates = sheet.getValues(); // Get the values in the selected range
var oneDay = 1000*60*60*24;
var row = 1;
var re = /^(0?[1-9]|[12][0-9]|3[01])[\/\-](0?[1-9]|1[012])[\/\-]\d{4}$/; // This will help you to check if it's really a date
dates.forEach(function(el){ // Iterate over each value
if(typeof el[0] == 'object'){ // Check if it's really a date
var gmtZone = el[0].toString().split(" ")[4].split(":")[0]; // Take the date's GMT
var dateFormatted = Utilities.formatDate(el[0], gmtZone, "dd/MM/yyyy"); // Format the date
if(re.test(dateFormatted)){ // Test if it's the right format
// This part will calculate the difference between the current date and the future date
var futureDateMs = new Date(el[0]);
var todayDateMs = (new Date()).getTime();
var differenceInMs = futureDateMs - todayDateMs;
var differenceInDays = Math.round(differenceInMs/oneDay);
if(differenceInDays >= 91.2501){ // Test if the difference it's greater to 91.2501 days (3 motnhs)
sheet.getCell(row, 1).setBackground("#00FF00"); // Set the color to the cell
}
row++;
}
}
});
Save it by clicking on File->Save.
Then you can select a range in a column and click on Custom Menu->Check Difference as you can see in the next image:
As you can see, you will get the desired result:
Notice
It's really important to be careful with what you consider to be a "month", I mean how many days you are going to take into consideration. In my code, I took Google's suggestion of 1 = 30.4167.
Docs
These are other Docs I read to be able to help you:
Utilities.formatDate()
Working with Dates and Times.
I hope this approach can help you.

Related

How to convert Date and Time with mailmerge google slides from sheets as it is in cell

I have created a table with which I can record our check in times of our employees with the help of a generated Qr code in each line.The data in the table is generated as slides and converted into pdf. For this I use a script that I got to work with your help and it works. Here I would like to thank you especially #tanaike.
My problem is that the date and time are not copied to the slides to be generated as indicated in the cell but completely with Central European time and I added in the script to look in column if its empty to generate the slide. If it's not empty don't do anything. As I said everything is working except this two things.
I must confess I did not try to correct it somehow because I had already shot the script and I made some here despair. It would be really great if you write me the solutions and I can take them over. I will share the spreadsheet with you and the screenshot with ae and time. Thanks for your time and effort to help people like us; we are really trying.
As another approach, when I saw your question, I thought that if your Spreadsheet has the correct date values you expect, and in your script, you are retrieving the values using getValues, getValues is replaced with getDisplayValues(), it might be your expected result.
When I saw your provided sample Spreadsheet, I found your current script, when your script is modified, how about the following modification?
From:
var sheetContents = dataRange.getValues();
To:
sheetContents = dataRange.getDisplayValues();
Note:
When I saw your sample Spreadsheet, it seems that the column of the date has mixed values of both the string value and the date object. So, if you want to use the values as the date object using getValues, please be careful about this.
Reference:
getDisplayValues()
Added:
About your 2nd question of I mean that when a slide has been generated, the script saves the link from the slide in column D if the word YES is in column L. How do I make the script create the slide if there is JA in the column L and there is no link in column D. is a link in column D, the script should not generate a slide again. Thus, the script should only generate a slide if column D is empty and at the same time the word JA is in column L., when I proposed to modify from if (row[2] === "" && row[11] === "JA") { to if (row[3] == "" && ["JA", "YES"].includes(row[11])) {, you say as follows.
If ichanged as you descripted if (row[3] == "" && ["JA", "YES"].includes(row[11])) { i got this error. Syntax error: Unexpected token 'else' Line: 21 File: Code.gs
In this case, I'm worried that you might correctly reflect my proposed script. Because when I tested it, no error occurs. So, just in case, I add the modified script from your provided Spreadsheet as follows. Please test this.
Modified script:
function mailMergeSlidesFromSheets() {
var sheet = SpreadsheetApp.getActiveSheet();
var dataRange = sheet.getDataRange();
sheetContents = dataRange.getDisplayValues(); // Modified
sheetContents.shift();
var updatedContents = [];
var check = 0;
sheetContents.forEach(function (row) {
if (row[3] == "" && ["JA", "YES"].includes(row[11])) { // Modified
check++;
var slides = createSlidesFromRow(row);
var slidesId = slides.getId();
var slidesUrl = `https://docs.google.com/presentation/d/${slidesId}/edit`;
updatedContents.push([slidesUrl]);
slides.saveAndClose();
var pdf = UrlFetchApp.fetch(`https://docs.google.com/feeds/download/presentations/Export?exportFormat=pdf&id=${slidesId}`, { headers: { authorization: "Bearer " + ScriptApp.getOAuthToken() } }).getBlob().setName(slides.getName() + ".pdf");
DriveApp.getFolderById("1tRC505IWtTj8nnPB7XyydvTtCJmOb6Ek").createFile(pdf);
// Or DriveApp.getFolderById("###folderId###").createFile(pdf);
} else {
updatedContents.push([row[3]]);
}
});
if (check == 0) return;
sheet.getRange(2, 4, updatedContents.length).setValues(updatedContents);
}
function todaysDateAndTime() {
const dt = Utilities.formatDate(new Date(),Session.getScriptTimeZone(),"MM:dd:yyyy");
const tm = Utilities.formatDate(new Date(),Session.getScriptTimeZone(),"HH:mm:ss");
Logger.log(dt);
Logger.log(tm);
}

Unable to set a javascript date object to a cell hidden by filter

I have a script which checks certain conditions to send reminders emails or sms to my clients. the only issues I'm finding is that if I try to write a cell that is hidden by a filter, the script executes but the data is not changed in any way.
I'll write a short version of the whole script:
function test(){
var nowTime = new Date();
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var lastrow =sheet.getLastRow();
var lastcol =sheet.getLastColumn();
var fullData =cell.offset(0, 0,lastrow-
cell.getRow()+1,lastcol).getValues();
var cell = sheet.getRange("A2");
var i=0;
while (i<fullData.length){
var reminderType =0;
var row = fullData[i];
if (row[0] == 1) {sendreminder();cell.offset(i, 2).setValue(new Date());}
}
}
if for example the first column has hidden all the rows with 1 the script executes and sends all the reminders but ignore the setvalue(), if the rows are visible it works perfectly.
One solution can de to remove the filter but would be very annoying since we use the filter a lot and the script is triggered by time every 10 minutes so I would be working on the sheet and suddenly the filter get removed to run the script.
I have tried with cell.offset, getrange etc.. without any success ... Ideas?
EDIT: The problem seems to be only if I try to write a date if (row[0] == 1) {cell.offset(i, 1).setValue(new Date());}
For instance I'm writing another information (a number) in a different column and that cell gets updated.
The rest remain the same
here is a test sheet I created:
https://docs.google.com/spreadsheets/d/1-FNDGmvCc8nRFTG65Sj9L2RhGn8R3DtwR3llwBG5-FA/edit#gid=0
For now I added this code to save the state of the filter and reestablish it at the end. It's not really elegant and still add a lot of chances of something being messed up or the script failing but it's the less invasive solution I came out with. Does someone has a better one?
// at the beginning
if (sheet1.getFilter()){
var filterRange= sheet1.getFilter().getRange();
var filterSetting = [];
var i=0;
while (i<filterRange.getNumColumns()-1) {filterSetting[i]= sheet1.getFilter().getColumnFilterCriteria(i+1);sheet1.getFilter().removeColumnFilterCriteria(i+1);i++; }
}
// At the end
if (sheet1.getFilter()){
var i=0;
while (i<filterRange.getNumColumns()-1) {if (filterSetting[i]) sheet1.getFilter().setColumnFilterCriteria(i+1, filterSetting[i]);i++; }
}
Given the fact the problem is not writing in the hidden row as it was pointed out, the solution is to use the formatdate to format the value before writing it in the cell.
Not ideal either since regional formattings might prevent the script from working on different accounts but sure better solution than disabling the filters.
here is the code i needed to add:
var nowTime = new Date();
var timeZone = Session.getScriptTimeZone();
var nowTimeFormatted = Utilities.formatDate(nowTime, timeZone, 'MM/dd/yyyy HH:mm:ss');
any idea on how to improve this script or to solve the original problem without workarounds is appreciated :)

How to return a normal javascript date object?

Is it possible to return a javascript date object from this? I have an text input field with the calendar and want to return a standard date object from it's value... Is this possible?
Is this what you are looking for?
var date = '2016-06-12'; // Can be document.getElementById('myField').value that points to your date field.
var date_parts = date.split('-');
var date_obj = new Date(date_parts[0],date_parts[1],date_parts[2]);
console.log(date_obj);
You can also simply use
new Date(document.getElementById('myField').value)
and see if it works. The date function is smart enough to parse based on browser's locale. This should work for time as well. Eg. new Date('2016-06-12 04:15:30')

Jquery onselect datepicker: if specific date then alert

This is my first question on stckoverflow so I hope I'm asking right.
On my website i'm using a jquery datepicker. This works fine. However, I need the following addon:
- When a user selects a date which is a specific date (var specificDate), alert with hello world.
This code already triggers the alert when selecting a date. However I am not able to figure out how to compare the "var date" with the array of specifc dates.
onSelect: function(dateText, inst){
var date = $(this).datepicker('getDate');
var specificDate = ["12-12-2013","11-12-2013"];
for (i=0; i < specificDate.length; i++){
if (date == specificDate [i]){
alert("hello world");
}
}
});
I think I need to know more about the date formats. My question is to get me a bit further with this how to make the comparison.
Thank you in advance!
Reference
if ($.datepicker.parseDate('dd-mm-yy', specificDate[0]) > $.datepicker.parseDate('dd-mm-yyyy', specificDate[1])){
alert(specificDate[0] + 'is later than ' + specificDate[1]);
}

Validating two dates in acrobat javascripts

well the code I posted below all works perfectly except for a small detail. When I input today date in the field dateEntered, the later rejects it, it validates if the date entered is before todays date, validate if the date falls on a weekends, but it also show an error message when it is todays date. Actually the user should be able to enter Today or after date.
Anyone can tell me where am wrong, already tried every possible ways but still not working even the ( ==) or (===) or (<=) ..nothing
if (event.value!="")
{
var e = util.scand("ddd, dd.mmm.yy", event.value);
var a = (e.getTime()) < (new Date().getTime());
if (a) {
app.alert("The Date cannot be before Today's Date", 1);
event.rc = null;
}
if (e.getDay()==6 || e.getDay()==0) {
app.alert("Cannot take permission on a Weekend!", 2);
event.rc=null;
}
}
I found the solution to my problem, I had to set the hour to 0. Thank to the one who updated this on stackoverflow and sorry forget to retain your name.
if (event.value!="")
{
var e = util.scand("ddd, dd.mmm.yy", event.value);
var b=new Date();
b.setHours(0,0,0,0);
if (e<b) {
app.alert("ERROR: Date cannot be before"+" "+ new Date(b), 5);
event.rc = null;
}
if (e.getDay()==6 || e.getDay()==0) {
app.alert("ALERT: The date you entered ("+event.value+") falls on a WEEKEND!", 3);
event.rc=null;
}
}
This codes also contains a condition of removing one weekend from the dates since the number of leaves allowed to take ranges from 1 to 7 thus only one weekend is remove.