Getting substrings of each Array-Element - javascript

I am trying to convert data stored in "dd.mm.yy" format to "w" format in Google Sheets/Appscript. Unfortunately I cannot use the ".formatDate()" function since sheets does not recognice the input values as date values, so I tried the following:
function CheckWeekNuber() {
var dateStr =SpreadsheetApp.getActiveSpreadsheet().getSheetByName("INSERT RAW DATA HERE").getRange(3,5,300,4).getValues();
var day = dateStr.substring(0,2);
var month = dateStr.substring(3,5);
var year = "20"+dateStr.substring(6,8);
var weekNumb = Utilities.formatDate(new Date(year, month-1, day), "GMT", "w");
SpreadsheetApp.getActiveSpreadsheet().getSheetByName("WEEKNUMBERS").getRange(3,5,300,4).setValues(weekNumb);
}
It worked perfectly with a foor loop, converting each single value at a time. But it was super slow. My problem lays in using the ".substring()" formula for arrays, it does not seem to work..
Do you have any idea how to fix it?

The use of substring() is not possible when applying directly to an array. Looping the only way in getting the substring() of each element on an array.
Suggestion
If you are open to changing the data in your sheet, you can try using createTextFinder(".").replaceAllWithText("/") on your data range to convert your data to date format. Once you have this, you will still loop into your new data to get the week number of each date. Code is as follows and this is working on my end:
function CheckWeekNuber() {
var range = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("INSERT RAW DATA HERE").getRange(3,5,300,4);
range.createTextFinder(".").replaceAllWith("/") // converts str date to date format
var dateFormat = range.getValues();
var lastRow = range.getLastRow();
var lastCol = range.getLastColumn();
var weekNumb = [];
for(var row in dateFormat){
for(var column in dateFormat[row]){
dateFormat[row][column] = Utilities.formatDate(new Date(dateFormat[row][column]), "GMT", "w");
}
}
SpreadsheetApp.getActiveSpreadsheet().getSheetByName("WEEKNUMBERS").getRange(3,5,300,4).setValues(dateFormat);
}

Related

Convert UTC ISO value to `String` (Text)

Objective: I need to convert a UTC value (col A) to a String before passing it to a function for local time zone conversion.
Errors: no errors, script runs successfully
Issue: Time is not converted to specified time zone
Further info:
If I use the following in my LOCALTIME function, the date is converted correctly.
var originalDate = new Date("2020-05-12T23:22:46.120Z");
Function to get the time in UTC (col A):
function getAllEmailAndDiningPreferences(changeType){
var orders = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Orders');
var ordersData = orders.getDataRange().getValues();
var lr = getLastRow(orders, "A1:E");
for (var i=0; i<lr; i++){
if(ordersData[i][1].length == 0){
var orderId = ordersData[i][0]; //note: need to convert 'orderId' to a String
var email = getEmailFromOrderedId(orderId.toString()); //toString() doesn't convert it to a expected String
convertOrderDateToLocalTimeZone(i+1, orderId);
i+1;
}
}
}
Function to convert to locatime zone:
function LOCALTIME(datetimeString) {
if (datetimeString.map) {
return datetimeString.map(LOCALTIME);
} else {
var originalDate = new Date(datetimeString);
return Utilities.formatDate(originalDate, "Australia/Adelaide", "yyyy-MM-dd'T'HH:mm:ss'Z'")
}
}
Answer:
Due to Sheet locale, you need to get the display value of the cell before making a date object so that the Script project reads it correctly as UTC.
More Information:
getDisplayValues() will literally get the values of the cells as you see them in the UI. As a result, as the strings are inputted in UTC, you can bypass the conversion to your local time zone by calling for the displayed datetime rather than the stored one:
Code Example:
function dateConvert() {
var d = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange("A2").getDisplayValue();
var dateObj = new Date(d);
var newDate = Utilities.formatDate(dateObj, "Australia/Adelaide", "yyyy-MM-dd'T'HH:mm:ss'Z'")
Logger.log(newDate);
}
In this case, newDate will be converted to the Australia/Adelaide timezone.
There is also the .getDisplayValues() method, which works in the same way only over a range of values rather than just a single cell.
References:
Class Range - getDisplayValue() | Apps Script | Google Developers

Google sheets dates, stored as strings by toString(), are not recognized as dates when written back into a cell?

