Determine correct date format of Google Form response - date

What is the best way to determine the correct date format (dd/mm or mm/dd) of a Google Form response.
When I use the namedValues object:
function onFormSubmit(e){
var namedValues = e.namedValues;
var date = namedValues['Date']; // Date=[05/06/2018]
var date = new Date(date);
Logger.log(date); //Sun May 06 00:00:00 GMT+10:00 2018
}
When I use the value from the spreadsheet:
function onFormSubmit(e){
var range = e.range;
var row = range.getRow();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Form Responses 1');
var date = sheet.getRange(row,2).getValue();
Logger.log(date); //Mon Jun 05 00:00:00 GMT+10:00 2018
}
I don't know whether I should be, but I am hesitant using the values from the spreadsheet in an onFormSubmit trigger, since I have experienced instability in the past where I think the trigger was running before the data was being posted to the spreadsheet.
I cannot find anything in the Google Forms documentation stating whether a date response is always in a consistent format. If it was always dd/mm/yyyy I could construct the date using the string parts.
Is there a way to use determine the correct date format from the namedValues object?
P.S I would rather not use the moment.js library for this one requirement, so keen to understand if its possible without.

You Google form will constantly submit the date in the same format, but your sheet might change the appearance of formatting.
Also, there is now a date format utility built into Apps script. You can change the date string to the format that you need.
// This formats the date as Greenwich Mean Time in the format
// year-month-dateThour-minute-second.
var formattedDate = Utilities.formatDate(new Date(), "GMT", "yyyy-MM-dd'T'HH:mm:ss'Z'");
Logger.log(formattedDate);

Related

Google scripts - Formatting date from a form input

To preface I'm very new at this but I currently have a script that outputs a Google Doc/PDF based on inputs into my google form.
The PDF is output whenever a new form is submitted, currently the formatting for the date comes out as DD/MM/YY but I want it to appear as dd MMMM yyyy i.e. 19 May 2020 rather than 19/05/20.
I've tried using the following to change the formatting
var signDate = e.values[1];
var formatSignDate = Utilities.formatDate(signDate, "GMT+1", "dd MMMM yyyy");
body.replaceText('{{Execution Date}}', formatSignDate);
But I get the following error
Exception: The parameters (String,String,String) don't match the method signature for Utilities.formatDate.
at autoFillFromForm(Code:17:28)
What am I doing wrong? Can I not use .formatDate with the date from my sheets cells?
Edit: error message with log of signDate
Stackdriver logs Info signDate = 20/05/2020 Error Exception: The parameters
(String,String,String) don't match the method signature for
Utilities.formatDate. at autoFillFromForm(Code:23:34)
Exception: The parameters (String,String,String) don't match the method signature for Utilities.formatDate
means that signDate is not recognized correctly as a date object
Please provide a log of signDate to help you troubleshoot more in detail.
UPDATE
If you have a date string in UK format ( DD/MM/YYYY), it won't be automatically recognized as a Javascript date object.
You'll need to convert it, e.g:
var convertedDate = new Date(signDate.split('/')[2], signDate.split('/')[1] - 1, signDate.split('/')[0]);
Logger.log(convertedDate);
var formatSignDate = Utilities.formatDate(convertedDate, "GMT+1", "dd MMMM yyyy");
Logger.log(formatSignDate);
Note: Using Utilities.formatDate() as above might give you the wrong date if you are setting it to a different timezone than your script time zone.

Conditional formatting for dates

