Google Sheets Auto-Parses Strings To Dates...Sometimes? - date

I'm using Google Sheets to scrape stock data from the tables on Yahoo Finance. For example, to grab a company's P/E Ratio, it's as simple as:
=INDEX(IMPORTHTML("https://finance.yahoo.com/quote/DELL","table", 2),3,2)
However, I'm running into an odd behavior when grabbing the earnings date. Yahoo Finance lists them in two possible formats: like "Feb 25, 2021" or like "Jan 28, 2021 - Feb 01, 2021"
In the first case, just grab the cell value exactly like above:
=INDEX(IMPORTHTML("https://finance.yahoo.com/quote/DELL","table", 2),5,2)
In the second, grab the cell value then parse out the first bit:
=LEFT(INDEX(IMPORTHTML("https://finance.yahoo.com/quote/KO","table", 2),5,2),12)
Now for the issue: it's inconsistent with how it treats the data. In the first case, it recognizes that the string "looks like" a date, & returns it directly as an actual date - as if the call were wrapped in DATEVALUE(), though obviously it is not. In the latter case, it returns it as a string, so you need to explicitly wrap it in DATEVALUE().
Why does it behave inconsistently, returning the first string as a date but the second string as a string? This makes it difficult to have one formula that handles both cases, as DATEVALUE() will break if you pass it something that's already a date (i.e. as in the first case).

Use your LEFT formula in both cases, add in the end *1 and format both as Date, for a single, consistent formula.
KO example
=LEFT(INDEX(IMPORTHTML("https://finance.yahoo.com/quote/KO","table", 2),5,2),12)*1
DELL example
=LEFT(INDEX(IMPORTHTML("https://finance.yahoo.com/quote/DELL","table", 2),5,2),12)*1

Related

Google Sheets - DATE format not working on imported Date in TEXT format

I text based .csv file with a semicolon separated data set which contains date values that look like this
22.07.2020
22.07.2020
17.07.2020
09.07.2020
30.06.2020
When I go to Format>number> I see the Google sheets has automatic set.
In this state I cannot use and formulas with this data.
I go to Format>number> and set this to date but formulas still do not see the actual date value and continue to display an error
Can someone share how I can quickly activate the values of this array so formulas will work against them?
I would be super thankful
Where the date are in column A, starting in cell A1, this formula will convert to DATE as a number, after which you apply formatting to Short Date style.
=ARRAYFORMULA(IF(A1:A="",,DATE(RIGHT(A1:A,4),MID(A1:A,4,2),LEFT(A1:A,2))))
Hopefully(!) the dates stay as text, otherwise Google Sheets would sometimes detect MM/dd/yyyy instead of dd/MM/yyyy, and you won't be able to distinguish between July 9th and September 7th in your example.
Solution #1
If your locale is for instance FR, you can then apply
=arrayformula(if(A1:A="";;value(A1:A)))
solution#2
you can try/adapt
function importCsvFromIdv1() {
var id = 'the id of the csv file';
var csv = DriveApp.getFileById(id).getBlob().getDataAsString();
var csvData = Utilities.parseCsv(csv);
csvData.forEach(function(row){
date = row[0]
row[0] = date.substring(6,10)+'-'+date.substring(3,5)+'-'+date.substring(0,2)
})
var f = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
f.getRange(1, 1, csvData.length, csvData[0].length).setValues(csvData);
}
First thanks to those that suggested a fix. I am not really a programmer and get cold sweats when I see suggesting of running scripts to solve simple problems. Sorry guys.
So the (non programmer) solution with the dates was to do a find/replace (CTRL + H) and replace all the (.)dots with (/)slashes, then to make sure the column is formatted as a date, then Google finally understands it as a date.
With the accounting values as well, I had to do the same find/replace to remove all the ' between thousands, then google woke up and understood them as numbers.
I am significantly underwhelmed by this from Google. They are getting too fat and lazy. They need some competition.

Google spreadsheet month name (MMMM) without declension

I want to display formatted month name in the basic form (nominative) as a label. In Czech language (and several next Slavic languages) we use declension. So if I use =TEXT(NOW();"MMMM") the cell shows month name in genetive instead of nominative (i.e. srpna instead of srpen).
Q: How to format the date in the nominative? The acceptable solution will offer some native way how to solve it but not:
manipulating with strings (month names are too complex)
having some another list with month names
calling own formula (Google script)
Maybe there is no native way how to solve this and it will be implemented in the future, so Google Script seems to be the easiest hotfix for now. And because I'm expecting many answers with the script, I'm putting the one here but this question is not about the javascript/google-script.
function monthName(date) {
var months = ["Leden","Únor","Březen","Duben","Květen", "Červen","Červenec","Srpen","Září","Říjen","Listopad","Prosinec"];
return months[date.getMonth()];
}

Export Calendar Date to spreadsheetout - Time Stripped off - Google Script