I have a sheet that adds several thousand values per day. To keep it small and nimble, it regularly stores rows of data as comma separated values on a separate sheet. I loop through each row using toString() on all the cells.
When retrieving and reprinting the needed data to a new sheet, the sheets do not recognize the strings as dates.
e.g. Fri Mar 29 2019 13:45:06 GMT-0700 (PDT)
My workaround is slicing the strings when retrieving them, I am just wondering why they don't recognize the standard date strings as dates.
function compressData() {
var sheet = SpreadsheetApp.getActiveSheet();
var arr = sheet.getRange(1,1,2,2).getValues();
var arrNew = [];
var arrRow =[];
var arrExpanded;
for (var i in arr) {
for (var x in arr[i]) {
arrRow.push(arr[x][i]);
}
arrNew.push([arrRow[i].toString()]);
}
// stores each row of the original array as a
// comma separated string in a new array
sheet.getRange(1, 3, arrNew.length, arrNew[0].length).setValues(arrNew);
// writes the new array to a new range
}
function expandData(){
// prints the arrays onto a new range and the new date
// cell isn't recognized as a date
var arrExpanded = [];
var sheet = SpreadsheetApp.getActiveSheet();
var arrCompressed = sheet.getRange(1,3,2,1).getValues();
for (var i in arrCompressed) {
var arrTemp = arrCompressed.toString().split(',');
arrExpanded.push(arrTemp);
}
// rebuilds the 2d array
sheet.getRange(1, 4, arrExpanded.length, arrExpanded[0].length).setValues(arrExpanded);
}
You extract date values from a string, and are wondering why Google Sheets doesn't recognize the standard date strings as dates.
The reason is that the date that you see on-screen is actually a number, milliseconds from the Unix epoch. It is merely formatted to display so that it "looks like" a date consisting of text.
To convert a date string to a value that Google Sheets will recognise as a date, you need to convert it. The following code provides a simple example:
In the screenshot below, the value in Cell B1 is a string; the value is cell C1 is a date value. Note the actual data value (number) displayed in cell C5 (this cell is formatted as 'Number');
function so5842277201() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheetname = "Sheet1";
var sheet = ss.getSheetByName(sheetname);
var datestring = sheet.getRange("A1").getValue();
Logger.log(datestring);
var date01 = new Date(datestring);
Logger.log(date01);
var date02 = Utilities.formatDate(date01,"GMT-7", "EEE MMM d yyyy HH:mm:ss");
var newdaterange = sheet.getRange("C1");
newdaterange.setValue(date02);
}
Screenshot

Conversion of Date to UNIX Timestamp

I have a JavaScript function running in Google Drive folder of many spreadsheets that is currently logging dates into the log;
function convertDates(){
var ui = SpreadsheetApp.getUi();
SpreadsheetApp.getActiveSpreadsheet().toast('Conversion Started With First Row Date Cells','Conversion', 5);
Logger.log('Date Conversion Started');
var activeCell = SpreadsheetApp.getActiveSpreadsheet().getActiveCell();
var cell = activeCell.getValue();
Logger.log(cell);
}
How would one convert the output of 'cell' which currently looks like:
May 03, 2014 at 05:19PM
Into a Unix Time stamp within Javascript? I am inclined to believe that this can involve the Date() function but am unsure.
Thank's in Advance.
You can do this way to remove "at" and the sheet then recognizes the value as a valid date.
function convertDates(){
var sheet = SpreadsheetApp.getActiveSheet();
var range_input = sheet.getRange(1, 1);
range_input = range_input.getValue();
range_input = range_input.replace("at ", " ");
sheet.getRange(1, 1).setValue(range_input);
}
I am just replacing for one single cell. You can loop that to all the needed cell values.
Hope that helps!
If you want the get a string representation of the number of seconds since the UNIX epoch (january 1, 1970) you can use a code like this :
function convertDates(){
var ui = SpreadsheetApp.getUi();
SpreadsheetApp.getActiveSpreadsheet().toast('Conversion Started With First Row Date Cells','Conversion', 5);
Logger.log('Date Conversion Started');
var activeCell = SpreadsheetApp.getActiveSpreadsheet().getActiveCell();
var unixEpoch = new Date(1970,0,1,0,0,0).getTime();// difference between JS epoch and UNIX epoch in milliseconds
var cell = ((activeCell.getValue().getTime()-unixEpoch)/1000).toString();
Logger.log(cell);
activeCell.setValue(cell);// this will write it back to the sheet... be careful, it is not a date object anymore but a string... so the code won't work after that.
}
You have to remove "at" and to add a space after "05:19".
Look like this :
var date = new Date("May 03, 2014 05:19 PM");

