Cannot find function getTime() in object - google-apps-script

I am trying to compare two dates in Google Docs using Apps script. My dates are formatted m/d/yyyy h:mm:ss. I keep getting an error saying "Cannot find function getTime in object 2/1/2013 9:42:46." Is there a problem with the way my dates are formatted? I've used this before successfully for dates that are formatted mm/dd/yyyy, and am not sure why adding the timestamp would make a difference. Any help would be greatly appreciated!
for (var i = 0; i < kValues.length; i++) { // repeat loop
if (kValues[i][0] == "") {var lastupdate = parseInt(new Date("1/1/1980 00:00:00").getTime()/day); } // if a date doesn't exist, throw it back in the past
if (kValues[i][0] != ""){
var lastupdate = parseInt(kValues[i][0].getTime()/day);} // if a date does exist, interpret it. Here's where I'm getting my error.
var statusDateChange = parseInt(statusDate[i][0].getTime()/day); // interpret a date from Sheet 2
var statusChange = changeStatus[i][0]; //find the new status
var currentStatus = status[i][0]; //find the old status
var currentOID = oid[i][0]; // set Order ID
var changeOID = statusOID[i][0]; // set Order ID in Sheet 2 to compare
Logger.log(lastupdate + "<=" + statusDateChange);
if (lastupdate <= statusDateChange && currentOID == changeOID && statusChange != currentStatus) {sheet.getRange(i + 2, 8, 1, 1).setValues(statusChange); // if the date in Sheet 1 is less than the date in Sheet 2 and the ID matches, change the status
}
}

is there really a dot at the end of the string or is ot a typo ? 2/1/2013 9:42:46.
This might be the issue, you can test it like this :
Logger.log(new Date("2/1/2013 9:42:46."))
Logger.log(new Date("2/1/2013 9:42:46"))
returns
Wed Dec 31 16:00:00 PST 1969
Fri Feb 01 00:42:46 PST 2013
the first value being equivalent to Logger.log(new Date(null)) and returns the JS ref date.

Related

Trying to get date format in Google Sheets to display as 1st, 2nd, 3rd etc with the relevant suffix using google scripts editor

I am trying to get the date format currently displaying as Monday 25 # 7:30 PM but I would like it to display showing the relevant suffix i.e. 'th' or 'st' or 'nd' i.e. 4th, 1st, 2nd etc.
I am using the code below but getting the error message "Exception: Invalid argument: date. Should be of type: Date" any ideas? Much apprecitated
function getOrdinal(date) {
var d = new Date(),
suffix = ['th', 'st', 'nd', 'rd'][(d > 3 && d < 21) || d % 10 > 3 ? 0 : d % 10];
return Utilities.formatDate(date, Session.getScriptTimeZone(), "d'" + suffix + "MMMM, yyyy");
}
Explanation:
Your goal is to convert the date in the sheet to Monday 25th January 2021.
You can use your current solution to obtain 25th and then use Utilities.formatDate to obtain day, month and year.
Template literals were used to concatenate the resulting string.
Code snippet:
Execute myFunction to paste the new format in column M assuming the data input is in column L (see screenshot):
function myFunction(){
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName('Sheet1'); // put the name of your sheet
const dts = sh.getRange('L1:L6').getValues().flat();
const new_dts = dts.map(c=>[getOrdinal(c)]);
sh.getRange(1,13,new_dts.length,1).setValues(new_dts);
}
function getOrdinal(input) {
const dt = new Date(input);
const d = dt.getDate();
const suffix = ['th', 'st', 'nd', 'rd'][(d > 3 && d < 21) || d % 10 > 3 ? 0 : d % 10];
const dayN = Utilities.formatDate(dt, Session.getScriptTimeZone(), "EEEE");
const ds = d+suffix;
const rd = Utilities.formatDate(dt, Session.getScriptTimeZone(), "MMMM yyyy");
return `${dayN} ${ds} ${rd}`;
}
Example sheet of code snippet:

Calculate time based on business working hours

