I am having a datatable return a number of Dates received - they are coming back in the format below(will always take this format):
/Date(1362045881257)/
how can I easily strip this to just the epoch digits so I can then convert into a readable date.
I have tried the following so far but it is not working as expected. So the first thing I was trying to remove was just the ( ) - then I was going to do another .replace to remove the / / and then remove the Date which would leave me with just the digits.
success: function (msg) {
for (var i = 0; i < msg.aaData.length; i++) {
var date = msg.aaData[i].DateReceived;
date.replace(/\(|\)/g, '');
alert(date);
}
fnCallback(msg);
},
success: function (msg) {
for (var i = 0; i < msg.aaData.length; i++) {
// toString() below might be redundant!
var date = msg.aaData[i].DateReceived.toString();
var reg = /[^0-9]/g;
var epoch = date.replace(reg, ''));
alert(epoch);
}
fnCallback(msg);
},
Related
I have a spreadsheet and row #1 has dates in each cell going across
I want to return the column number whenever that column matches today's date. First header starts in cell B1.
I am using the following and I can get it to work, but when instead I do 'return i', it always returns '0'.
function getColumnIndex() {
var spreadsheet = SpreadsheetApp.getActive();
var sheet = spreadsheet.getActiveSheet();
var lastColumn = sheet.getLastColumn();
var data = sheet.getRange(1,2,1,lastColumn).getValues(); //create an array of data from row 1
for (var i = 0; i <= data.length; i++) {
var dateToday = Utilities.formatDate(new Date(), "EST", "MM/dd/yyyy")
if (data[i] == dateToday) {break};
{
return i;
}
}
}
Now if I switch the last line 'return i' to 'return dateToday' the function will work and it will return the correct date so I know it's matching properly (and if I change row cells to other values it will return those values if it matches). I just can't get it to spit out the index number when I put 'return i'.
Issues / Explanation:
var data = sheet.getRange(1,2,1,lastColumn).getValues(); returns a 2D array.
As a result, data[i] returns a 1D array which is actually referring to the row. To solve this issue, flatten the array to convert it to 1D:
var data = sheet.getRange(1,2,1,lastColumn).getDisplayValues().flat();
Your if condition is executed at the first iteration i=0 because you put a semicolon ; right after it. Also, break is not needed because nothing will be executed after the return statement:
Replace:
if (data[i] == dateToday) {break};
{
return i;
}
with
if (data[i] == dateToday)
{
return i;
}
When you are working with date comparisons, you need to use getDisplayValues() to be sure that you are comparing the the displayed values
and not the value of the date.
Solution:
function getColumnIndex() {
var spreadsheet = SpreadsheetApp.getActive();
var sheet = spreadsheet.getActiveSheet();
var lastColumn = sheet.getLastColumn();
var data = sheet.getRange(1,2,1,lastColumn).getDisplayValues().flat(); //create an array of data from row 1
for (var i = 0; i <= data.length; i++) {
var dateToday = Utilities.formatDate(new Date(), "EST", "MM/dd/yyyy")
if (data[i] == dateToday)
{
return i;
// return i+2; // if you want to get the column number instead.
}
}
}
Keep in mind, i refers to the position of the array. In JavaScript, the indexes in the arrays start from 0. Also, your data starts from the second column. If you want your script to return the number of column, then change return i to return i+2.
function getColumnIndexForToday() {
const ss=SpreadsheetApp.getActive();
const sh=ss.getActiveSheet();
const shsc=2;
const offset=0;//0 if you want the index from column B 1 if you want the index from ColumnA
const data=sh.getRange(1,shsc,1,sh.getLastColumn()-shsc+1).getDisplayValues()[0];//assuming format is "MM/dd/yyyy"
var dObj={};
data.forEach(function(h,i){dObj[h]=i+offset;});//You really can just do this once and then use it repeatedly
var dateToday = Utilities.formatDate(new Date(), "EST", "MM/dd/yyyy")
return dObj[Utilities.formatDate(new Date(),Session.getScriptTimeZone(),"MM/dd/yyyy")];
}
I have the 2 columns in my table schema:
Column D= Date, i.e. 20180611 [yyymmdd]
Column F= Continuous Value, i.e. 0.1, 0.6, -0.3 etc.
This is what I want to happen:
Check in column D for yesterday's date. Then, take in the corresponding row, and check if column F is greater than 0.5 (for yesterday's date). If TRUE, then send an email alert.
This is the script I have but it does not trigger for some reason. What is wrong with it?
function readCell() {
var sheet = SpreadsheetApp.getActive().getSheetByName('test');
var dates = sheet.getRange('D1:D').getValues();
var date = null;
var dateRow = 0;
var dateCount = dates.length;
var yesterday = new Date();
yesterday.setDate(yesterday.getDate() - 1);
var yesterdayString = yesterday.toDateString();
for (dateRow; dateRow < dateCount; ++dateCount) {
try {
date = dates[dateRow].toDateString();
if (date === yesterdayString) {
++dateRow;
// To account for zero-based array
break;
}
} catch (error) {
Logger.log(error);
}
}
var value = sheet.getRange('F' + dateRow).getValue();
if (value >= 0.5) {
var result = ('Alert found on: ' + date);
MailApp.sendEmail('blabla#gmail.com', 'Alert', result);
}
};
Here is the data
The problem could be due to the use of an open reference D2:D to get values and then use dates.length to set the number of iterations on the for loop because it could be a number too large.
One "quick and dirty" way that could solve the above issue is to replace
var dateCount = dates.length;
by
var dateCount = sheet.getDataRange().getValues().length;
I have date string like this 1 May 2010 To 15 Aug 2016 .I just want to check this as date string on my function and not to proceed on a function.When I'm checking this string with new Date(value) its returning Invalid date.How can I check this as date?
I would use js date library moment js for this.
var checkDate = function (str){
var dates = str.split("To");
var flag = true;
for(var i = 0; i < dates.length; i++) {
if (moment(dates[i]).isValid()) {
flag = false;
}
}
return flag;
}
I have created a fiddle for that
https://jsfiddle.net/Refatrafi/wj5zc75e/
var str = "1 May 2010 To 15 Aug 2016";
//First split string
var array = str.split("To");
//then check if both are dates
for(var i = 0; i < array.length; i++) {
if(isNaN(new Date(array[i]))) { //Checking date
alert(array[i]+ ' is not valid date');
}
}
When parsing strings you should always provide the format of the string to parse. This can be done very simply using the ES5 every method:
var isValid = '1 May 2010 To 15 Aug 2016'.split(' To ').every(function(s) {
return moment(s,'D MMM YYYY').isValid();
});
console.log(isValid);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.14.1/moment.js"></script>
If arrow functions are OK, then:
var isValid = '1 May 2010 To 15 Aug 2016'.split(' To ').every(s=>moment(s,'D MMM YYYY').isValid());
does the job.
var checkDate = function (str){
var dates = str.split("To");
for(var i = 0; i < dates.length; i++) {
if (moment(dates[i]).isValid()) {
return true;
} else {
return false;
}
}
}
I can use this function in my code anywhere.
I have a string "P18DT5H2M3S" which means: 18 days, 5 hours, 2 minutes, 3 seconds.
I have to parse this string to hour and minute. Should I use regex or split or substr etc...?
(regarding to this How can I convert come string timespan variable from Wcf to hours and minutes?)
You can use whatever you want.
Following is the example using split method with regex.
var res = "P18DT5H2M3S";
var tokens = res.split(/[A-Z]+/);
//var str = "D:"+token[1]+" H:"+tokens[2]+" M:"+tokens[3]+" S:"+tokens[4];
alert("D:"+tokens[1]+" H:"+tokens[2]+" M:"+tokens[3]+" S:"+tokens[4]);
You can do with substr but for this you have to find index of letters. So Spit with regex is simpler approach.
So I took #chandil03's answer and tweaked it to return a HH:MM:SS format.
var stamp = "PT2H10M13S"
// strip away the PT
stamp = stamp.split("PT")[1];
// split at every character
var tokens = stamp.split(/[A-Z]+/);
// If there are any parts of the time missing fill in with an empty string.
// e.g "13S" we want ["", "", "13", ""]
for(var i = 0; i < 4 - stamp.length; i++){
tokens.unshift("");
}
// Here we add logic to pad the values that need a 0 prepended.
var stampFinal = tokens.map(function(t){
if(t.length < 2){
if(!isNaN(Number(t))){
return ("0" + Number(t).toString());
}
}
return t;
});
// pop the last element because it is an extra.
stampFinal.pop();
console.log(stampFinal.join(":"));
I found this page:
http://www.petershev.com/blog/net-timespans-returned-by-breeze-js-or-working-with-iso8601-duration-standard/
So when I added to https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js this js,
I can convert
duration = moment.duration.fromIsoduration('P18DT5H2M3S');
duration._data can be used
it has _days, _hours, _minutes
Please, find my solution based on inoabrian's.
function fromString(timeSpan) {
var hours = 0;
var minutes = 0;
var seconds = 0;
if (timeSpan != null && typeof (timeSpan) == 'string' && timeSpan.indexOf('PT') > -1) {
timeSpan = timeSpan.split("PT")[1].toLowerCase();
var hourIndex = timeSpan.indexOf('h');
if (hourIndex > -1)
{
hours = parseInt(timeSpan.slice(0, hourIndex));
timeSpan = timeSpan.substring(hourIndex + 1);
}
var minuteIndex = timeSpan.indexOf('m');
if (minuteIndex > -1)
{
minutes = parseInt(timeSpan.slice(0, minuteIndex));
timeSpan = timeSpan.substring(minuteIndex + 1);
}
var secondIndex = timeSpan.indexOf('s');
if (secondIndex > -1)
seconds = parseInt(timeSpan.slice(0, secondIndex));
}
return [hours, minutes, seconds];
}
I have my dates converted to moment.js, and now I want to compare it with another date ('now' in this case).
Just a plain compare with a date object seems to be a lot faster than using moment.js isAfter function.
Will this simple compare work in all locales?
Am I missing something here?
Is there a very specific reason why isAfter seems to create a new moment object instead of taking a shortcut when it's a Date object?
All my dates are in UTC.
function executeTests() {
isAfterTest();
compareTest();
}
function isAfterTest() {
console.time('isAfterTest');
var now = new Date();
var dateOfBirth = moment('2000-01-01');
for (var i = 0; i < 50000; i++) {
var x = dateOfBirth.isAfter(now);
}
console.timeEnd('isAfterTest');
}
function compareTest() {
console.time('compareTest');
var now = new Date();
var dateOfBirth = moment('2000-01-01');
for (var i = 0; i < 50000; i++) {
var x = dateOfBirth > now;
}
console.timeEnd('compareTest');
}
<script src="http://cdnjs.cloudflare.com/ajax/libs/moment.js/2.7.0/moment-with-langs.js"></script>
<button onclick="executeTests();">Run Test</button>
Results:
isAfterTest: 3754.000ms (index):32
compareTest: 24.000ms
See: http://jsfiddle.net/t4grs0p7/2/
Looking at the documentation http://momentjs.com/docs/ the isAfter method accepts different types of Date format:
moment().isAfter(Moment|String|Number|Date|Array);
This means it needs to do type checking and then convert it to a date object before running the calculation.
One way you could reduce this impact would be to pass in a Moment object as the comparison date:
function isAfterTest() {
console.time('isAfterTest');
var now = moment();
var dateOfBirth = moment('2000-01-01');
for (var i = 0; i < 50000; i++) {
var x = dateOfBirth.isAfter(now);
}
console.timeEnd('isAfterTest');
}
I created a fiddle to compare, but that doesn't seem to improve it much at all:
http://jsfiddle.net/kmturley/t4grs0p7/7/
Looking at your version I believe you should be using valueOf() method to compare the values:
window.compareTest2 = function() {
console.time('compareTest2');
var now = moment().valueOf();
var dateOfBirth = moment('2000-01-01').valueOf();
for ( var i = 0; i < 50000; i++ )
var x = dateOfBirth > now;
console.timeEnd('compareTest2');
}
Here is a working example:
http://jsfiddle.net/kmturley/t4grs0p7/8/