I realize this is likely very easy but I'm a struggling newbie. I have dates in spreadsheet cells D3, D4, and D5 (mm/dd/yyyy) and simply need a macro to add 7 days to each of them. I've managed to mangle together some code that may be working but the output is in milliseconds rather than mm/dd/yyyy format.
I can't seem to get the syntax right to convert it. Any hints? Thank you!
function UpdateDates() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var First = new Date();
var Second = new Date();
var Third = new Date();
var First = ss.getRange('D3').getValue();
var Second = ss.getRange('D4').getValue();
var Third = ss.getRange('D5').getValue();
ss.getRange('D3').setValue(First.getTime() + 7);
ss.getRange('D4').setValue(Second.getTime() + 7);
ss.getRange('D5').setValue(Third.getTime() + 7);
}
Adding days to date provides a unique challenge mainly because you have to take care of year, month and date. And increment each accordingly, hence just using getDate() doesn't work. You will need to keep track of the month and year. So as to change them if adding the seven days change the month or the year.
However, by using getTime() you can get the measure of time in milliseconds since Jan 1, 1970. And, add 7 days in milliseconds and convert it back to a date using new Date() constructor. Thus the constructor would take of figuring out the correct date based on the time.
Your code will look like so:
function UpdateDates() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
//Get the dates from the cell and convert them into Milliseconds since 1970/01/01
var First = new Date(ss.getRange('D3').getValue()).getTime();
var Second = new Date(ss.getRange('D4').getValue()).getTime()
var Third = new Date(ss.getRange('D5').getValue()).getTime();
var dayInMs = 24*60*60*1000 //one day in Milliseconds
//add sevendays to each date in milliseconds
First = First + (7*dayInMs)
Second += (7*dayInMs)
Third += (7*dayInMs)
//Convert Milliseconds to date use new Date(time in ms) and set Values of the cell
ss.getRange('D3').setValue(new Date(First));
ss.getRange('D4').setValue(new Date(Second));
ss.getRange('D5').setValue(new Date(Third));
}
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 have a script that checks each cell in a specific column, then gets me the value and stores it to a variable. The cells in that column all have different dates in this format. 9/9/2020
I'm trying to figure out how to create another variable that subtracts 7 days from the given date.
Can someone help me with creating a variable that subtracts 7 days from the date grabbed by the "start_date" variable.
Example:
var sss = SpreadsheetApp.openById('1rIK-TunX1lBlFzndk5L4ExdLQO1GQLwlH-1viZzFZU0');
var ss = sss.getSheetByName('Form Responses 1');
function test() {
var lr = ss.getLastRow()
for (var i = 2;i<=lr;i++){
var start_date = ss.getRange(i,13).getValue();
var minus7days = ??
}}
Any help would be greatly appreciated!!
Working with date objects
When performing calculations with date objects, the best is to convert them to milliseconds.
This can be done e.g. with getTime()
After the calculation you can transform the milliseconds back to a date object with new Date()
Sample Code snippet:
var ms = start_date.getTime();
var sevenDays = 7*24*60*60*1000;
var minus7daysMs = ms - sevenDays;
var minus7days = new Date(minus7daysMs);
Another way to do the same is through setDate, which sets the day of month:
//simulate getValue
const start_date = new Date("2020-9-9");
const minus7date = new Date(start_date);
minus7date.setDate(start_date.getDate()-7);
console.info({start_date,minus7date});
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.
How to put in a Cell the number of days pass from a specific date. For example:
Column1: 12/05/2013 18:00:00 Actual Days using Function New Date() Column2: The script will insert the numbers of days (Today - Column1) = 4
The script should be insert in the column 2 the number of days pass from today. Today is 16/05/2013 23:00, the script will insert 4. If possible due this?
I'll appreciate if you can help me.
That function was passed by friend but I think doesn't work because the date is not in milliseconds but the result in the cell should be number of days
}
function formatting2(event) {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet(); // get the sheet
var columnF = sheet.getRange(2, 1, sheet.getLastRow()-1, 1);
var updateage = sheet.getRange(2, 2, sheet.getLastRow()-1, 1);
var fValues = columnF.getValues(); // get the values
var result = new Date();
updateage.setValue(result-fValues)
}
This is a possible way to get the result you want, I wrote it as a custom function, ie you have to put it in the the cell where you want it to appear in the form =dayToToday()
here is the script with a few logs and comments to show intermediate values.
function dayToToday(x){
var sh = SpreadsheetApp.getActiveSheet();
Logger.log(sh.getActiveCell().getRowIndex())
var refcell = sh.getRange(sh.getActiveCell().getRowIndex(),1).getValue();;// get value in column A to get the reference date
var refTime = new Date(refcell);
var ref = refTime.setHours(0,0,0,0)/(24*3600000);// set hours, minutes, seconds and milliseconds to 0 if necessary and get number of days
var today = new Date();
var TD = today.setHours(0,0,0,0)/(24*3600000);// set hours, minutes, seconds and milliseconds to 0 if necessary and get number of days
var day = parseInt(TD-ref);// get the difference in days (integer value )
return day ; // return result that will be in cell
}
EDIT :
if I understand your use case I suggest you abandon the custom function aproach (that I never use since I don't like it so much) and go for this solution that uses a timer trigger and/or a menu to update values in your spreadsheet in one batch.
(ps : sorry for not having answer quickly enough... too busy these days :-)
function onOpen() {
var menuEntries = [ {name: "test function", functionName: "toTrigger"},
];
var ss = SpreadsheetApp.getActiveSpreadsheet();
ss.addMenu("test menu",menuEntries);//
}
// create a timer trigger that will call "toTrigger" every 15 minutes
function toTrigger(){
var sh = SpreadsheetApp.getActiveSheet();
var data = sh.getRange(1,1,sh.getLastRow(),2).getValues();
for(var n=0;n<data.length;++n){
if(typeof(data[n][0])=='object'){
data[n][1]=dayToToday(data[n][0])
}
}
sh.getRange(1,1,sh.getLastRow(),2).setValues(data)
}
function dayToToday(x){
var refcell = x;;// get value in column A to get the reference date
var refTime = new Date(refcell);
var ref = refTime.setHours(0,0,0,0)/(24*3600000);// set hours, minutes, seconds and milliseconds to 0 if necessary and get number of days
var today = new Date();
var TD = today.setHours(0,0,0,0)/(24*3600000);// set hours, minutes, seconds and milliseconds to 0 if necessary and get number of days
var day = parseInt(TD-ref);// get the difference in days (integer value )
return day ; // return result that will be in cell
}
second EDIT:
when using var data = sh.getRange(1,1,sh.getLastRow(),2).getValues();
the numbers in getRange are start row, start column, number of Rows, number of Columns so you'll have to gat a range that includes the columns you want and then use data [n][columnNumber-1] to get the corresponding value. (-1 because array start from 0 and columns count from 1 (A in fact but A is first column ;-))
if you need a variable reference then let me know because the function must be modified to accept 2 variables (a ref and another one).
LAST EDIT (I hope)
I changed some details... see [9] and [5] index corresponding to J and F
function toTrigger(){
var sh = SpreadsheetApp.getActiveSheet();
var data = sh.getRange(1,1,sh.getLastRow(),sh.getLastColumn()).getValues();
for(var n=0;n<data.length;++n){
if(typeof(data[n][9])=='object'){
data[n][5]=dayToToday(data[n][9])
}
}
sh.getRange(1,1,data.length,data[0].length).setValues(data)
}
update/edit
result in hours (following request in comments)
function hoursToToday(x){
var refcell = x;;// get value in column A to get the reference date
var refTime = new Date(refcell);
var refhrs = refTime.getHours();
var ref = refTime.setHours(refhrs,0,0,0)/3600000;// set hours, minutes, seconds and milliseconds to 0 if necessary and get number of days
var today = new Date();
var todayHrs = today.getHours()
var TD = today.setHours(todayHrs,0,0,0)/3600000;// set hours, minutes, seconds and milliseconds to 0 if necessary and get number of days
var hrs = TD-ref;// get the difference in days (integer value )
return hrs ; // return result that will be in cell
}