I have some buttons in my spreadsheet that are connected to a time tracker script, which outputs the current time into the appropriate column:
var ss = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
function start() {
ss.getRange(ss.getActiveRange().getRowIndex(), 5).setValue(new Date().toLocaleTimeString());
ss.getRange(ss.getActiveRange().getRowIndex(), 5).setNumberFormat('HH:mm');
}
function stop() {
ss.getRange(ss.getActiveRange().getRowIndex(), 6).setValue(new Date().toLocaleTimeString());
ss.getRange(ss.getActiveRange().getRowIndex(), 6).setNumberFormat('HH:mm');
var newcell = ss.getRange(ss.getActiveRange().getRowIndex()+1, 5);
if (newcell.isBlank()){
ss.setCurrentCell(newcell).activate();
}
else{
ss.insertRowAfter(ss.getActiveRange().getRowIndex());
ss.setCurrentCell(newcell).activate();
};
}
This used to work perfectly and output the time as a number, which I could then format however I needed. I have it written to output the desired format using setNumberFormat('HH:mm'). But just this year after coming back to it after a couple months, it now outputs as text only. For example, instead of outputting 16:00, it outputs 4:00:00 PM as text that I can't work with or use as a reference in a formula. All my formulas calculating total time now give #VALUE!. I have not edited the script at all.
Does anyone know why it's doing this all of a sudden and how I can fix it?
Thanks in advance.
You could try using the options argument from toLocaleTimeString()
Try replacing:
toLocaleTimeString()
With:
toLocaleTimeString("en-US", { hour12: false })
Output:
Reference:
toLocaleTimeString()
Related
I am very new to using google script and is something I have taken interest in recently, with no prior knowledge I have so far been trying to self teach.
I have been playing around with a excel formula that will grab some data from a table on a daily basis and concatenate into a Date and Time format.
So I have the following data in a table:
Event : Time Start : Time End : Location : Description
Work Rota: 24/01/2022 08:30:00 : 24/01/2022 19:30:00 : (postcode) : Work Shift for today
The first row being headers and the 2nd row with the data I am trying to utilise.
The data in the Time Start and Time End column is data using the concatenate formula from another spreadsheet.
If this was not a concatenate formula, the correct Date and Time format for the script works fine, However I understand due to the concatenate formula, the data for the string format is not suitable for the createEvent function.
I have been playing around with google script to find a way to take this data and being able to import it into my google calendar and after struggling now for multiply days! I cannot find a resolution.
Is there a formula or process, that can read the data in column 2 and 3 to convert the data into a suitable format needed for the createevent function
This is the script I have been using.
function addEvents() {
var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("TEST");
var lr = ss.getLastRow();
var cal = CalendarApp.getCalendarById("calendarId");
var data = ss.getRange("A2:E" + lr).getValues();
for (var i = 0;i<data.length;i++){
cal.createEvent(data[i][0], data[i][1], data[i][2], {location: data[i][3], description: data[i][4]});
}
}
I appreciate anyone that may be able to help with this and thank you in advance!
I would have tried:
cal.createEvent(data[i][0], new Date(data[i][1]), new Date(data[i][2]), {location: data[i][3], description: data[i][4]});
}
I'm trying to make a quick macro to grab the current date and time and put it in a cell. I want to make this a static time. I made a quick macro by recording and it works as I recorded it, but when I ran the recorded macro it does nothing. I am just doing a now function and then copying it and pasting the value on top. If I split it into two separate macros, it works. I have no idea what I am doing wrong. Any help is appreciated.
"Timestamp" does not work.
"Now" works.
"copypaste" works.
'''
function TimeStamp() {
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.getCurrentCell().setFormulaR1C1('=now()');
spreadsheet.getActiveRange().copyTo(spreadsheet.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
};
function Now() {
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.getCurrentCell().setFormulaR1C1('=now()');
};
function copypaste() {
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.getActiveRange().copyTo(spreadsheet.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
};
'''
You may use date object to return timestamp compared with using =now formula, which is faster and prevent script to skip your next line:
function TimeStamp() {
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.getCurrentCell().setValue(new Date());
};
Reference
Get today date in google appScript
Edit: Original issue
In the original script, the script might not apply the changes after setting the formula =now() and before copy/paste, since spreadsheet operations are sometimes bundled together to improve performance. So it's treating the active range as empty, and after pasting this empty value, the cell will remain empty.
To avoid that, you could have used SpreadsheetApp.flush() after setting the formula =now().
I have a google sheet form response data where column B is a time duration value. But it shows time in AM or PM. I tried different app script but still unable to get the value a time Delta( difference) format
The form response data itself gives time in AM or PM. Help me in this matter.
This is my latest code.
function timeFormat() {
var cell = SpreadsheetApp.getActive().getSheetByName('Sheet4').getRange('B1:B');
cell.setNumberFormat('hh:mm');
}
Is your issue basically with the AM / PM part popping up when you click into the cells formatted as 'hh:mm'? You can fix that by applying the duration format for hours to the entire range (e.g. B2:B)
GAS:
range.setNumberFormat('[hh]:mm');
Or manually under Format -> Number -> More Formats -> Custom number format (a lot easier)
And here's how the end result looks like. Note that you get the 'AM/PM' part popping up when you click into cells formatted as 'hh:mm' but not with the ones formatted as [hh]:mm:
You could use this function as a cell function and then format the cells as a duration and you will get hours:minutes:seconds.
function days(Start,End) {
if(Start && End)
{
var second=1000;
var minute=60*second;
var hour=minute*60;
var day=hour*24;
var t1=new Date(Start).valueOf();
var t2=new Date(End).valueOf();
var d=t2-t1;
return d/day;
}
else
{
return 'Invalid Inputs';
}
}
This essentially returns the date number in the form that the spreadsheet understands as days and fraction of days.
It's hours I'm struggling to know why I don't get correct timeZone using this script !
I've used moment.js and moment-timezone and followed instruction explained here:
Timezone conversion in a Google spreadsheet
google-spreadsheet/40324587
I am trying to convert timezones usign following script:
var DT_FORMAT = 'YYYY-MM-DD HH:mm:ss';
function fromUtc(dateTime, timeZone) {
var from = m.moment.utc(dateTime,
DT_FORMAT);//https://momentjs.com/timezone/docs/#/using-
timezones/parsing-in-zone/
return from.tz(timeZone).format(DT_FORMAT);
}
function toUtc(dateTime, timeZone) {
var from = m.moment.tz(dateTime, DT_FORMAT,
timeZone);//https://momentjs.com/timezone/docs/#/using-timezones/parsing-
in-zone/
return from.utc().format(DT_FORMAT);
}
function myFunction(datetimeString,timeZone,format) {
var moment = new Date(datetimeString);
return Utilities.formatDate(moment, timeZone, format)
}
In my spreadsheet, the first column is date and time in standard GMT and I'm going to change date and time to different TimeZones which I wrote in next columns. Even-though I'm getting the date and time, but it is incorrect and I don't know how to fix it.
Here is the link to Google sheet:
https://docs.google.com/spreadsheets/d/1Tc0G2daX9FYIL354iyOffd06BtNPx5v-40KE5RtwDB4/edit?usp=sharing
and here is the link to my script app:
https://script.google.com/d/1u54McW1HBm-A2alno1DWWTFwk-vdok8ljwKfI_5htAHK-XrMt554YGLn/edit?usp=sharing
Update (replying to comment) :
I use the function like this, I write in in a cell in spreadsheet:
=fromUtc(A2, D1)
I am trying to create a recurring event in a Google Calendar but I keep getting the following error: Cannot convert Array to (class)[]
The problem lies in that I am trying to grab data from a cell to fill in the class. The code is the following:
var recur4 = CalendarApp.newRecurrence().addWeeklyRule().onlyOnWeeks([rep]);
var ne4 = c.createAllDayEventSeries(title, start, recur4, options);
Now, the variable rep is equal to cell H2 which has the following text in it: 31,36
When I put Logger.log(rep); it outputs 31,36 so there is no problem there either.
When I take out rep and put in 31,36 in the brackets, the script works perfectly and adds the events to the calendar, so I know that the problem is not anywhere else in the script.
I suppose that the problem has to do with the formatting in the cell, but I have no idea. Any help would be appreciated.
UPDATE
OK so based on the comment below, I changed the script to the following:
var sp = rep.split(",");
for(var i=0; i<sp.length; i++) { sp[i] = +sp[i]; }
var recur4 = CalendarApp.newRecurrence().addWeeklyRule().onlyOnWeeks(sp);
var ne4 = c.createAllDayEventSeries(title, start, recur4, options);
This got rid of the error, BUT now it is adding events every Friday. In the debugger, it now shows that the array is an integer array and comes out like this: [31,36] which should represent the two weeks I need, but something still does not work and the recur4 remains as undefined instead of an object.
UPDATE
Based on the comments that people gave below, the final script that worked fine was the following:
var recur4 = CalendarApp.newRecurrence().addYearlyRule().onlyOnWeeks(rep.split(",")).onlyOnWeekday(CalendarApp.Weekday.FRIDAY);
var ne4 = c.createEventSeries(title, start, stop, recur4, options);
The issue you have with your EventRecurrence specification is that you are specifying that this event should repeat weekly, but then use a restriction that is incompatible with a weekly restriction.
If you describe your condition with words, note that you cannot avoid saying "year". This is a strong indication that perhaps your recurrence period is incorrect.
E.g. "repeat this event every week, on weeks 31 and 36 of the year" vs. "repeat this event every year, on weeks 31 and 36"
Indeed, changing your restriction from weekly to yearly results in a valid RecurrenceRule:
var recur = CalendarApp.newRecurrence()
.addYearlyRule()
.onlyOnWeeks(rep.split(",").map(
function (week) {
return parseInt(week, 10);
})
);
References:
onlyOnWeeks
addYearlyRule
PS: the EventRecurrence and RecurrenceRule classes are pretty much interchangeable.