I am using Google Script to export some calendar events to a spreadsheet; the relevant portion of my script is below:
var details=[[mycal,events[i].getTitle(), events[i].getDescription(), events[i].getLocation(), events[i].getStartTime(), myformula_placeholder, ('')]];
var range=sheet.getRange(row,1,1,7);
range.setValues(details);
This code works but the "time" that is put into the spreadsheet is a real number of the form nnnnn.nn. On the spreadsheet itself the date looks great using the integer to the left of the decimal (eg 10/15/2017) but the decimals are part of the value and therefore are part of the spreadsheet value.
My script drops the data into a sheet in my workbook, and another sheet reads the rows of data with the above date types, looking for specific date info from the other sheet using the match function (for today()). That would work fine if I could get rid of the decimals.
How can I use what I have above (if I stray far from what I have found works I will be redoing hours of work) but adding just what is needed to only put into the output spreadsheet the whole number portion so I have a pure date that will be found nicely by my match function using today()?
I have been digging, but errors abound in trying to put it all together. "Parse" looked like a good hope, but it failed as the validation did not like parse used within getStartTime. Maybe I used it in the wrong manner.
Help would be appreciated greatly.
According to the CalendarApp documentation, getStartTime() generates a Date object. You should be able to extract the date and time separately from the date object:
var eventStart = events[i].getStartTime(); // Returns date object
var startDate = eventStart.toDateString(); // Returns date portion as a string
var startTime = eventStart.toTimeString(); // Returns time portion as a string
You could then write one or both of these to your spreadsheet. See the w3schools Javascript Date Reference for more information:
http://www.w3schools.com/jsref/jsref_obj_date.asp
If you If you want to specify the string format, you can try formatDate in the Utilities service:
https://developers.google.com/apps-script/reference/utilities/utilities#formatdatedate-timezone-format
You could just use the Math.floor() function
http://www.w3schools.com/jsref/jsref_floor.asp
which will round the real number to an integer. Your line would then read:
var details=[[mycal,events[i].getTitle(), events[i].getDescription(), events[i].getLocation(), Math.floor(events[i].getStartTime()), myformula_placeholder, ('')]];

Powershell simplest method to get current time expressed as UTC

I have reviewed the post Creating a DateTime object with a specific UTC DateTime in PowerShell, but it does not seem to directly answer the question I am asking:
What is the most direct method in PowerShell (3.0) to return a sortable string representing "now" as UTC?
I expected the correct answer to be:
Get-Date -Format (Get-Culture).DateTimeFormat.UniversalSortableDateTimePattern
OR
get-date -format u
but this is not the case.
Example: At 1300 hrs (1pm) on September 1st, 2016 in the Pacific Time Zone during DST, I get the response:
2016-09-01 13:00:00Z (the local time with a "Z" appended)
when I was expecting:
2016-09-01 20:00:00Z (correct UTC/GMT time)
So basically, my code is just getting a string representing the "local" time and appending a "Z".
Now, I know I can manipulate to get to that point, but I'm looking for the minimal (simplest, cleanest) way to get here.
Bonus Points (as if they existed): How do I get that same, sortable result, but displaying with "UTC" and/or "GMT" as the suffix. Same minimal requirement.
Probably something like this:
[DateTime]::UtcNow.ToString('u')
Which is equivalent to:
[DateTime]::UtcNow.ToString((Get-Culture).DateTimeFormat.UniversalSortableDateTimePattern)
For the bonus, I think the most straightforward way is just to replace Z with UTC:
[DateTime]::UtcNow.ToString('u').Replace('Z','UTC')
I'm assuming you'll always want UTC since that what it seems like from your question. There doesn't appear to be a format string to get just the 3 letter time zone.
I tried this, and it also gives the result I want:
"[DateTime]::UtcNow.ToString('yyyyMMdd_HHmmss_UTC')"
It is showing time in the format 20180108_152407_UTC
so you can play with the date/time formatting as you wish basically

How can I add several months to a date coming from a date form field?

With DateJS, you'd add e.g. six months to the current date like this:
Date.today().addMonths(6);
However, I need to add 24 months not to today's date, but to a date which a user has typed into a date field. So the today() should in principle be replaced by something like this.getField('begin_date').value.
The result shall be written into another data form field.
I tried hard, but couldn't make it. Can anyone help me out?
Providing the input value is a textual representation of a date, you need to convert it into a Date object at the first place. Then you can work with it as you want.
DateJS has a pretty smart parse() function which does exactly that, so you'd achieve it like this:
Date.parse(this.getField('begin_date').value).addMonths(24)
When a specific date format is needed, like DD.MM.YYYY commonly used in Europe, you can use parseExact() and specify the format. Like this:
Date.parseExact(dateToParse, 'dd.MM.yyyy') // leading zeroes required; parses 01.04.2014 but not 1.4.2014
Date.parseExact(dateToParse, 'd.M.yyyy') // leading zeroes not required; parses both 01.04.2014 and 1.4.2014
Here is a solution that I found for my problem, using DateJS as well:
start = this.getField('begin_date').value;
var d1 = util.scand("dd.mm.yyyy", start);
var myDate = new Date(d1);
result = myDate.addMonths(24);
This works pretty fine, also spanning leap years, except for the 28th of February, 2014/2018/2022 ... ; the result then will be the 28th of February, 2016/2020/2024 ... and not the 29th of February 2016/2020/2024... In these cases it's up to the user to accept the 28th or to manually change the date to the 29th.