on the select event i have the starting date and the ending date of the event as parameter.
also i have a list of times
and i want to see if any of the items of my list is between of the event start and endtime
the 3 objects are in Date Format
how can i compare the 3 Times of the Dates to see if if its true????
select: function (start, end, allDay) {
var defaultTemplate = undefined;
$.each(jsonTimeTemplates, function(){
templateStartTime = $.fullCalendar.parseDate(this.Start);
templateEndTime = $.fullCalendar.parseDate(this.End);
if(( templateStartTime.getTime() >= start.getTime()) && ( templateStartTime.getTime() <= end.getTime())){
defaultTemplate = this;
}
});
},
in this case jsonTimeTemplates is my list of objects but when i debug with firebug the if sentence never applies.
here i have an screenshot of my debugging where i have
8:00>=8:00 && 8:00 <= 8:15
i hope the dates arent making the problem here.
function compareDates(dateFrom, dateTo){
if ( Date.parse( dateTo ) < Date.parse( dateFrom ) )
return true;
return false;
}
This function returns true if dateTo is smaller than dateFrom. You can use this function to reach your goal.
Function call:
var startDateStr = $.fullCalendar.formatDate(start, 'MM/dd/yyyy hh:mm tt');
var endDateStr = $.fullCalendar.formatDate(end, 'MM/dd/yyyy hh:mm tt');
compareDates(startDateStr, endDateStr);
in the mean time i used the functions gethours and getminutes to do the comparisons. but i hope theres a better way to do this
if( ( templateStartTime.getHours() >= start.getHours() ) && ( templateStartTime.getHours() <= end.getHours() ) &&
(templateStartTime.getMinutes() >= start.getMinutes() ) && ( templateStartTime.getMinutes() <= end.getMinutes() ))
{
defaultTemplate = this;
}
Related
I'm new around here, apologies in advance. I go with my question: I have a google spreadsheet with multiple cells and two sheets. What I am trying to do is that when I type a value in any cell in column 2, the time and date will automatically appear in the adjacent cell. I have gotten this code, which only worked for me on Sheet 1:
function onEdit() {
var s = SpreadsheetApp.getActiveSheet();
if( s.getName() == "HOJA 1-HF-SSB" ) { //checks that we're on the correct sheet
var r = s.getActiveCell();
if( r.getColumn() == 2 ) { //checks the column
var nextCell = r.offset(0, 1);
if( nextCell.getValue() === '' ) //is empty?
nextCell.setValue(new Date()).setNumberFormat("dd-MM-yyyy HH:mm");
}
}
}
Then I have managed to simplify it and adapt it to work on both sheets of the document:
function onEdit(e) {
var sheets = ["HOJA 1-HF-SSB", "HOJA 2-FM-DMR"];
if (sheets.indexOf(e.source.getActiveSheet()
.getName()) === -1 || e.range.columnStart !== 2) return;
e.range.offset(0, 1)
.setValue(new Date()).setNumberFormat("dd-MM-yyyy HH:mm");
}
My questions are: Is there a way to get the date and time to go in separate columns? That is, when I fill in column 2, the date is written in column 3 and the time in column 4?
My final goal, apart from separating the date and time, is to determine later (I don't know how to do it) and highlight which values recorded in column 2 are duplicated on the same date, comparing them with the automatic dates in column 3, regardless of the time. Thank you and excuse me, I am a very newbie!
Try (only for column #2)
function onEdit(e) {
var sheets = ["HOJA 1-HF-SSB", "HOJA 2-FM-DMR"];
if (sheets.indexOf(e.source.getActiveSheet().getName()) === -1 || e.range.getColumn() !== 2) return;
var dateObj = new Date();
var month = dateObj.getUTCMonth() + 1; //months from 1-12
var day = dateObj.getUTCDate();
var year = dateObj.getUTCFullYear();
var newdate = year + "/" + month + "/" + day;
e.range.offset(0, 1).setValue(newdate).setNumberFormat("dd-MM-yyyy");
e.range.offset(0, 2).setValue(new Date()).setNumberFormat("HH:mm");
}
https://docs.google.com/spreadsheets/d/1NYxNfoPM6l_PJTPBDxEth2n-T_H0o03FG6C0OMDuJOo/copy
I'm trying to execute some code if the current time anywhere in the world is between 8:30 AM and 5:30 PM and is not the weekend in Mountain Standard Time. I'm loading in moment-with-locales.min.js and moment-timezone-with-data.min.js. My code looks like this:
var format = 'hh:mm',
date = new Date()
mstWeekday = moment(date, 'd', 'MST')
time = moment(date, format),
beforeTime = moment('08:30', format, 'MST'),
afterTime = moment('17:30', format, 'MST');
if ( (time.isBetween(beforeTime, afterTime)) && ( (mstWeekday !== 6) || (mstWeekday !== 7) ) ) {
// Do something
}
If my browser is set to MST, this seems to work. If I set it to something else, like Tokyo time, it doesn't work.
Try using moment-timezone for timezone related ops
The following might help you
const moment = require("moment-timezone");
var beforeTime = moment.tz("08:30", "hh-mm", "MST");
var afterTime = moment.tz("17:30", "hh-mm", "MST");
var date = moment("21-03-2020");
var mstWeekday = moment(date, "d", "MST");
if (
date.isBetween(beforeTime, afterTime) &&
(mstWeekday !== 6 || mstWeekday !== 7)
) {
console.log("in here");
}
This is what I ended up doing (didn't even need moment.js):
var beforeTime = 1430; // 8:30 AM MST in UTC
var afterTime = 2330; // 5:30 PM MST in UTC
var date = new Date();
var currentHours = date.getUTCHours();
var currentMinutes = leadingZero(date.getUTCMinutes());
var currentTime = parseInt('' + currentHours + currentMinutes); // Make 24 hour (0000)
var currentDayMst = date.toLocaleString("en-US", {timeZone: "America/Edmonton"}); // Get current day of week in MST
currentDayMst = new Date(currentDayMst);
currentDayMst = currentDayMst.getDay();
// If not between 8:30am and 5:30pm OR Saturday OR Sunday, do stuff
if ( !( (currentTime >= beforeTime) && (currentTime <= afterTime) ) || (currentDay == 6) || (currentDay == 0) ) {
// Do stuff
}
function leadingZero (i) {
if (i < 10) {
i = "0" + i;
}
return i;
}
I would like to compare two dates in this format dd mmm yyyy, compare validators wont work because of the format and custom validator is server side validation. I would like to have a clinet side validation. What would be the best way to do it? if you have any examples or links please let me know.
I dont know if there are options availables with ajax, jquery or javascript that can do this?
Cheers
Since JavaScript natively converts from MMM dd, yyyy, this would be one approach:
var date1Str = "09 Sep 2011";
var date2Str = "04 May 2012";
var dateParts = date1Str.split(" ");
var newDateStr = dateParts[1] + " " + dateParts[0] + ", " + dateParts[2];
var date1 = new Date( newDateStr );
var dateParts = date2Str.split(" ");
var newDateStr = dateParts[1] + " " + dateParts[0] + ", " + dateParts[2];
var date2 = new Date( newDateStr );
if ( date1 > date2 )
...
There are tons of links on the net to do date parsing in JavaScript and plenty of libraries that make it easier. Remember that culture plays a part. "Oct" is in English but in German it will be "Okt".
Here's a simple class you can use to compare dates; the convert function has been adjusted to accommodate your format:
<script type="text/javascript">
var dates = {
convert:function(d) {
return (
d.constructor === Date ? d :
d.constructor === Array ? new Date(d[1],d[0],d[2]) :
d.constructor === Number ? new Date(d) :
d.constructor === String ? new Date(d) :
typeof d === "object" ? new Date(d.year,d.month,d.date) :
NaN
);
},
compare:function(a,b) {
return (
isFinite(a=this.convert(a).valueOf()) &&
isFinite(b=this.convert(b).valueOf()) ?
(a>b)-(a<b) :
NaN
);
},
inRange:function(d,start,end) {
return (
isFinite(d=this.convert(d).valueOf()) &&
isFinite(start=this.convert(start).valueOf()) &&
isFinite(end=this.convert(end).valueOf()) ?
start <= d && d <= end :
NaN
);
}
}
</script>
Credit for this class belongs to #some: https://stackoverflow.com/a/497790/879420
I need to do user validation of a date field, it should be in the format yyyyMMdd and should not be more than one year in the future. How would I go about doing this? Currently I only have a crude regexp which is insufficient.
function VerifyDate(source, args)
{
var regexp = /^([1-2]{1}[0-9]{1})\d{2}([0][1-9]|[1][0-2])([0][1-9]|[1-2][0-9]|[3][0-1])$/
var result = args.Value.match(regexp);
if(result) {
args.IsValid = true;
} else {
args.IsValid = false;
}
}
Take the regex to check the format only. You can stay simple:
^(\d{4})(\d{2})(\d{2})$
Then parse the date and check the range:
function VerifyDate(source, args)
{
args.IsValid = false;
var regexp = /^(\d{4})(\d{2})(\d{2})$/;
var daysInMonth = function (y, m) {return 32-new Date(y, m, 32).getDate(); };
var ma = regexp.exec(args.Value);
if (ma && ma.length == 4 && ma[2] < 12 && ma[3] <= daysInMonth(ma[1], ma[2]))
{
var diff = new Date(ma[1], ma[2], ma[3]) - new Date();
args.IsValid = diff < 31536000000; // one year = 1000ms*60*60*24*365
}
}
new Date() don't throw an exception if month or day is out of range. It uses the internal MakeDay to calculate a date (see ECMAScript Language Specification section 15.9.3.1 and 15.9.1.13). To make sure that the date is valid in the function below, the input is converted to integers who is converted to a date, and then the parts of the date are compared to the integers.
Since date uses MakeDay, the calculation of maxDate works even if now is the leep day (xxxx0229 will be yyyy0301 where yyyy=xxxx+1)
function verifyDate(args)
{
var result=false,
match = args.Value.match(/^(\d{4})(\d{2})(\d{2})$/);
if (match && match.length === 4)
{
var year = parseInt(match[1],10),
month =parseInt(match[2],10) -1, // 0 = January
day = parseInt(match[3],10),
testDate= new Date(year,month,day),
now = new Date(),
maxDate = new Date(now.getFullYear() + 1, now.getMonth(), now. getDate()),
minDate = new Date(1800,0,1),
result = (
testDate.getFullYear() === year &&
testDate.getMonth() === month &&
testDate.getDate() === day &&
testDate >= minDate &&
testDate <= maxDate
);
}
args.IsValue = result;
return result;
}
The solution I finally went with is a combination of your answers, I used datejs which seems pretty nice. Here is my final validation function. For some reason the month seems to use a 0 based index so that's why it says -1 in the .set().
function VerifyDate(source, args)
{
args.IsValid = false;
var regexp = /^(\d{4})(\d{2})(\d{2})$/;
var m = regexp.exec(args.Value);
if (m && m.length == 4) {
try {
var result = Date.today().set({ year: Number(m[1]), month: Number(m[2]-1), day: Number(m[3]) });
if (result < Date.today().add({ years: 1 })) {
args.IsValid = true;
}
}
catch (ex) {
}
}
}
I have been trying to find a really fast way to parse yyyy-mm-dd [hh:mm:ss] into a Date object. Here are the 3 ways I have tried doing it and the times it takes each method to parse 50,000 date time strings.
Does anyone know any faster ways of doing this or tips to speed up the methods?
castMethod1 takes 3673 ms
castMethod2 takes 3812 ms
castMethod3 takes 3931 ms
Code:
private function castMethod1(dateString:String):Date {
if ( dateString == null ) {
return null;
}
var year:int = int(dateString.substr(0,4));
var month:int = int(dateString.substr(5,2))-1;
var day:int = int(dateString.substr(8,2));
if ( year == 0 && month == 0 && day == 0 ) {
return null;
}
if ( dateString.length == 10 ) {
return new Date(year, month, day);
}
var hour:int = int(dateString.substr(11,2));
var minute:int = int(dateString.substr(14,2));
var second:int = int(dateString.substr(17,2));
return new Date(year, month, day, hour, minute, second);
}
-
private function castMethod2(dateString:String):Date {
if ( dateString == null ) {
return null;
}
if ( dateString.indexOf("0000-00-00") != -1 ) {
return null;
}
dateString = dateString.split("-").join("/");
return new Date(Date.parse( dateString ));
}
-
private function castMethod3(dateString:String):Date {
if ( dateString == null ) {
return null;
}
var mainParts:Array = dateString.split(" ");
var dateParts:Array = mainParts[0].split("-");
if ( Number(dateParts[0])+Number(dateParts[1])+Number(dateParts[2]) == 0 ) {
return null;
}
return new Date( Date.parse( dateParts.join("/")+(mainParts[1]?" "+mainParts[1]:" ") ) );
}
No, Date.parse will not handle dashes by default. And I need to return null for date time strings like "0000-00-00".
I've been using the following snipplet to parse UTC date strings:
private function parseUTCDate( str : String ) : Date {
var matches : Array = str.match(/(\d\d\d\d)-(\d\d)-(\d\d) (\d\d):(\d\d):(\d\d)Z/);
var d : Date = new Date();
d.setUTCFullYear(int(matches[1]), int(matches[2]) - 1, int(matches[3]));
d.setUTCHours(int(matches[4]), int(matches[5]), int(matches[6]), 0);
return d;
}
Just remove the time part and it should work fine for your needs:
private function parseDate( str : String ) : Date {
var matches : Array = str.match(/(\d\d\d\d)-(\d\d)-(\d\d)/);
var d : Date = new Date();
d.setUTCFullYear(int(matches[1]), int(matches[2]) - 1, int(matches[3]));
return d;
}
No idea about the speed, I haven't been worried about that in my applications. 50K iterations in significantly less than a second on my machine.
This was the fastest I could come up with after some fiddling:
private function castMethod4(dateString:String):Date {
if ( dateString == null )
return null;
if ( dateString.length != 10 && dateString.length != 19)
return null;
dateString = dateString.replace("-", "/");
dateString = dateString.replace("-", "/");
return new Date(Date.parse( dateString ));
}
I get 50k iterations in about 470ms for castMethod2() on my computer and 300 ms for my version (that's the same amount of work done in 63% of the time). I'd definitely say both are "Good enough" unless you're parsing silly amounts of dates.
I'm guessing Date.Parse() doesn't work?
Well then method 2 seems the best way:
private function castMethod2(dateString:String):Date {
if ( dateString == null ) {
return null;
}
if ( dateString.indexOf("0000-00-00") != -1 ) {
return null;
}
dateString = dateString.split("-").join("/");
return new Date(Date.parse( dateString ));
}
Because Date.parse() does not accept all possible formats, we can preformat the passed dateString value using DateFormatter with formatString that Data.parse() can understand, e.g
// English formatter
var stringValue = "2010.10.06"
var dateCommonFormatter : DateFormatter = new DateFormatter();
dateCommonFormatter.formatString = "YYYY/MM/DD";
var formattedStringValue : String = dateCommonFormatter.format(stringValue);
var dateFromString : Date = new Date(Date.parse(formattedStringValue));
var strDate:String = "2013-01-24 01:02:40";
function dateParser(s:String):Date{
var regexp:RegExp = /(\d{4})\-(\d{1,2})\-(\d{1,2}) (\d{2})\:(\d{2})\:(\d{2})/;
var _result:Object = regexp.exec(s);
return new Date(
parseInt(_result[1]),
parseInt(_result[2])-1,
parseInt(_result[3]),
parseInt(_result[4]),
parseInt(_result[5]),
parseInt(_result[6])
);
}
var myDate:Date = dateParser(strDate);
Here is my implementation. Give this a try.
public static function dateToUtcTime(date:Date):String {
var tmp:Array = new Array();
var char:String;
var output:String = '';
// create format YYMMDDhhmmssZ
// ensure 2 digits are used for each format entry, so 0x00 suffuxed at each byte
tmp.push(date.secondsUTC);
tmp.push(date.minutesUTC);
tmp.push(date.hoursUTC);
tmp.push(date.getUTCDate());
tmp.push(date.getUTCMonth() + 1); // months 0-11
tmp.push(date.getUTCFullYear() % 100);
for(var i:int=0; i < 6/* 7 items pushed*/; ++i) {
char = String(tmp.pop());
trace("char: " + char);
if(char.length < 2)
output += "0";
output += char;
}
output += 'Z';
return output;
}