Comparing Dates in Google Sheets - java

I am new to Java and to Google Script Editor. I have a custom CRM spreadsheet in google sheets, and would like to set up reminder emails based on regularly scheduled follow-up dates. I'm having trouble with the code. I think the trouble may be due to the fact that I'm trying to compare a date to a string, but I can't figure out how to get it to work.
The goal is to send off an email when the date for follow-up matches today's date. The date for follow-up is calculated based on a formula.
Even when the log reads:
[16-07-28 13:38:06:549 PDT] Date is Thu Jul 28 2016 00:00:00 GMT-0700 (PDT)
[16-07-28 13:38:06:549 PDT] Today is Thu Jul 28 2016 00:00:00 GMT-0700 (PDT)
My If statement if (date == todayFull) doesn't work. Here's the code:
function sendEmails() {
var ss = SpreadsheetApp.openById("number");
var sheet = ss.getSheetByName("Script");
var startRow = 2; // First row of data to process
var lastRow = sheet.getLastRow();
var lastCol = sheet.getLastColumn();
// Fetch the range of cells
var dataRange = sheet.getRange(2, 1, lastRow, lastCol);
// Fetch values for each row in the Range.
var data = dataRange.getValues();
for (var i = 0; i < data.length; ++i) {
var row = data[i];
var date = row[32];
var todayFull = new Date();
todayFull.setHours(0);
todayFull.setMinutes(0);
todayFull.setSeconds(0);
Logger.log("Date is "+date);
Logger.log("Today is "+todayFull);
if (date == todayFull) {
Logger.log("This is a test. The Date is Today");
// var emailAddress = row[28]; // Email column
// var groupName = row[3]; // Group Name column
// var subject = "Follow up with this group right now!";
// MailApp.sendEmail(emailAddress, subject, groupName);
};
};
}

