I have a requirement where i have to filter my data based on datetime.I am retrieving data in server side and passing it to client side by serializing it.My date is in format(
"2014-01-01 12:00:00").Controls i used are Telerik RadDatePicker and RadSlider, upon the change of slider value i want to filter my data by adding hours to date selected and comparing it with my data. Is there any easy way to do it in javascript which will handle all the scenarios like handling leap year scenario as the date will change when the hours will exceed 24.
This is what solve my problem.
function clientValueChange(sender, eventArgs) {
var hr = parseInt(sender._itemData[sender.get_value()].value);
if (dtWPSelDate == "")
return;
var arr = dtWPSelDate.split(' ')[0].split('-');
var dtt = new Date();
dtt.setYear(arr[0]);
dtt.setMonth(parseInt(arr[1]-1));
dtt.setDate(arr[2]);
if (eventArgs.get_oldValue() > eventArgs.get_newValue())
dtt.setHours(-hr,0,0);
else
dtt.setHours(hr,0,0);
dtt.setMinutes(0);
dtt.setSeconds(0);
if ((parseInt(hr) % 24) == 0) {
dtWPSelDate = dtt.format('yyyy-MM-dd 00:mm:ss');
}
else
dtWPSelDate = dtt.format('yyyy-MM-dd hh:mm:ss');
console.log(dtWPSelDate);
}
var dtWPSelDate ;
function DateSelected(sender, eventArgs) {
dtWPSelDate = eventArgs._newValue;
}
var dateString = "4/10/2014"; //consider this as your date in string DataType
var dateArray = dateString.split("/");
var date = new Date(dateArray[2], Number(dateArray[1])-1, dateArray[0]);
//To add Hours
var hoursToBeAdded = 10;
date.setHours(hoursToBeAdded);
Highlight point is you no need to worry about leap year which will be handled by javascript itself.
Related
I am trying to get functionality - if the user entered date is less than the current date I need to show an error message on the screen, I implemented the following code which is working fine in my local system date but not working in other time zones. Can anyone please help in getting this.
I need to use only javascript or jquery. I was not supposed to use other libraries.
dateFormat = function(value, event) {
let newValue = value.replace(/[^0-9]/g, '').replace(/(\..*)\./g, '$1');
const dayOrMonth = (index) => index % 2 === 1 && index < 4;
// on delete key.
if (!event.data) {
return value;
}
return newValue.split('').map((v, i) => dayOrMonth(i) ? v + '/' : v).join('');
}
checkStart = function(value) {
var newDate = new Date().toISOString();
var inputDate = new Date(value).toISOString();
var today = new Date(newDate).setHours(0,0,0,0);
var userDate = new Date(inputDate).setHours(0,0,0,0);
if(userDate < today) {
$('#error-msg3').show();
$('#startDate').val('');
} else {
$('#error-msg3').hide();
}
}
<input type="tel" maxlength="10" id="startDate" name="startDate" placeholder="mm/dd/yyyy"
oninput="this.value = dateFormat(this.value, event)" onblur="checkStart(this.value)" required/>
<span id="error">Start date should not be lesser than the current date.</span>
<script src="https://code.jquery.com/jquery-3.6.0.js"></script>
Server and Db May run on a different timezone, (UTC preferred ) and when you sen date as a string it doesn't have any timezone there instead it is just a string.
Try sending it as a timestamp or UTC date string
So that server and db will automatically convert it to their timzone and store it. and when any user fetch it from other time zone it will automatically converts to their timezone (but you store string it will just be treated as a string everywhere)
let d = new Date()
console.log(d.getTime())
//or get utc string
console.log(d.toUTCString())
Send this value to your server (API)
Your code runs entirely on the client so timezone is irrelevant.
In the OP there is:
var newDate = new Date().toISOString();
...
var today = new Date(newDate).setHours(0,0,0,0);
The conversion of Date to string to Date to number is inefficient and unnecessary. The following is equivalent:
let today = new Date().setHours(0,0,0,0);
Similarly for inputDate:
var inputDate = new Date(value).toISOString();
...
var userDate = new Date(inputDate).setHours(0,0,0,0);
is equivalent to:
let userDate = new Date(value).setHours(0,0,0,0);
All calculations are local so timezone is irrelevant. Also see Why does Date.parse give incorrect results?
Attempting to control user input using script is always fraught as there are many cases that are either impossible or impractical to code around. The use of a tel input for Dates is an example. The whole issue can be avoided by using a date input and setting a min value to today. Then users can't select a date before today and your issue is solved, e.g.
window.onload = function() {
let dateEl = document.getElementById('dateInput');
dateEl.min = new Date().toLocaleString('en-CA', {year:'numeric', month:'2-digit', day:'2-digit'});
}
<input id="dateInput" type="date">
If you are comparing the date sent by the user to a date on the server, then user system clock accuracy and timezone may be an issue, but that isn't explained in the OP.
If that is an issue, then you need to ask another question on that specific topic.
If you really want to manually control the input date and show an error message when invalid dates are selected, then parse the value from the date input and compare it to the start of today and go from there:
// Parse YYYY-MM-DD as local
function parseYMDLocal(s) {
let [Y, M, D] = s.split(/\D/);
return new Date(Y, M-1, D);
}
// Check if date in YYYY-MM-DD format is before today
function isBeforeToday(d) {
return parseYMDLocal(d) < new Date().setHours(0,0,0,0);
}
function checkValue() {
let errEl = document.getElementById('errEl');
errEl.textContent = '';
console.log(typeof this.value);
if (isBeforeToday(this.value)) {
errEl.textContent = 'Date must be today or later';
} else {
// do something else
}
}
window.onload = function() {
document.getElementById('dateInp').addEventListener('blur', checkValue, false);
}
#errEl {color: red}
<input id="dateInp" type="date"><span id="errEl"></span>
I have a script in a Google Sheet that is sending out an alert if a certain condition is met. I want to trigger the script to run hourly, however, if an alert was already sent out today, I don't want to send out another one (only the next day). What is the best way to achieve this?
I've tried formatting the date several ways, but somehow the only thing working for me so far is getting the year, month and day from the date object as int and comparing them separately.
function sendAlert{
var now = new Date();
var yearNow = now.getYear();
var monthNow = now.getMonth() + 1;
var dayNow = now.getDate();
var sheet = SpreadsheetApp.getActive().getSheetByName('CHANGE_ALERT');
var sentYear = sheet.getRange("R2").getValue();
var sentMonth = sheet.getRange("S2").getValue();
var sentDay = sheet.getRange("T2").getValue();
if (yearNow != sentYear || monthNow != sentMonth || dayNow != sentDay) {
sendEmail();
var sentYear = sheet.getRange("R2").setValue(yearNow);
var sentMonth = sheet.getRange("S2").setValue(monthNow);
var sentDay = sheet.getRange("T2").setValue(dayNow);
else {
Logger.log('Alert was already sent today.');
}
}
I think this solution is definitely not the best approach, but I cannot come up with another that merges the date into one. Only comparing the new Date() doesn't work, since the time of day will not necessarily be the same. If I format the date to YYYY-MM-dd, it should work, but then when I get the date again from the spreadsheet it gets it as a full date with the time again.
Requirement:
Compare dates and send an email if one hasn't been sent already today.
Modified Code:
function sendAlert() {
var sheet = SpreadsheetApp.getActive().getSheetByName('blank');
var cell = sheet.getRange(2,18); //cell R2
var date = new Date();
var alertDate = Utilities.formatDate(cell.getValue(), "GMT+0", "yyyy-MM-dd");
var currentDate = Utilities.formatDate(date, "GMT+0", "yyyy-MM-dd");
if (alertDate !== currentDate) {
sendEmail();
cell.setValue(date);
} else {
Logger.log('Alert was already sent today.');
}
}
As you can see, I've removed all of your year/month/day code and replaced it with Utilities.formatDate(), this allows you to compare the dates in the format you specified in your question. I've also changed the if statement to match this, so now we only need to compare alertDate and currentDate.
References:
Utilities.formatDate()
Class SimpleDateFormat
I am working on a date problem.
So, in the app I have a table that have some user records that includes a date of birth field (datetime sql type). The problem is that for some users whose date of birth is prior to 1954, the date is not properly reflected.
For example, I have a user whose date of birth is 11/08/1920 but when I set the date of birth via server script, it ends up with the value 11/07/1920 23:23:24.
I am getting the date value from a spreadsheet and the server script looks like this:
function importDOBs(){
var allRecs = [];
var ss = SpreadsheetApp.openById("adfsasdfasdfasdfasdfasdf");
var sheet = ss.getActiveSheet();
var data = sheet.getRange(2,4,sheet.getLastRow(),2).getValues();
for(var i=0; i<5; i++){
var row = data[i];
var date = row[0];
var oldMrn = row[1];
var query = app.models.purgedRecords.newQuery();
query.filters.oldMrn._equals = oldMrn;
var record = query.run()[0];
if(record){
var dob = new Date(date);
record.dateOfBirth = dob;
allRecs.push(record);
}
}
app.saveRecords(allRecs);
}
These are the values in the spreadsheet (they are strings, not dates):
1954-03-04T00:00:00
2014-03-01T00:00:00
1951-10-20T00:00:00
1920-11-08T00:00:00
1938-09-27T00:00:00
However, somehow I'm always getting this:
As you see, there is a discrepancy on the dates that are prior to 1954. So far, I have tried other things such as changing this part:
if(record){
var dob = new Date(date);
record.dateOfBirth = dob;
allRecs.push(record);
}
to this:
if(record){
var dob = Utilities.formatDate(new Date(date),"GMT","yyyy-MM-dd'T'HH:mm:ss'Z'");
var birthDate = new Date(dob);
record.dateOfBirth = birthDate;
allRecs.push(record);
}
and the above resulted in the same thing. I have tried other dates after 1954 and they also seem wrong. For example 05/19/1968 reflects 05/18/1968 23:00:00. So my best guess so far this has to do something with the daylight savings, perhaps?
The snake pit of converting dates between platforms
Try to set the values to UTC or just format them into the datetime format for MySQL
The first option as seen in the snippet below requires you to convert the format in SQL:
See this answer: MySQL yyyy-mm-ddThh:mm:ss.sssZ to yyyy-mm-dd hh:mm:ss
DATE_FORMAT(STR_TO_DATE(«string»,'%Y-%m-%dT%H:%i:%s.000Z'),'%Y-%m-%d %H:%i:%s');
//Using Z to set to UTC
let allRecs = [];
document.querySelector("pre").textContent.split("\n").forEach(function(element) {
if (element != "") {
const dob = new Date(element + "Z"); //Z forces te date to be in UTC with zero time offzet or: 00:00:00
const dateOfBirth = dob;
allRecs.push(dateOfBirth);
}
});
console.log(allRecs);
allRecs = [];
//format to MySQL datetime format
document.querySelector("pre").textContent.split("\n").forEach(function(element) {
if (element != "") {
element = element.replace("T", " "); //replace T with space
//now the string is in the datetime format for MySQL
allRecs.push(element);
}
});
console.log(allRecs);
<pre>
1954-03-04T00:00:00
2014-03-01T00:00:00
1951-10-20T00:00:00
1920-11-08T00:00:00
1938-09-27T00:00:00
</pre>
my code below is in javascript, $('#date_start').change(function(){ is working fine, but when im using if else statement to compare the date inputted in my inputbox from the current date, nothing happens at all.
$(document).ready(function() {
$('#date_start').change(function(){
var startdate = $('#date_start').datepicker("getDate");
var today = new Date();
var tomorrow = today.add(2).day();
if(startdate.getTime() < today.getTime()){
document.getElementById('finish').disabled = true;
}
else{
Remove Time from both of Date and compare it.
String input = "2012/01/20 12:05:10.321";
DateFormat inputFormatter = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS");
Date date = inputFormatter.parse(input);
DateFormat outputFormatter = new SimpleDateFormat("MM/dd/yyyy");
String output = outputFormatter.format(date);
I have a Google App Script that stopped working and throws the Error "TypeError: Cannot find function getHours in object 17.". Since we haven't made any changes in the code and I'm not too familiar with Google App Script/Javascript, I hope someone can point me to the right direction.
The code is much longer than this but I'm giving an example of an appearance of the getHours function (I can provide the full code if needed):
if (action.indexOf("[") == -1 && action != "") { // Check if there is some operation to take action
var roomtype = row[1]; // Reading data from the table
var desc = row[8];
var date = row[2];
var tstart = row[3];
var tstop = row[4];
var name = row[5];
var company = row[9];
var short_title = RoomShortcuts[0][roomtype] + " " + name + " (" + company + ")"; // Creating title of the Calendar entry
if (action == "Tentative") { short_title = "PROV: " + short_title; } // This is for Tentative events
var year = date.getYear(); // Getting the date and time and transforming it for the calendar
var month = date.getMonth();
var day = date.getDate();
var startHour = tstart.getHours();
var startMinute = tstart.getMinutes();
var stopHour = tstop.getHours();
var stopMinute = tstop.getMinutes();
var startdate = new Date(year, month, day, startHour, startMinute);
var stopdate = new Date(year, month, day, stopHour, stopMinute);
if (roomtype == "Gallery") {
var repeat = 2;
cal_EventCalendar[0]['Gallery'] = CalendarApp.openByName("Hub SMR");
} else {
var repeat = 1;
}
Thanks a lot!
I had a similar problem. I was able to use getHours in one script but got the same error when trying to access the sheet from another script. Anyhow, after reading:
http://www.w3schools.com/jsref/jsref_gethours.asp
I put together the following solution:
function weeklyUpdater() {
var sheet = SpreadsheetApp.getActiveSheet();
var schedule = sheet.getRange(2, 2, sheet.getLastRow() + 1, 3).getValues();
var hours = new Date(schedule[0][2]); // parse string into date
var hoursX = hours.getHours();
Logger.log(hoursX + ":");
}
The key is using new Date whereas in my other script schedule[0][2].getHours() works!
Anyhow, hope this helps.
I don't know what row is, or where it's defined. But the 4th element is a number object, with a value of 17, not whatever object you expected it to be.
var tstart = row[3];
var startHour = tstart.getHours(); // Number object has no function getHours()
the issue is in your spreadsheet, not in your script.
You can easily test that by double clicking on the cell that correspond to row[3] (most probably in column D) and see what happens : if it's a date object that shows only hours:minutes then it will give you a calendar popup like this:
If it is a 'ordinary' number or string then nothing special will happen and your script will never get any hour or minute from it since these statements need a date object as argument.
This is one of the dangers of spreadsheets that makes things look like what they are not, in this case showing time value in hours and minutes while the object behind is is a full date value with years, seconds and milliseconds... one often forget that ;-)
So, check the most recent cell values and I'm pretty sure you'll find that someone typed a value the wrong way and that the spreadsheed failed to translate it into a date value.