concatenate date and time in google spreadsheet

I have a script that imports events from spreadsheets into calendar:
function caltest1() {
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 2; // First row of data to process
var numRows = 3; // Number of rows to process
var dataRange = sheet.getRange(startRow, 1, numRows, 5);
var data = dataRange.getValues();
var cal = CalendarApp.getDefaultCalendar();
for (i in data) {
var row = data[i];
var title = row[0]; // First column
var desc = row[1]; // Second column
var tstart = row[2];
var tstop = row[3];
var loc = row[4];
//cal.createEvent(title, new Date("March 3, 2010 08:00:00"), new Date("March 3, 2010 09:00:00"), {description:desc,location:loc});
cal.createEvent(title, tstart, tstop, {description:desc,location:loc});
}
}
The script works fine if my spreadsheet contains the data like:
Title Description Start Stop Channel
Mr Dear no drinks 5/6/2014 20:55:00 5/6/2014 21:57:00 what ever
But it does not work if I create my own date =CONCATENATE($D4, " ",$G4), given that D4 has a date and G4 has time combined into a single cell Date and time. I figured because it senses that concatenate creates a plain text and not a time formatting, but how can I fix it?
In spreadsheets, dates have a native value of an integer representing the number of days since december 31 1899 and time is a decimal value which is the fraction of a day ( 6 hours = 1/4 of a day for example , 0.25 day).
So when you add DATE+TIME (integer+decimal) in a spreadsheet you get a full date with time .
So the answer (as you noticed it in your comment on the other answer) is logically to ADD both values. That's actually the reason spreadsheets are build like that ! (to make it easy to use date and time)
Use the formula =D2+E2 in a new column and you get a complete date object directly useable in JavaScript.
In Javascript date and time are the same objects, there is no time object that has no date and no date without time : their native values are milliseconds counted from January 1 1970 at midnight (which is an integer).
Since the type of concatenated strings is text, you can convert them to date before calling the Calendar methods.
var tstart = new Date(row[2]);
var tstop = new Date(row[3]);
I successfully concatenated date and time by using
=text(A2,"dd/mm/yy") & ", " & text(B2,"HH:MM")
I concatenated date and time

how to compare the date in xml row with today's date

I have one xml file which is retrieved using jquery in sharepoint. One of the row of the xml is like below.
<z:row ows_Title='Have dinner party with Host' ows_Due_x0020_Date='2012-05-10 00:00:00' ows_MetaInfo='1;#' ows__ModerationStatus='0' ows__Level='1' ows_ID='1' ows_UniqueId='1;#{2A8F277A-C95B-420C-89A9-3B979F95C8F4}' ows_owshiddenversion='3' ows_FSObjType='1;#0' ows_Created='2012-10-25 03:19:35' ows_PermMask='0x7fffffffffffffff' ows_Modified='2012-10-29 00:56:09' ows_FileRef='1;#personal/Inclusions/Lists/Events/1_.000' />
Now i want to retireve the "Due Date" column and compare with the today's date. For retrieving date there is no issue. But how to compare the both dates? For comparing the date with today I used like this.
var k = new Date();
var year = k.getYear();
var month = k.getMonth();
var day = k.getDate();
var fulldate = year+"-"+month+"-"+day
But it is displaying only with date. In xml we are getting time also. I dont want to compare with time. I want to compare with only dates. How to achieve it? I want to put that whole process in the following function.
$(xData.responseXML).find("z\\:row").each(function() {
//here i want to compare that date column with present date
});
Finally i want, the date coming in the xml is less than the today's date or not?
Something like this:
function isPastDate( date ) {
return (new Date( date )).getTime() < (new Date()).getTime();
}
Highly recommend Date.js library for all the comparison and formatting methods that can make a lot of date work greatly simplified
http://www.datejs.com/
finally the required comparison like below.
function compareDates(passdate)
{
var splitdate = passdate.split(" ");
var splitdate1 = splitdate[0].split("-");
var newdate = splitdate1[1]+"-"+ splitdate1[2]+"-"+splitdate1[0];
return ((Date.parse(newdate)) < (new Date()).getTime());
}

Categories