Thanks for the help. The first answer ended up working most of the way. Using .getDate() helped, but I also had to add arguments for month and year. Here's the code I ended up with:
function sendEmails() {
var ss = SpreadsheetApp.openById("");
var sheet = ss.getSheetByName("");
var startRow = 4; // First row of data to process
var lastRow = sheet.getLastRow(); //Get the last row of data to be processed
var lastCol = sheet.getLastColumn();
var dataRange = sheet.getRange(2, 1, lastRow-3, lastCol);
var data = dataRange.getValues();
for (var i = 0; i < data.length; ++i) {
var row = data[i];
var date2 = new Date(row[24]); // creates a new Date (date in string) object
var todayFull2 = new Date(); // creates a new Date (now) object
if (date2.getDate() == todayFull2.getDate() && date2.getMonth() == todayFull2.getMonth() && date2.getYear() == todayFull2.getYear()) {
etc

You're comparing two different data types:
var date = row[32]; // reads in a String object
var todayFull = new Date(); // creates a new Date (now) object
...
if (date == todayFull) { // compares Date with String
...
}
You might be better off creating the Date object when you read the value from your Sheet, and then comparing the actual dates in milliseconds (at time 00:00:00:00 of given date) of those Date objects, as you appear to be intending to do:
var date = new Date(row[32]); // creates a new Date (date in string) object
var todayFull = new Date(); // creates a new Date (now) object
todayFull.setHours(0,0,0,0) // sets time to midnight of current day
...
// compare Date with Date
if (date.getTime() == todayFull.getTime()) {
...
}
See MDN's excellent documentation on Javascript's Date.

Related

How find all MongoDB documents inserted between two LocalDateTime

I'm trying to develop an app that retrive all documents inserted in a certain period.
This is my actual sample code:
MongoClient mongoClient = MongoClients.create("mongodb://localhost:27017");
MongoDatabase database = mongoClient.getDatabase("eam");
MongoCollection<Document> collection = database.getCollection("coll");
List<Document> docsList = new ArrayList<>();
LocalDateTime initDate = LocalDateTime.now();
LocalDateTime endDate = initDate.plusSeconds(5);
int i = 0;
while (LocalDateTime.now().isBefore(endDate)) {
Document doc = new Document("id", i)
.append("name objy", "Obj " + i)
.append("timeStamp", LocalDateTime.now());
docsList.add(doc);
i++;
}
collection.insertMany(docsList);
MongoCursor<Document> cursor = collection.find(new Document("timestamp", new Document("$gte", endDate.minusSeconds(3)).append("$lte", endDate.minusSeconds(2)))).iterator();
try {
while (cursor.hasNext()) {
System.out.println(cursor.next().toJson());
}
} finally {
cursor.close();
}
As #Valijo, I modified my code to filter by gte and lte but now It doesn't return anything!
Why?
Take a look at https://docs.mongodb.com/manual/reference/method/Date/ if you don't want to work with timestamps
$in checks if timestamp is equals to one of the values inside the $in: https://docs.mongodb.com/manual/reference/operator/query/in/
But you need a between, this code should work for you:
db.yourcollection.find({$gte: {'timestamp': min}, $lte: {'timestamp': max}})
please mind: the above code is for mongo shell, but you should be able to "translate" it to your needed syntax
EDIT: also mind that mongodbs time is always UTC
$in selects exact values as given array.
So, you need to keep the exact timestamp reference (with 1 ms precision)
The problem is here:
LocalDateTime initDate = LocalDateTime.now();
LocalDateTime endDate = initDate.plusSeconds(5);
int i = 0;
while (LocalDateTime.now().isBefore(endDate)) {
Document doc = new Document("id", i)
.append("name objy", "Obj " + i)
.append("timeStamp", LocalDateTime.now()); //<-- The timestamp ms may differ from initDate ms
docsList.add(doc);
i++;
}
Solution 1: While inserting documents, use:
initDate.plusSeconds(i)
And then your query will return what you expect
Solution 2: (You may translate to your programming language)
Keep timeStamp references and then search them
var date1 = new Date(1537457334015); //Thursday, 20 September 2018 15:28:54.015
var date2 = new Date(1537457335014); //Thursday, 20 September 2018 15:28:55.014
var date3 = new Date(1537457336015); //Thursday, 20 September 2018 15:28:56.015 1 sec 1 ms
var date4 = new Date(1537457336025); //Thursday, 20 September 2018 15:28:56.025 2 sec 11 ms
var date2Plus1Sec = new Date( date2.getTime() + 1000 );
//db.coll.remove({})
db.coll.insert([
{
"timeStamp" : date1
},
{
"timeStamp" : date2
},
{
"timeStamp" : date3
},
{
"timeStamp" : date4
}
])
db.coll.find({"timeStamp" :{$in: [date1, date2, date2Plus1Sec ]} } ).pretty();
Result:
/* 1 */
{
"_id" : ObjectId("5ba3bea3ba135b198e17ec2d"),
"timeStamp" : ISODate("2018-09-20T15:28:54.015Z")
}
/* 2 */
{
"_id" : ObjectId("5ba3bea3ba135b198e17ec2e"),
"timeStamp" : ISODate("2018-09-20T15:28:55.014Z")
}
So Thursday, 20 September 2018 15:28:56.014 not exists in database
Solution 3: Don't use exact value match and use $gte and $lte operators to search timeStamp range

How to use Google Scripts with Google Sheets to send an email 3 days before a defined date?

I modified Google's Mail Merger example to create a Google Spreadsheet/Script that I would like to have send an email 3 days before a client's rental due date. I have a cell set up to take the rental due date inputted by the user and subtract it by today's date.
I then have a if statement running to check if that cell is equal to 3 and if so send an email with MailApp. But for some reason it does not seem to work and when I try and Logger.log the variable comes back undefined. I am really new to Google Scripts and Sheets so I apologize if I am being vague at all or not understanding something fundamental.
Here is a link to the sheet, you just have to go to tools/script editor to see the script.
function sendEmails() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var dataSheet = ss.getSheets()[0];
var dataRange = dataSheet.getRange(2, 1, dataSheet.getMaxRows() - 1, 7);
var templateSheet = ss.getSheets()[1];
var emailTemplate = templateSheet.getRange("A1").getValue();
// Create one JavaScript object per row of data.
var objects = getRowsData(dataSheet, dataRange);
// For every row object, create a personalized email from a template and send
// it to the appropriate person.
for (var i = 0; i < objects.length; ++i) {
// Get a row object
var rowData = objects[i];
// Generate a personalized email.
// Given a template string, replace markers (for instance ${"First Name"}) with
// the corresponding value in a row object (for instance rowData.firstName).
var emailText = fillInTemplateFromObject(emailTemplate, rowData);
var emailSubject = "Your Renty Rental is Due Soon!";
var timeTill = objects[i][6];
Logger.log(timeTill);
if (timeTill == 3) {
MailApp.sendEmail(rowData.emailAddress, emailSubject, emailText);
}
}
}
Based on this link
And assuming you just wanted to send simple email to the recipient, I made a more simple email function for you;
function sendMail(){
var ss = SpreadsheetApp.getActiveSpreadsheet(); //Get the active Spreadsheet
var sheet = ss.getSheetByName('Sheet1'); //Get the sheet by name, Sheet1 as example
var startRow = 2; //We start process things from row 2
var lastRow = sheet.getLastRow(); //Get the last row of data to be processed
var lastCol = sheet.getLastColumn(); // Get the last column of data to be processed
var range = sheet.getRange(2,1,lastRow,lastCol); //Fetch the range
var data = range.getValues(); //Get the values inside the range
for (var i = 0;i<data.length;i++) //Iterate values
var row = data[i]; //Set up variable for easier retrieve data to be processed and more understandable by human
var FirstName = row[1]; //Column B
var LastName = row[2]; //Column C
var emailAddress = row[3]; //Column D
var dueDate = Utilities.formatDate(new Date(row[4]),'GMT+0800','MM/dd/yyyy'); //Column E. Utilities format so the date won't be in long values
var timer = row[6]; //Column G
var msg = 'Hello '+FirstName+' '+LastName+'<br><br>' // Your templates
+'This is a test mail '+dueDate+'<br><br>'
+'Bla bla bla<br>'
+'Another lines of texts<br><br>'
+'Another lines of texts<br><br>'
+'Thank You<br><br>'
+'OH!! I like Banana.';
if(timer == 3){ //Set up the condition
GmailApp.sendEmail(emailAddress,'Your Renty Rental is Due Soon!',msg,{htmlBody:msg}); //Send the email to the recipient
sheet.getRange(startRow+i,7).setNote('Email Sent'); //Set note on column 'G'
}
}
For the trigger to run everyday, go to "Resource", click "Current Project Trigger". Set new project trigger with "function sendMail", "Time driven", "Day timer", "time you want the script to run".
If anything in doubt, comment it here.
Fixed:
I forgot the {} behind "For" loop;
function sendMail(){
var ss = SpreadsheetApp.getActiveSpreadsheet(); //Get the active Spreadsheet
var sheet = ss.getSheetByName('Sheet1'); //Get the sheet by name, Sheet1 as example
var startRow = 2; //We start process things from row 2
var lastRow = sheet.getLastRow(); //Get the last row of data to be processed
var lastCol = sheet.getLastColumn(); // Get the last column of data to be processed
var range = sheet.getRange(2,1,lastRow,lastCol); //Fetch the range
var data = range.getValues(); //Get the values inside the range
for (var i = 0;i<data.length;i++){ //Iterate values
var row = data[i]; //Set up variable for easier retrieve data to be processed and more understandable by human
var FirstName = row[1]; //Column B
var LastName = row[2]; //Column C
var emailAddress = row[3]; //Column D
var dueDate = Utilities.formatDate(new Date(row[4]),'GMT+0800','dd/MM/yyyy'); //Column E. Utilities format so the date won't be in long values
var timer = row[6]; //Column G
var msg = 'Hello '+FirstName+' '+LastName+'<br><br>' // Your templates
+'This is a test mail '+dueDate+'<br><br>'
+'Bla bla bla<br>'
+'Another lines of texts<br><br>'
+'Another lines of texts<br><br>'
+'Thank You<br><br>'
+'OH!! I like Banana.';
if(timer ==3){ //Set up the condition
GmailApp.sendEmail(emailAddress,'Your Renty Rental is Due Soon!',msg,{htmlBody:msg}) //Send the email to the recipient
sheet.getRange(startRow+i,7).setNote('Email Sent'); //Set note on column 'G'
SpreadsheetApp.flush
}
}
};

how to change kendo standard date format to sql format if the grid on server filtering?

I have Kendo grid with server filtering enable , if I click on filtering the date column , the server is receiving the date value as standard one like below
Tue May 03 2016 00:00:00 GMT+0400 (Arabian Standard Time)
I know how to change the date value on update , like below
parameterMap: function(data, type) {
if (type !== "read" && data.models) {
//return {models: kendo.stringify(options.models)};
var d = new Date( data.models[0].joinDate );
data.models[0].joinDate = kendo.toString(new Date(d), "yyyy-MM-dd");
console.log("date is:"+data.models[0].joinDate);
// here the server is receiving the join date as yyyy-MM-dd
return data;
}
}
else
{
// it is showing an error if i do like that
// var d = new Date( data.models[0].joinDate );
// data.models[0].joinDate = kendo.toString(new Date(d), "yyyy-MM-dd");
return data;
}
now my question is what is the function that fires if I click on filter button of the grid which in there I can parse the date to sql format before sending to server . I have tried to do it in read function as mentioned above but it is showing an error .
I think I solve it after long time searching , and this answer for someone who is searching like me .
In order to change the filter field value from standard date-time format to sql format before sending to the server , we need to change the value of that field in filter configuration object of the datasource for the grid .
in order to get the filter configuration object , we can get inside transport.parameterMap like below
parameterMap: function(data, type) {
if (type !== "read" && data.models) {
//return {models: kendo.stringify(options.models)};
var d = new Date( data.models[0].joinDate );
data.models[0].joinDate = kendo.toString(new Date(d), "yyyy-MM-dd");
console.log("joinDate in sql frmat for any update on grid:"+data.models[0].joinDate);
return data;
}
else
{
// get currently applied filters from the Grid is data.filter.
var currFilterObj = data.filter;
var currentFilters = currFilterObj ? currFilterObj.filters : [];
if (currentFilters && currentFilters.length > 0) {
for (var i = 0; i < currentFilters.length; i++) {
if (currentFilters[i].field == "joinDate")
{
var d = new Date( currentFilters[i].value );
currentFilters[i].value = kendo.toString(new Date(d), "yyyy-MM-dd");
console.log("Now joinDate value is in sql format "+currentFilters[i].value);
}
}
}
return data;
}

How do I search for a range of values in between two Strings in Java

First I know this is bad way to compare dates but I don't understand how to evaluate a strings to include the data between 2 values. For example in this code how would I list not only transactions that occurred on tdate 1 and 2 but also the transactions that fell between them.
tdate information is set up like 11/07/2013
System.out.println("Start Date: ");
tdate = in.next();
System.out.println("End Date: ");
tdate2 = in.next();
transactionSet trr = new transactionSet();
for(int idx = 0; idx < ts.getNumTrans(); idx++){
t = ts.retrieve(idx);
if (t.getTdate().equals(tdate) || t.getTdate().equals(tdate2)){
trr.insert(t);
}
}
SimpleDateFormat format = new SimpleDateFormat("d/M/yyyy"); // If this is the right format
Date first = format.parse(tdate);
Date second = format.parse(tdate2);
Date toCheck = format.parse(someDate);
if (toCheck.after(first) && toCheck.before(second)){
// ...
}
You might want to do this in a try/catch block, in case the dates that are input are not formatted correctly.

netbeans: how to set value to control which is retrieved from database?

I want to fetch records from database & want to set on form. In this form I am using JDateChooser from JCalendar. I have written the following code for this:
public void showdata()
int a=leaveView.getSelectedRow();
int b=(Integer)leaveView.getValueAt(a, 0);
String c=(String)leaveView.getValueAt(a, 1);
String d=(String)leaveView.getValueAt(a, 2);
String e=(String)leaveView.getValueAt(a, 3);
String f=(String)leaveView.getValueAt(a, 4);
String g=(String)leaveView.getValueAt(a, 5);
String h=(String)leaveView.getValueAt(a, 6);
int i=(Integer)leaveView.getValueAt(a, 7);
String j = (String)leaveView.getValueAt(a, 8);
String k = (String)leaveView.getValueAt(a, 9);
AL.empid.setSelectedItem(b);
AL.empname.setText(c);
AL.empname.setEditable(true);
AL.department.setText(d);
AL.department.setEditable(true);
AL.leavetype.setSelectedItem(e);
AL.other.setText(f);
AL.other.setEditable(true);
AL.jDateChooser1.setDate(g);
AL.jDateChooser2.setDate(h);
AL.noofdays.setText(""+i);
AL.noofdays.setEditable(true);
AL.singleday.setSelected(true);
AL.multipleday.setSelected(true);
}
but it's setting today's date to JDateChooser by default... it's not displaying the date which is retrieved from database... The above code is throwing an error at lines AL.jDateChooser1.setDate(g) and AL.jDateChooser2.setDate(h) for g & h...What can I do?
Assuming you are using this JCalendar API
From the javadocs setDate accepts a date object and not a string. First convert(parse) the dateString(g & h) to Date objects then set the date.
DateFormat df = new SimpleDateFormat("dd/MM/yyyy"); //adjust this according to your requirement
Date gDate,hDate;
        try {
            gDate = df.parse(g);
hDate = df.parse(h);
        } catch (ParseException e) {
            e.printStackTrace();
        }
AL.jDateChooser1.setDate(gDate);
AL.jDateChooser2.setDate(hDate);
for some example date formats,visit http://docs.oracle.com/javase/1.4.2/docs/api/java/text/SimpleDateFormat.html

Categories