Add numbers of hours to a timestamp and make sure that the output is within working hours.
For example:
Open Time -> 9:00 AM
Close Time -> 6:00 PM
First Date -> 12/1/2020 12:00 PM
Add Time -> 7 hours
Result -> 13/1/2020 10:00 AM
I am trying to achieve this using GAS ES5/ES6
Already tried a formula which is very close to this logic:
Cell A7 = First Date
Cell G5 = Add Time
Cell B1 = 9/24-18/24
Sheet2!A:A = List of Holidays to Skip
0000011 = Skips Saturday and Sunday
=if(A7,if(and(hour(A7+G$5)>9,(hour(A7+G$5)<18)),A7+G$5,workday.intl(int(A7+G$5+$B$1),1,"0000011",Sheet2!A:A)+hour(A7+G$5+$B$1)/24),"")
I think you are looking for this:
function myFunction() {
var open_h = 9 // 24h
var close_h = 18 //24h
var add_h = 7 // number of hours
var d = new Date();
d.setDate(d.getDate() + (1 + 7 - d.getDay()) % 7);
next_Monday = d.getDate()
var first_date = new Date() ;
var end_date = new Date();
end_date.setTime(end_date.getTime() + (add_h*60*60*1000))
if (end_date.getDate()>first_date.getDate()){
end_date.setDate((new Date()).getDate());
end_date.setHours(23, 0 , 0);
}
if (end_date.getHours()>=close_h){
if (end_date.getDay() == 5 || end_date.getDay() == 6 || end_date.getDay() == 0 ) {end_date.setDate(next_Monday) }
else {end_date.setDate(end_date.getDate() + 1)} // tomorrow
var end_time = end_date.getHours()-close_h + open_h
end_date.setHours(end_time, 0, 0);
}
Logger.log(end_date)
} // end function
end_date will give you the desired result.
Edit: it also takes weekends into consideration.

How to deal with duplicates in google sheets script?

