I have a column contain a date in "Sep -13" format.
When I access it from code, it gives integer value. How can I get a date object?
If I use "dd/mm/yyyy" format in sheet, it gives me date object.
function check()
{
var source = SpreadsheetApp.openById('sheet id');
var sourcesheet = source.getSheetByName('sheet name');
var tt = sourcesheet.getRange('F700').getValue();
debugger;
}
Result:
That cells original value might be an integer. That could be happen if you copy and paste values only for a date. so .getValue() will give you that number.
You can use that number to create a date object. JavaScript dates can be constructed by passing milliseconds
//base date 01/01/1970 integer value :25569
//excelDate your date in integer
var myDate = new Date((excelDate - 25569)*86400*1000);
Related
How to I query price at a particular date and time using Alphavantage API.
For eg: I tried this:
https://www.alphavantage.co/query?function=TIME_SERIES_INTRADAY&symbol=^INFY&interval=1min&outputsize=compact&apikey=***********
However I want to pass both Date and Time and need the HIGH for that particular minute for that symbol.
I am using the Excel 365 Add-On but I can use Google Sheets as well.
Possible?
The url will give you a json. You have then to parse it and then apply a formula to retrieve the max value and date/hour/minute it occurs. To parse the json, try with your own api key :
function getAllDataJSON(code) {
var url = 'https://www.alphavantage.co/query?function=TIME_SERIES_INTRADAY&symbol='+code+'&interval=1min&apikey='+YOURAPIKEY
var data = JSON.parse(UrlFetchApp.fetch(url).getContentText())['Time Series (1min)']
var resultat = []
for (var elem in eval(data)){
resultat.push([elem,eval(data[elem]['1. open']),eval(data[elem]['2. high']),eval(data[elem]['3. low']),eval(data[elem]['4. close']),eval(data[elem]['5. volume'])])
}
return resultat
}
If you want extended period, the answer will be a csv file
function getAllDataCSV(code){
// last month : slice=year1month1 (by default) ... until slice=year2month12 (farthest month from today)
// interval : 1min
var url = 'https://www.alphavantage.co/query?function=TIME_SERIES_INTRADAY_EXTENDED&slice=year1month1&symbol='+code+'&interval=1min&apikey='+apikey
var csv = UrlFetchApp.fetch(url).getContentText();
return Utilities.parseCsv(csv)
}
var date = Utilities.formatDate(new Date(), "GMT-8", "m/dd/yyyy")
if (formS.getRange("B7").getValue() != " " && formS.getRange("B7").getValue() != date)
{
SpreadsheetApp.getUi().alert("Please Enter A Valid Date");
return
}
Trying to make the condition above check if the cell is not empty and that it does not contain a date prior to Today's Date
function myfunk() {
const ss = SpreadsheetApp.getActive();
const formS = ss.getSheetByName('formS');
const dtv = new Date(new Date().getFullYear(), new Date().getMonth(), new Date().getDate()).valueOf();
if (!formS.getRange("B7").isBlank() && new Date(formS.getRange("B7").getValue()).valueOf() < dtv) {
SpreadsheetApp.getUi().alert("Please Enter A Valid Date");
return;
}
}
Checking Dates in Apps Script
In general you can use the Date object as you would in normal JavaScript code. There are just one main thing to bear in mind if your script needs to be sensitive to timezones.
The timezone is defined in the manifest:
This cannot be changed dynamically. So if you need to be sensitive to them, then you will need to manage the offsets in your code.
Your script
This line:
var date = Utilities.formatDate(new Date(), "GMT-8", "m/dd/yyyy")
Returns a string. Not a date object, so you can't compare it to another date object, such as what is returned from a sheet value if it is formatted as a date.
You could use Regex or split to get the year and month and compare it that way, but then you may run into issue when you use the script on the 1st of January. This is because by simply comparing the year, month and date of 31/12/2021 with 01/01/2022, then your conditional statements would be a bit tricky. Possible, but maybe a bit hard to read.
Initializing to midnight
What follows is one approach to take to carry out this comparison in a relatively simple way.
It seems convenient to get a date object initialized to 00:00:00 of today. Then you can quickly compare the date using Unix time.
var now = new Date()
now.setHours(0)
now.setMinutes(0)
now.setSeconds(0)
now.setMilliseconds(0)
You can also do this in a more concise way like this:
var now = new Date()
now.setHours(0,0,0,0);
Then you can use the getTime() method on the date objects to get Unic time in milliseconds and compare them.
var dateToCheck = formS.getRange("B7").getValue()
if (
!(dateToCheck instanceof Date) || // If value is not instance of a Date object
dateToCheck.getTime() <= now.getTime() // If date is before 00:00:00 today.
) {
SpreadsheetApp.getUi().alert("Please Enter A Valid Date");
return
}
}
Which seems like a concise way to do the comparison you are looking for.
References
Apps Script Dates
JS Date object
I'm using Sheets.Spreadsheets.Values.update to paste values into a sheet (due to performance issues using range.setValues().
In the case of dates, the source values are date objects (which were pasted fine when I used range.setValues([[]]).
The end result now is though cells with the string version of the date, e.g., Mon Feb 28 00:00:00 GMT+01:00 2022 which do not correspond to a valid gsheet date. I've tried some of the options but cannot find a way for this to work.
I believe your goal as follows.
You want to put the values to Google Spreadsheet using Sheets API with Google Apps Script.
In your current issue, the values include the date object. When this date object is put using spreadsheets.values.update method, the value cannot be used as the date object. You want to resolve this issue.
In order to achieve your goal, how about putting the values by converting from the date object to others?
Pattern 1:
In this pattern, the date object is converted to the serial number and put to the Spreadsheet.
const spreadsheetId = "###"; // Please set the Spreadsheet ID.
const values = [[new Date(), "b1", "c1"], [new Date(), "b2", "c2"]]; // This is a sample value for replicating your issue.
// Here, the date values are converted to the serial number.
const convertedValues = values.map(r => r.map(c => c instanceof Date ? (c.getTime() / 1000 / 86400) + 25569 : c));
Sheets.Spreadsheets.Values.update({values: convertedValues}, spreadsheetId, "Sheet1", {valueInputOption: "USER_ENTERED"});
(c.getTime() / 1000 / 86400) + 25569 for converting from the unix time to the serial number was referred from this answer.
In this script, the date object is put as the serial number. So, please set the number format of the column "A" as the date time. By this, the serial number can be seen as the date time.
Pattern 2:
In this pattern, the date object is converted to the string value for parsing as the date object and put to the Spreadsheet.
const spreadsheetId = "###"; // Please set the Spreadsheet ID.
const values = [[new Date(), "b1", "c1"], [new Date(), "b2", "c2"]]; // This is a sample value for replicating your issue.
// Here, the date values are converted to the string value for parsing as the date object.
const convertedValues = values.map(r => r.map(c => c instanceof Date ? Utilities.formatDate(c, Session.getScriptTimeZone(), "yyyy/MM/dd HH:mm:ss") : c));
Sheets.Spreadsheets.Values.update({values: convertedValues}, spreadsheetId, "Sheet1", {valueInputOption: "USER_ENTERED"});
In this script, the date object is put as the string value for parsing as the date object by USER_ENTERED.
This sample uses yyyy/MM/dd HH:mm:ss as the date format. When this format cannot be parsed, please modify this for your situation.
References:
Method: spreadsheets.values.update
formatDate(date, timeZone, format)
var valueDate = Utilities.formatDate(sheet.getRange("D2").getValue(), SpreadsheetApp.getActive().getSpreadsheetTimeZone(), "dd/MM/YYYY hh:mm:ss");
var valueResetCD = Utilities.formatDate(sheet.getRange("C2").getValue(), SpreadsheetApp.getActive().getSpreadsheetTimeZone(), "hh:mm:ss");
This are my 2 lines I currently have - As the Spreadsheet timezone may be different from the makro timezone I got told to always get the timezone from the Sheet.
In those 2 values I have the right values safed (tried to print them into a field)
first is 19/09/2020 22:34:52 (a specific date) and the second is 03:00:00.000 (3 Hours)
Now what I want to do is just add those 2 times together so I get as output: 20/09/2020 01:34:52
I tried it with: sheet.getRange("Data!$A$21").setValue(valueDate + valueResetCD) but I guess it is not that easy - it just copies the 2 string values of the times into one line.
How can I add those 2 Time / Date values to eachother so I get the output above
I believe your situation and goal as follows.
In your situation, as a sample value,
valueDate is 19/09/2020 22:34:52 retrieved from sheet.getRange("D2").getValue().
valueResetCD is 03:00:00.000 retrieved from sheet.getRange("C2").getValue().
Both values are the date object.
You want to add valueResetCD to valueDate.
When the sample values are used, you want to get 20/09/2020 01:34:52 as the result value.
Modification points:
In this case, I think that valueDate is the correct date time like 19/09/2020 22:34:52 as the date object.
But, I think that valueResetCD is 1899/12/30 03:00:00. Because the Spreadsheet uses the serial number.
From this situation, it is required to convert the serial number to unix time.
And also, in this case, the time difference is required to be considered.
Both values are added by converting from the date object to the unix time. And, the result value is converted to the date object.
When above points are reflected to the Google Apps Script, it becomes as follows.
Modified script:
function myFunction() {
var sheetName = "Sheet1"; // Please set the sheet name.
// 1. Retrieve values from the cells as the date object.
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName);
var valueDate = sheet.getRange("D2").getValue(); // As a sample value, it's `19/09/2020 22:34:52`.
var valueResetCD = sheet.getRange("C2").getValue(); // As a sample value, it's `03:00:00.000`.
// 2. Convert the date object to the unix time.
var valueDateUnix = valueDate.getTime();
var differenceBetweenSerialAndUnix = new Date("1970/01/01 00:00:00").getTime() - new Date("1899/12/30 00:00:00").getTime();
var timeDifference = (new Date().getTimezoneOffset()) * 60 * 1000;
var valueResetCDUnix = valueResetCD.getTime() + differenceBetweenSerialAndUnix - timeDifference;
// 3. Add both time and convert it to the date object.
var resultDateObject = new Date(valueDateUnix + valueResetCDUnix);
var resultString = Utilities.formatDate(resultDateObject, SpreadsheetApp.getActive().getSpreadsheetTimeZone(), "dd/MM/YYYY hh:mm:ss");
console.log(resultDateObject)
console.log(resultString) // You can see "20/09/2020 01:34:52" at the log.
// 4. Put the value to the cell.
sheet.getRange("A1").setValue(resultDateObject);
}
Note:
In this answer, it supposes that the values from the cells "C2" and "D2" are the date object. If those values are the string which is not the date object, above script cannot be used. So please be careful this.
References:
Date
getTime()
getTimezoneOffset()
I have a question about the date convert:
in sheet, I have a date '05/11/2018', I need to get next date 06/11/2018.
var end=Utilities.formatDate(new Date(coach_date.getTime()+1*3600000*24), 'GMT', 'dd/MM/yyyy');
var start = new Date();
var events = calendar.getEvents(start,end);
it shows the 'end' is string, not object. it has to be getEvents(object,object)
so I used end = new Date(end); it got '11/06/2018', change month from Nov to June.
How could I fix it, then use it on getevents() feature.
Thanks a lot.
Utilities.formatDate() converts the date object into a string. So, use
var end = coach_date.setDate(coach_date.getDate()+1);