How can I compare two dates in format dd mmm yyyy? - asp.net

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

Related

FullCalendar change date format

When the user select a range of dates on the calendar, a modal opens and the input fields of initial and final dates are auto complete with the dates selected previously. The problem is that they are displaying in this format YYYY-MM-DD and I want it to be DD-MM-YYYY. I have tried everything but nothing seems to work.
Here is where I get the dates and fill the inputs:
select: function (info) {
$('#ModalAdd').modal('show');
$('#ModalAdd').appendTo("body");
$('#activoReservar').val($('#selectActivoReserva option:selected').text());
$('#fechaInicial').val(info.startStr);
var endDate = new Date(info.end);
var beforeDay = new Date(endDate.getFullYear(),endDate.getMonth(),endDate.getDate() - 1).toISOString().slice(0,10);
$('#fechaFinal').val(beforeDay);
},
And here are the things I have tried:
$('#fechaInicial').val(info.startStr.format('ddd, DD-MM-YYYY')); //i tried with dd and a single d too. And without any d
$('#fechaFinal').val(beforeDay.format('ddd, DD-MM-YYYY'));
you may create another function (which you can use anywhere else too),
pass a date to that function and return your desired format.
The sample function might look like as follow:
function dateToDMY(date) {
var d = date.getDate();
var m = date.getMonth() + 1; //Month from 0 to 11
var y = date.getFullYear();
return '' + (d <= 9 ? '0' + d : d) + '-' + (m <= 9 ? '0' + m : m) + '-' + y;
}
And you may call the function from select or any other place as follow:
select: function (selectionInfo) {
var startStr = dateToDMY(selectionInfo.start);
}

Check if a time is between two times and not on a weekend in a certain timezone with moment.js

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;
}

fullCalendar Comparing Times

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;
}

Verify a date in JavaScript

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) {
}
}
}

Actionscript 3 - Fastest way to parse yyyy-mm-dd hh:mm:ss to a Date object?

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;
}

Resources