So in the project I want to do I have a google sheet with timestamps and names next to those timestamps in the spreadsheet. I am having trouble accounting for duplicates and giving the name multiple timestamps in another google sheet.
for(var i = 0; i < length; i++){//for loop 1
if(currentCell.isBlank()){//current cell is blank
daySheet.getRange(i+10, 2).setValue(fullName);//set name to first cell
daySheet.getRange(i+10,3).setValue(pI);
daySheet.getRange(i+10,day+3).setValue(1);
}else if(counter > 1 ){//the index of the duplicate in the sheet month
//if counter is > 1 then write duplicates
for(var t = 1; t <= sheetLength ; t++){//loop through sign in sheet
//current index i
if(signInLN == signInSheet.getRange(t+1,3).getValue()){
//if there is a match
daySheet.getRange(t+10,day+3).setValue(1);
//day is equal to the day I spliced from the timestamp
//at this point I am confused on how to get the second date that has the same
//name and add to the row with the original name.
//when i splice the timestamp based on the row of index i, with duplicates I get
//the day number from the first instance where the name is read
}
}
}//for loop 1
How can I get this to work with duplicates so I can account for the dates but make sure that if there are
any duplicates they will be added to the row of the original name
Google Sheet EX:
12/10/2020 test1
12/11/202 test2
12/15/2020 test1
Should be something like this:
name 10 11 12 13 14 15 16
test1 1 1
test2 1
//the one is to identify that the date is when the user signed in on the sheets.
Sample Spreadsheet:
Code snippet done with Apps Script, adapt it to your needs.
use Logger.log() in case you don't understand parts of code
It is done mainly with functional JavaScript
function main(){
var inputRange = "A2:B";
var sheet = SpreadsheetApp.getActive().getSheets()[0]
var input = sheet.getRange(inputRange).getValues(); //Read data into array
var minDate, maxDate;
var presentDates = input.map(function(row) {return row[0];}); //Turns input into an array of only the element 0 (the date)
minDate = presentDates.reduce(function(a,b) { return a<b?a:b}); //For each value, if its the smallest: keep; otherwise: skip;
maxDate = presentDates.reduce(function(a,b) { return a>b?a:b}); //Same as above, but largest.
var dates = [];
for (var currentDate = minDate; currentDate <= maxDate; currentDate.setDate(currentDate.getDate()+1)) {
dates.push(getFormattedDate(currentDate)); //Insert each unique date from minDate to maxDate (to leave no gaps)
}
var uniqueNames = input.map(function(row) {return row[1];}) //Turns input into an array of only the element at 1 (the names)
.filter(function (value, index, self) {return self.indexOf(value) === index;}); //Removes duplicates from the array (Remove the element if the first appearence of it on the array is not the current element's index)
var output = {}; //Temporary dictionary for easier counting later on.
for (var i=0; i< dates.length; i++) {
var dateKey = dates[i];
for (var userIndex = 0; userIndex <= uniqueNames.length; userIndex++) {
var mapKey = uniqueNames[userIndex]+dateKey; //Match each name with each date
input.map(function(row) {return row[1]+getFormattedDate(row[0])}) //Translate input into name + date (for easier filtering)
.filter(function (row) {return row === mapKey}) //Grab all instances where the same date as dateKey is present for the current name
.forEach(function(row){output[mapKey] = (output[mapKey]||0) + 1;}); //Count them.
}
}
var toInsert = []; //Array that will be outputted into sheets
var firstLine = ['names X Dates'].concat(dates); //Initialize with header (first element is hard-coded)
toInsert.push(firstLine); //Insert header line into output.
uniqueNames.forEach(function(name) {
var newLine = [name];
for (var i=0; i< dates.length; i++) { //For each name + date combination, insert the value from the output dictionary.
var currentDate = dates[i];
newLine.push(output[name+currentDate]||0);
}
toInsert.push(newLine); //Insert into the output.
});
sheet.getRange(1, 5, toInsert.length, toInsert[0].length).setValues(toInsert); //Write the output to the sheet
}
// Returns a date in the format MM/dd/YYYY
function getFormattedDate(date) {
var year = date.getFullYear();
var month = (1 + date.getMonth()).toString();
month = month.length > 1 ? month : '0' + month;
var day = date.getDate().toString();
day = day.length > 1 ? day : '0' + day;
return month + '/' + day + '/' + year;
}
Run script results:

Find and match a date in array

I'm trying to make a function in order to find & match the date of day in a array.
But for a weird reason, if two dates are matching, my function never find the match.
So..., if I change my date by an other string (ex : "foo" match with "foo"), it's work.
Here my code, and then the log return. Have you an idea why my script can't match two equal dates ?
Thank you !
function hideBeforeToday(values, value)
{
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = SpreadsheetApp.setActiveSheet(ss.getSheetByName(roadmapSS))
var range = sheet.getRange(4, 11, 1, sheet.getLastColumn())
var values = range.getValues();
Logger.log(values);
var value = moment().set({hour:0,minute:0,second:0,millisecond:0}).utc().toDate();
Logger.log("date", value);
for(var i = 0; i < values.length; i++) {
if(values[i].indexOf(value) > -1) {
Logger.log("data found");
}
}
}
[18-01-11 13:49:33:065 CET] Logger.log([arrayValues, [[[Wed Jan 10 00:00:00 GMT+01:00 2018, Thu Jan 11 00:00:00 GMT+01:00 2018]]]]) [0 secondes]
[18-01-11 13:49:33:067 CET] Logger.log([dateOfDay, [Thu Jan 11 00:00:00 GMT+01:00 2018]]) [0 secondes]
[18-01-11 13:49:33:070 CET] Script exécuté [durée totale d'exécution : 0,535 secondes]
Look at this example:
var date1 = new Date("Thu Jan 11 00:00:00 GMT+01:00 2018");
var dates = [date1];
console.log(date1); // prints 2018-01-10T23:00:00.000Z
console.log(dates.indexOf(date1)); // prints 0
While this:
var date1 = new Date("Thu Jan 11 00:00:00 GMT+01:00 2018");
var dates = [new Date("Thu Jan 11 00:00:00 GMT+01:00 2018")];
console.log(date1); // prints 2018-01-10T23:00:00.000Z
console.log(dates.indexOf(date1)); // prints -1
I don't know what data you have in the spreadsheet, if it is a string or a Date object, but try converting both to the same type before comparing. Check their types and perhaps use the toISOString() function?

automatically update age

I got a website with an about section. there is some text about me including my current age. Lazy as I am I don't want to change that date after every birthday.
Is there an easy script to display my age based on my birthdate? I didn't find anything like that on the web.
Thx ahead.
You can do it in javascript. This should be more than enough to get you started..
// The date you were born
var birthDate = new Date(1990, 6, 19, 0, 0, 0, 0);
// The current date
var currentDate = new Date();
// The age in years
var age = currentDate.getFullYear() - birthDate.getFullYear();
// Compare the months
var month = currentDate.getMonth() - birthDate.getMonth();
// Compare the days
var day = currentDate.getDate() - birthDate.getDate();
// If the date has already happened this year
if ( month < 0 || month == 0 && day < 0 )
{
age--;
}
alert( age );