I have a column in which dates are saved in string format like this: "Tuesday, 18th November(11:00)"
I want to take this string date and save its equivalent date in Date format corresponding to its row in new column (first empty column in sheet), so that I can later compare that date with current date.
I have written this function and I am in test phase. However I have two questions :
1) This function is not inserting value in corresponding row in new column.
2) Since setValue is Object type it will not save value in Date type, for me setDay, set Month methods are not working (may be because of wrong object).
Here is my code:
function replaceStringDate(e) {
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 2;
var lastRow = SpreadsheetApp.getActiveSheet().getLastRow();
var lastColumn = SpreadsheetApp.getActiveSheet().getLastColumn();
var dataRange = sheet.getRange(startRow,2,lastRow,12);
var values = dataRange.getValues();
var index = dataRange.getRowIndex();
for(i=0;i<values.length;++i){
var lastCell = sheet.getRange(index,14);
var appointmentDateFirst = values[i][8] ;
if (appointmentDateFirst == "Thursday, 18th November (11:00 to 12:00)") {lastCell.setValue('18/11/2011');}
index=index+1;
} //end for loop
} //end function
here is a piece of code to start with, I played with string manipulation and regex... It's kind of fragile and needs to be improved to handle different cases but the idea is working...
I'm sure it can be done more efficiently with only regex but this string approach was easier...
function convertToDateTest(){
Logger.log(convertToDate("Tuesday, 18th November(11:00)"))
}
function convertToDate(str){
Logger.log(str.substring(str.indexOf(', ')+1,str.indexOf('(')).replace('th','')+' '+new Date().getFullYear());
var date = new Date(str.substring(str.indexOf(', '),str.indexOf('(')).replace('th','')+' '+new Date().getFullYear());
var time = str.match(/((([0-1]?[0-9])|([2][0-3])):)([0-5][0-9])/g);
Logger.log(time);
new Date(date).setHours(time[0]);
return date;
}
Related
I have a column 'C' containing dates and in that some cell values are having values like " Due on Date". I have written app script code that if a cell value contains "Due on" it will be copied to another column,else copied to different column.But on running I found that cells having "due on " on running the date and month are interchanged. for eg: if a cell contains "Due on 08/02/2022(dd/MM/yyyy)" is changed to "02/08/2022(MM/dd/yyyy)". Is there any method to retain the same date format.I have already done the date format methods in the spreadsheet and maintained the same time zone .
Here is the sample code:
for(var i=value.length-1;i>=0;i--){
var chn = value[i];
if(chn[2]!="NA"){
// var rdate= new Date(chn[2]);
var dat=Utilities.formatDate(new Date(chn[2]), "GMT+5:30", "dd-MMMM-yyyy");
var mat= chn[2].toString();
if(mat.match(/Due on/)){
var d1= mat.replace("Due on", "");
var ds = new Date(dat);
var year = ds.getFullYear();
var month = ds.getDate();
var day = ds.getMonth();
Logger.log(chn[2]);
Logger.log(dat);
Logger.log(ds);
Logger.log(month);
// var pubdate = new Date(year, day,month);
// Logger.log(pubdate);
ss.getRange("C"+(i+2)).setValue("Valid till "+Utilities.formatDate(ds, "GMT+5:30", "dd-MMMM-yyyy"));
}
else{
.................
}
}
A copy of the spreadsheet and the executions log is attached here:
Execution log:
You code works for me correctly, however here are some thoughts for troubleshooting
You do not specify into which sheet you want to write (I assume ss is SpreadsheetApp.getActiveSpreadsheet()). This is dangerous when your spreadsheet has several sheets. It's best to sue the method getSheetByName()
Reduce your code snippet to something simpler to reduce potential error sources
Change you spreadsheet locale for changing the date formatting
Since your date is concatenated to a string (and the method formatDate() returns a date anyway), the output should not be affected by any locales and date formatting, however to be sure, try to set it explicitly to a string.
Make sure you pass to new Date() a valid date object or date string.
This code snippet works for me regardless of the spreadsheet locale and the number formatting of the cells:
function myFunction() {
var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1");
for(var i = 10; i >= 0; i--){
var dat=Utilities.formatDate(new Date("2022-05-15"), "GMT+5:30", "dd-MMMM-yyyy");
ss.getRange("C"+(i+2)).setValue(("Due on " + dat).toString());
}
}
UPDATE:
If the problem is the format of the original date string, you need to convert it to the necessary format for new Date(). To do so, you need to know the formatting of the original date string.
For a date string with the format ddmmyyyy , you can do it as following:
var chn = [];
chn[2] = "15052022";
var day = Number(chn[2].substring(0,2));
var month = Number(chn[2].substring(2,4));
var year = Number(chn[2].substring(4,8));
console.log("day: " + day)
console.log("month: " + month)
console.log("year: " + year)
var dat= Utilities.formatDate(new Date(year, month - 1, day), "GMT+5:30", "dd-MMMM-yyyy");
ss.getRange("C2").setValue(("Due on " + dat).toString());
I have a Google Sheet that has entries with one of the Columns having a date when it's entered. I want the code to check if a date in Column E is older than 30 days and delete the row.
However, I have column E specifically formatted in plain text under the sheet options. The reason for doing so is I have a different script pull the data from the sheets as JSON and setting the column to plain text makes it show up as a string how I wanted in my JSON.
My code works if I format the column "E" in a date format.
Data is currently added as so "May 11th, 2021" whereas the closest date format in sheets is "May 11, 2021" without the "th" or "rd" after the dates but I would like to keep it how I have it if possible.
The code below works if Column E is formatted in date format but is there a way to get it to work as plain text format option which I currently have it set to?
Made a dummy Google Sheet for visual:
https://docs.google.com/spreadsheets/d/1_156bLL03lFo9NdjE6KmrGiFJvYXkvReel_9znMwT4M/edit?usp=sharing
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("sheet1"); //assumes Sheet 1 is the name of the sheet
var datarange = sheet.getDataRange();
var lastrow = datarange.getLastRow();
var values = datarange.getValues();// get all data in a 2D array
var monthOld = new Date()
monthOld = new Date(monthOld.getTime()-30*3600000*24) //Set date 30 days in past from today
Logger.log(monthOld) // confirm I am getting date 30 days ago
for (i=lastrow;i>=2;i--) {
var tempDate = values[i-1][4];// arrays are 0 indexed so row2 = values[1] and colE = [4]
Logger.log(tempDate)
if (tempDate <= monthOld)
{
sheet.deleteRow(i);
Logger.log(`Row ${i} was deleted`);
} else {
Logger.log(`Nothing was deleted`);
}
}
}
Try
var tempDate = new Date(values[i-1][4].replace(/(th|rd|st|nd)/gm,""));
Using the testbelow function as an intermediate function to pass the appropriate arguments to isOlderThan(). You pass the datestring in ds and the number of days in days. isOlderThan returns true or false based upon todays date.
function testbelow() {
isOlderThan({ds:"Jul 30th, 2021",days:30})
}
function isOlderThan(obj) {
const dA = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug"]
const dt = new Date();
const dtv = new Date(dt.getFullYear(),dt.getMonth(),dt.getDate() - obj.days).valueOf();
let t = obj.ds.split(" ");
let idtv = new Date(t[2],dA.indexOf(t[0]),parseInt(t[1])).valueOf();
Logger.log(idtv < dtv);
return idtv < dtv
}
Mike Steelson provided the line of code I needed to convert the plain text by parsing out the values that didn't apply and converting it to a date.
var tempDate = new Date(values[i-1][4].replace(/(th|rd|st|nd)/gm,""));
I want to compare the dates in Referral Date column with the present day and if Referral Date is lesser than present day then proceed with script if not throw an error "future date referral".
function dateFun() {
var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Worksheet");
var headers = ss.getRange('A:Z').getValues()[0];
var column =headers.indexOf("Referral Date")+1;
var presentDay = new Date();
if (column.valueOf()>presentDay){
}else{
SpreadsheetApp.getUi().alert("Future Date Referral")
}
}
Image for reference
Hope its clear!
Date objects can be compared with logical operators.
Ok you are on the right track here, but you are missing some important methods to get the data from the spreadsheet.
function dateFun() {
// Open the worksheet
var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Worksheet");
// Get data display values
var range = ss.getRange('A:Z');
// Get index of "Referral Date" in headers
var headers = range.getValues()[0];
var columnIndex = headers.indexOf("Referral Date")+1;
// Get today's date
var presentDay = new Date();
// Loop through the dates column
for(var i=1;i<=range.getNumRows();i++){
// Get the value to compare to today
var rowDate = new Date(range.getValues()[i+1][columnIndex]);
if(rowDate.valueOf()>presentDay.valueOf()){
SpreadsheetApp.getUi().alert("Future Date Referral");
}
}
}
Further reading:
Date()
getDisplayValue()
In Google Sheets I have a list of activities with a start date, and a number that specifies the duration in days of that activity. I need to use Google Apps Script to sum those numbers to the date, to obtain the deadline for the activity.
I've tried the solution posted in this question: Adding Days to a Date - Google Script.
The problem with that solution is that the script editor of the spreadsheet doesn't recognize the "Date" Class, so I can't instantiate a Date element.
Summing directly only takes the date and the number as a string.
Trying the method above results in a #NUM! error in the cell I want to convert.
EDIT:
I've tried this, where V3 holds the date I want to sum:
var fecha= new Date (ss.getSheetByName(camada).getRange("V3").getValue());
var fecha2= new Date();
fecha2.setDate(fecha.getDate() + 1);
ss.getSheetByName(camada).getRange("W3").setValue(fecha2);
It apparently works, but the problem is that V3 holds 5/13/2019 and the date returned is 4/14/2019, so it is a day more (13->14) but it is a month less (5->4).
The answer was in Adding Days to a Date - Google Script.
Three things:
don't define fecha2 as new Date(); this gives it no context and instead returns today's date.
let fecha2 be a variable name
the correct statement is var fecha2 = new Date(fecha.setDate(fecha.getDate() + 1));
function so55593876() {
var ss = SpreadsheetApp.getActiveSheet();
var range = ss.getRange("C3");
var value = range.getValue();
Logger.log("DEBUG: Date Range: "+range.getA1Notation()+", Date value: "+value);//DEBUG
var date = new Date(value); // make the sheet value a date object
Logger.log("DEBUG: new date(value) = "+date);//DEBUG
var dateTime = new Date(date.getTime()+1*3600000*24);
Logger.log("DEBUG: Method 1 (add one day = getTime()+1*3600000*24) = "+dateTime);//DEBUG
var dateDate = new Date(date.setDate(date.getDate()+1));
Logger.log('DEBUG: Method 2 (add one day = getdate()+1) = '+dateDate);//DEBUG
ss.getRange("C4").setValue(dateDate);
Logger.log("<<<<<<<<<<<FETCHA>>>>>>>>>>>>>");
var fecha = new Date(value); // make the sheet value a date object
Logger.log("DEBUG: fecha: new date(value) = "+fecha);//DEBUG
var fecha2= new Date(); // note there are no parameters; this will return TODAY's date
Logger.log("DEBUG: fecha2 = "+fecha2);//DEBUG
var fecha3 = fecha2.setDate(fecha.getDate() + 1);
Logger.log("DEBUG: fecha3 = "+fecha3); //DEBUG
var fecha2 = new Date(fecha.setDate(fecha.getDate() + 1));
Logger.log("DEBUG: fecha2 = "+fecha2); //DEBUG
ss.getRange("C5").setValue(fecha2);
}
I have left all the Logger statements in the code so that you can identify the various values at different states of the script.
I'm trying to write a script where the dates in a column are compared against todays date, and if the dates in the column match, an email is sent.
function sendEmails() {
var sheet = SpreadsheetApp.getActiveSheet();
var rotDate = sheet.getRange("F6").getValue();
var today = sheet.getRange("F1").getValue();
//var today = new Date().toLocaleDateString(); // Today's date, without time
var dumpCell = sheet.getRange("J3");
var dumpCell2 = sheet.getRange("J4");
var dumpCell3 = sheet.getRange("J5");
if(rotDate==today) {
//dumpCell is there to dump a value in a cell if the IF statement is true
dumpCell.setValue(rotDate);
MailApp.sendEmail("this is where my email would go", "subject", "body");
}
//these dump the compared vars into cells so they can be checked against one another manually
dumpCell2.setValue(rotDate)
dumpCell3.setValue(today)
}
This is as far as I've gotten. The Values in F6 and F1 are identical, I've typed them out, retyped them, copied and pasted, etc. But for some reason, my if statement just won't run. It behaves as if the two values are different, and I can't work out why.
If I change var rotDate and var today to matching strings, eg "123" then it seems to work as expected.
This is a screenshot of my test data sheet. There are other columns there with other data which were meant to be used for more testing, but I didn't get that far.
Does anyone know what I might be doing wrong?
After trying a variety of approaches, I cracked it using a code snippet from Jon Lin's answer here:
Compare two dates Google apps script
After realizing that the fault was with trying to compare two dates (either a date in an adjacent cell, or a procedurally generated date whenever the function is run, I knew I had to do some better formatting with the data I was intending to compare. This is my repaired code that now works as expected:
function sendEmails() {
var sheet = SpreadsheetApp.getActiveSheet();
var rotDate = sheet.getRange("F6").getValues();
var today = new Date();
//sample values
var sYyyy = Utilities.formatDate(new Date(rotDate), "GMT+8","yyyy");
var sMm = Utilities.formatDate(new Date(rotDate), "GMT+8","MM");
var sDd = Utilities.formatDate(new Date(rotDate), "GMT+8","dd");
//Test Values
var tYyyy = Utilities.formatDate(new Date(today), "GMT+8","yyyy");
var tMm = Utilities.formatDate(new Date(today), "GMT+8","MM");
var tDd = Utilities.formatDate(new Date(today), "GMT+8","dd");
//var rotDate = sheet.getRange("F6").getValue();
//var today = sheet.getRange("F1").getValue();
//var today = new Date().toLocaleDateString(); // Today's date, without time
var dumpCell = sheet.getRange("J3");
var dumpCell2 = sheet.getRange("J4");
var dumpCell3 = sheet.getRange("J5");
if (sYyyy + sMm + sDd == tYyyy + tMm + tDd) {
//if(rotDate===today) {
//dumpCell is there to dump a value in a cell if the IF statement is true
dumpCell.setValue(rotDate);
MailApp.sendEmail("tv18766#gmail.com", "subject", "body");
}
//these dump the compared vars into cells so they can be checked against one another manually
dumpCell2.setValue(rotDate)
dumpCell3.setValue(today)
}