CalendarExtender saying the wrong date is selected, possibly timezone related - javascript

I have a page with a TextBox and a CalendarExtender that is supposed to allow me to detect what date is selected. However, this is reporting the date that isn't selected.
<asp:TextBox ID="tbEffectiveDate" runat="server"
CssClass="input-small"
MaxLength="10"
Text='<%# Bind("NewEffectiveDate", "{0:MM/dd/yyyy}") %>'>
</asp:TextBox>
<ajaxToolkit:CalendarExtender ID="atkEffectiveDate" runat="server"
FirstDayOfWeek="Sunday"
TargetControlID="tbEffectiveDate"
Format="MM/dd/yyyy"
OnClientDateSelectionChanged="CheckForSunday">
</ajaxToolkit:CalendarExtender>
Essentially I'm making sure the user has selected a Sunday, but when I select a day on the calendar, the JavaScript says it is a day before. I'm perplexed.
function CheckForSunday(sender, args) {
var selectedDate = new Date();
selectedDate = sender.get_selectedDate();
// Both of these show the date before the date was selected
alert(sender.get_selectedDate());
if (selectedDate.getDay() != 0) {
// not a Sunday
var sunday = selectedDate;
// calculated the nearest Sunday
sunday.setDate(selectedDate.getDate() - selectedDate.getDay());
sender.set_selectedDate(sunday);
// tell the user that the date wasn't a Sunday
// and that the previous Sunday was selected.
$("#must-be-sunday").modal("show");
}
}
For example, if I select a Sunday, such as May 5th:
Then at the line alert(sender.get_selectedDate());, it displays
This is saying Saturday, May 4th is selected instead of May 5th. Since in my locale, we are -0700 and this is displaying 7 hours before midnight on the 5th, I'm guessing this has something to do with the timezone.
Does anyone know what may be causing this and how to fix it so it doesn't work with the time and only the date selected?

As usual, after writing everything out into a question on here, I've resolved my issue. This was indeed due to timezones, but still is very awkward. If someone has a better solution, I'd love to hear it.
Using getTimezoneOffset() and the solution from How to add 30 minutes to a JavaScript Date object?, I created a calculation to fix this.
var selectedDate = sender.get_selectedDate();
// get the timezone offset in minutes
var timeOffsetMinutes = selectedDate.getTimezoneOffset();
// Convert minutes into milliseconds and create a new date based on the minutes.
var correctedDate = new Date(selectedDate.getTime() + timeOffsetMinutes * 60000);
This corrected my issue and I get the date needed.

You right that the problem due to timezones as CalendarExtender use UTC dates for each day cell value. If you want to check day of week selected you may use Date.getUTCDay() function instead of the Date.getDay() and getUTCDate() instead of getDate() in OnClientDateSelectionChanged handler.

Related

Calculating date field based on another date field

I need to create a form with 2 date fields.
User will enter first date field (start-date) and I need to calculate 4 weeks from start date in the second date field (one-month-expiry). Better still: is there a way to calculate 1 calendar month instead of weeks?
I've managed to get the second field to populate a date - but it's not correct.
This is JavaScript, which I don't really understand. I've managed to get this far just by googling.
<script type="text/javascript">
document.getElementById('one-month-expiry').value
= (new Date(document.getElementById('start-date').valueAsDate
+ (6.04e+8 * 4)))
.format("dd/MM/yyyy");
</script>
It keeps returning the same date (29/01/1970). So I've obviously managed to stuff something up.
Any ideas how to include the first date field as part of my calculation?
<script type="text/javascript">
let date = new Date(document.getElementById('start-date').valueAsDate);
date.setMonth(date.getMonth() + 1);
document.getElementById('one-month-expiry').value = date.format("dd/MM/yyyy");
</script>
Beware that this might have some issues with edge cases. For example, adding one month to 31st January will give you 31st February, which does not exist, causing the date to roll over to 2nd March instead.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date

Exclude weekend dates from working days in JavaScript