I'm trying to come up with a simple conditional format formula for highlighting cells that have a date that is greater than three months older than today's date. It seems though that the "Date is before" option only gives a few options, none of them seem to allow what I'm looking for. Is there a custom formula that could accomplish this?
Edit: attaching a snip of the column in question:
Formula :
=DAYS(now(),B2)>90
Go to the custom formula in the conditional formating rules and use this:
=DATEDIF(A1,TODAY(),"D")<90
try:
=1*C2>DATE(YEAR(TODAY()), MONTH(TODAY())+3, DAY(TODAY()))
also make sure you have valid dates and not plain text dates. you can test this with ISDATE formula
You can use Apps Script and a Custom Menu in order to solve your issue with setting the color in the cell depending on the date. Go to Tools->Script Editor and paste this code:
function onOpen() {
var ui = SpreadsheetApp.getUi();
ui.createMenu('Custom Menu')
.addItem('Check Difference', 'dateDifference')
.addToUi();
}
function dateDifference(){
var sheet = SpreadsheetApp.getActiveSheet().getActiveRange(); // Get the selected range on the sheet
var dates = sheet.getValues(); // Get the values in the selected range
var oneDay = 1000*60*60*24;
var row = 1;
var re = /^(0?[1-9]|[12][0-9]|3[01])[\/\-](0?[1-9]|1[012])[\/\-]\d{4}$/; // This will help you to check if it's really a date
dates.forEach(function(el){ // Iterate over each value
if(typeof el[0] == 'object'){ // Check if it's really a date
var gmtZone = el[0].toString().split(" ")[4].split(":")[0]; // Take the date's GMT
var dateFormatted = Utilities.formatDate(el[0], gmtZone, "dd/MM/yyyy"); // Format the date
if(re.test(dateFormatted)){ // Test if it's the right format
// This part will calculate the difference between the current date and the future date
var futureDateMs = new Date(el[0]);
var todayDateMs = (new Date()).getTime();
var differenceInMs = futureDateMs - todayDateMs;
var differenceInDays = Math.round(differenceInMs/oneDay);
if(differenceInDays >= 91.2501){ // Test if the difference it's greater to 91.2501 days (3 motnhs)
sheet.getCell(row, 1).setBackground("#00FF00"); // Set the color to the cell
}
row++;
}
}
});
Save it by clicking on File->Save.
Then you can select a range in a column and click on Custom Menu->Check Difference as you can see in the next image:
As you can see, you will get the desired result:
Notice
It's really important to be careful with what you consider to be a "month", I mean how many days you are going to take into consideration. In my code, I took Google's suggestion of 1 = 30.4167.
Docs
These are other Docs I read to be able to help you:
Utilities.formatDate()
Working with Dates and Times.
I hope this approach can help you.

Extract the date format from react-intl

I have a component that uses a datepicker. The datepicker needs a dateFormat property that fits the momentjs pattern, for example 'DD.MM.YYYY' or 'MM/DD/YYYY'.
The date formatting is handled by react-intl. This works fine when converting from a date to a string (via formatDate). However, I need to retrieve the pattern as described above.
My goal is to do something like
dateFormat = this.props.intl.extractDateFormat() // returns 'DD.MM.YYYY'
I have found this similar question, but the only answer relies on parsing the string, which I cannot do, because I do not know whether Day or Month will come first in the formatted date.
If it is possible to convert this string to a date and somehow retrieve the format from momentjs, that would also be a good solution.
I was able to get the date format from react-intl. To do this, I defined an example date and had it formatted by react-intl, and then parsed the format by referring to the original string.
My component which is exported as injectIntl(Component) has this method:
deriveDateFormat = () => {
const isoString = '2018-09-25' // example date!
const intlString = this.formatDate(isoString) // generate a formatted date
const dateParts = isoString.split('-') // prepare to replace with pattern parts
return intlString
.replace(dateParts[2], 'DD')
.replace(dateParts[1], 'MM')
.replace(dateParts[0], 'YYYY')
}
The date will e.g. be formatted to '09/25/2018', and this function would return 'MM/DD/YYYY', a format which can be used by Moment.js.
This function only works if you know that the month and day will always be displayed with two digits. It would fail if the format is something like 9/25/2018.
I have not found a way to extract the date format from react-intl directly.

Add day to date with momentjs

I am trying to add a day to my date:
let createdDate = moment(new Date()).utc().format();
let expirationDate = moment(createdDate).add(1, 'd');
console.log(expirationDate);
However, this keeps returning an obscure object {_i: "2017-12-20T21:06:21+00:00", _f: "YYYY-MM-DDTHH:mm:ss Z", _l: undefined, _isUTC: false, _a: Array(7), …}
fiddle:
http://jsfiddle.net/rLjQx/4982/
Does anyone know what I might be doing wrong?
You are logging a moment object. As the Internal Properties guide states:
To print out the value of a Moment, use .format(), .toString() or .toISOString().
let createdDate = moment(new Date()).utc().format();
let expirationDate = moment(createdDate).add(1, 'd');
console.log(expirationDate.format());
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.20.1/moment.min.js"></script>
Please note that you can get the current date using moment() (no need to use new Date()) or moment.utc().
I will go with this one, simple works for me and I don't think you need other function to only add day in moment.
var yourPreviousDate = new Date();
var yourExpectedDate = moment(yourPreviousDate).add(1, 'd')._d;
The add method modifies the moment object. So when you log it, you're not getting an obscure object, you're getting the moment object you're working with. Are you expecting a formatted date? Then use format or some other method.
I agree with other answers just providing shortcut and different ways
You can do the format at the same time
moment().add(1,'d').format('YYYY-MM-DD');
or you can just format any date or date object
moment(result.StartDate).format('YYYY-MM-DD');

How to return a normal javascript date object?

Is it possible to return a javascript date object from this? I have an text input field with the calendar and want to return a standard date object from it's value... Is this possible?
Is this what you are looking for?
var date = '2016-06-12'; // Can be document.getElementById('myField').value that points to your date field.
var date_parts = date.split('-');
var date_obj = new Date(date_parts[0],date_parts[1],date_parts[2]);
console.log(date_obj);
You can also simply use
new Date(document.getElementById('myField').value)
and see if it works. The date function is smart enough to parse based on browser's locale. This should work for time as well. Eg. new Date('2016-06-12 04:15:30')