So I am kinda stuck in figuring out a certain aspect. What I want to do is the following:
Let's say I just have a simple date display, which will show a date such as October 10th, 2017 to an end user. And then there is an option to subtract a certain number of days from said date (an offset of 1, 2, 3, whatever offset is chosen).
What I am looking to do is completely exclude weekend dates from the count - so if today is Monday, October 9th, and an offset of 1 is selected, it goes to Friday the 6th; if an offset of 2 is chosen, it goes to Thursday the 5th; an offset of 3 goes to Wednesday the 4th...
If today was Wednesday, October 11th, an offset of 2 would take you to Monday the 9th, an offset of 4 would go to Thursday the 5th, and so on (completely disregards / skips weekend dates when counting / subtracting which day to land on).
I have so far been able to only find answers for the functionality to calculate the number of working days excluding weekends, and things of that nature (which I already have, using the momentjs-business npm module, but is not exactly what I need).
I did not post code because this is part of a much larger code base, and I feel posting snippets would only add to the confusion, since I believe the question is relatively simply and straightforward; I do not want to over complicate.
All I would like is to not include weekends at all when setting an offset from whichever date is displayed to the user (the date which is displayed to the user is from a database).
I hope this all made sense, and if more info is needed, please let me know. Thanks in advance for anyone that can point me in the right direction!
This will achieve what you want I think. Please note this is terribly inefficient. If your offset is very large it generates a new date every iteration of the loop. With some tinkering it could be optimized
let startDate = new Date('10/10/2017');
let endDate = "", offset = 2;
while(offset > 0){
endDate = new Date(startDate.setDate(startDate.getDate() - 1));
if(endDate.getDay() !== 0 && endDate.getDay() !== 6){
offset--;
}
}
Here is a working Fiddle
You can use moment-business library. It has the subtractWeekDays that:
Subtract week days from the moment, modifying the original moment. Returns the moment.
Your code could be like the following:
var m = moment("October 10th, 2017", "MMMM Do, YYYY");
business.subtractWeekDays(m, 2);
If you don't want to add an external library, have a look at addWeekDays and subtractWeekDays code.
JavaScript date objects have a getDay() method that tells you what day of the week it is. You could use this to figure out which dates are weekends and exclude them.
var date = new Date();
var dayOfWeek = date.getDay();
console.log(dayOfWeek) // 1 for Monday, 2 for Tuesday, etc.

later.js - February and End of Month

I am creating a platform for recurring monthly orders.
I am using later.js for the recurrence. I have come across the following two cases and I am wondering if anybody has suggestions on how to better handle these (or if later.js handles them natively somehow):
later.parse.recur().on(31).dayOfMonth()
The date is the 31st of a given month. Current result is that is jumps months that end on the 30th. WORKAROUND: is to use last().dayOfMonth().
later.parse.recur().on(30).dayOfMonth()
later.parse.recur().on(31).dayOfMonth()
Month of February, ending on the 28th or 29th. How to handle if the date is 30th (or 31st). WORKAROUND: If date > 28th, add .and().on(59).dayOfYear()
Thanks!
I don't know the specifics of later.js, but apparently you can write something called a custom modifier: https://github.com/bunkat/later/blob/master/example/modifier.js
In addition to this, if you add a month to a javascript date (doesn't matter if the number becomes greater than 11/december), set the day of the month to the first then subtract 1 day, then you'll get the date of the last day in the originally given month. For example:
var a = new Date("2000-02-25");
var b = new Date(new Date(a.getFullYear(),a.getMonth()+1,1)-1);
console.log(b);

MomentJS get the previous friday

I have a user inputted date which I convert to a moment
var newDate = moment('01/02/2015');
What I need to do is get the previous friday relative to whatever date is passed in. How can I accomplish this?
I thought about doing something like this:
moment('01/02/2015').add('-1', 'week').day(5);
but wonder how reliable it would be.
newDate.day(-2);
It's that easy. :)
day() sets the day of the week relative to the moment object it is working on.
moment().day(0) always goes back to the beginning of the week. moment().day(-2)goes back two days further than the beginning of the week, i.e., last Friday.
Note: this will return to the Friday of the previous week even if newDate is on Friday or Saturday. To avoid this behavior, use this:
newDate.day(newDate.day() >= 5 ? 5 :-2);

Will assigning 0 to the 3rd parameter of a JavaScript Date() object always create an end of month date?

I'm working on a jQuery credit card expiration date validation script. Credit cards expire after the last day of the expiration month. For instance, if the card expires on 8/2013 then it's good through 8/31/2013.
In the past on the server side I've determined the last day of the month by adding 1 to the current month, then subtracting 1 day.
Today I noticed that when creating a new date, if 0 is applied to the 3rd parameter of the JavaScript Date() object, the resulting date will be the end-of-month day. But I've been unable to locate any online documentation to affirm this observation.
Here is some sample code.
var month = 10;
var year = 2013;
var expires = new Date(year, month, 0);
alert(expires);
And here is a jsFiddle example that I created.
This is a bit confusing, because I thought in JavaScript months were zero based. I've tested this in Chrome, Firefox, IE, and Safari, and the behavior appears consistent. The returned date consistently displays the last day of the month. This looks like a lucky find, but I'd really like to understand what is happening here.
Am I safe to run with this approach to assigning an end of month date, and if so is there some online documentation that I can point to which affirms this? Thanks.
Months are zero-based. That creates an end-of-month date in the previous month. Month 10 is November, so creating a date with day 0 in November gives you the end of October (month 9).
That is, day 0 in November means "the day before 1 November", which is the last day of October. Day -1 in November would be 30 October.

Categories

Resources