Datepicker can't subtract properly on 2/28? - jquery-ui

I don't think I'm hallucinating as I've tried it a dozen times. Here's my code:
$('#teo_prep_due').change(function() {
var ber = $('#ber_rcvd');
var tpd = $('#teo_prep_due');
var brDate = ber.datepicker('getDate');
var tpDate = tpd.datepicker('getDate');
var s1Date = new Date();
var s2Date = new Date();
var sdDate = new Date();
s1Date.setDate(brDate.getDate() + 5);
console.log(s1Date);
s2Date.setDate(tpDate.getDate() - 3);
console.log(s2Date);
if (s1Date < s2Date) {
sdDate.setDate(s1Date.getDate());
} else {
sdDate.setDate(s2Date.getDate());
}
$('#survey_due').datepicker('setDate', sdDate);
});
On my date form, I've entered February 28, 2013 for ber_rcvd and March 14, 2013 for teo_prep_due. Following the code, my result should be March 5, 2013. However, s2Date is resulting in February 11, 2013, as if a full month and 3 days are being subtracted instead of just 3 days. Has anyone else run into this?
Using: jquery-1.9.1.min.js, jquery-migrate-1.1.1.js and jquery-ui-1.10.1.min.js.
http://jsfiddle.net/devlshone/veP7b/

The problem is that .setDate() does not set the date, it sets the day of the month. It takes an integer as an argument. When you created s2Date it defaulted to today, which is in February. When you add tpDate.getDate()// equals 14 with -3, you get 11, and therefore February 11th.

Related

Iterate through range and match values

I have a spreadsheet with two sheets: Week#, Events.
Sheet "Week#" (calendar week # in Column A and the start day of this week in Column B):
01 January 4, 2016
02 January 11, 2016
03 January 18, 2016
04 January 25, 2016
05 February 1, 2016
and so on till week 52
Sheet "Events" has next columns:
Facility, Repeats, Belongs to week #, Week # starts on, Item, Action, Status.
It's filled with something like this (number of rows varies):
SalonA, monthly, 4, January 25,2016, Floor, to mop the floor, Created
The script is like this:
function createEventmanually (title, date)
{
var sheet = SpreadsheetApp.getActiveSheet();
var row = sheet.getActiveRange().getRowIndex();
var EventStatus = sheet.getRange(row, 7).setValue("Created");
var title = sheet.getRange(row,1).getValue()+" "+"Week "+sheet.getRange(row,3).getValue()+" "+sheet.getRange(row,5).getValue()+":"+" "+sheet.getRange(row,6).getValue();
var cal = CalendarApp.getCalendarsByName('RM') [0];
var date = sheet.getRange(row,4).getValue();
var event = cal.createAllDayEvent(title, date);
}
I manually copy and paste calendar dates from sheet Week# to column "Week # starts on" in sheet Events. And then run the script every time to create event.
How to automatize this process? I understand that it could be done through iteration but I cannot figure it out.
Thank you in advance.
If what you want is 52 calendar events (One every week) for every different
task in the Events sheet, this code is how you would need to do it.
function createAllEventsForTheYear() {
var allRowsOfDataInEventSheet,allDataInWeekSheet,cal,eventSh,i,j,L,Lj,lastRowInEventSheet,lastRowInWeekSheet,
lastColumnInEventSheet,lastColInWeekSh,ss,row,
weekNumberSheet,rowDataBeingProcessedFromEventsSheet,thisEventTitle,thisWeeksDate;
cal = CalendarApp.getCalendarsByName('RM')[0];
ss = SpreadsheetApp.getActiveSpreadsheet();
eventSh = ss.getSheetByName('Events');
weekNumberSheet = ss.getSheetByName('Week#');
lastRowInEventSheet = eventSh.getLastRow();
lastRowInWeekSheet = weekNumberSheet.getLastRow();
lastColumnInEventSheet = eventSh.getLastColumn();
lastColInWeekSh = weekNumberSheet.getLastColumn();
allRowsOfDataInEventSheet = eventSh.getRange(2, 1, lastRowInEventSheet-1, lastColumnInEventSheet).getValues();
allDataInWeekSheet = weekNumberSheet.getRange(2, 1, lastColInWeekSh-1, lastColInWeekSh).getValues();
L = allRowsOfDataInEventSheet.length;
Lj = allDataInWeekSheet.length;
for (i=0;i<L;i+=1) { //Loop through every row of data in the Events sheet
rowDataBeingProcessedFromEventsSheet = allRowsOfDataInEventSheet[i];//Get one row of data
thisEventTitle = rowDataBeingProcessedFromEventsSheet[0] + "Week" + rowDataBeingProcessedFromEventsSheet[2] + " " + rowDataBeingProcessedFromEventsSheet[4] + ": " + rowDataBeingProcessedFromEventsSheet[5];
for (j=0;j<Lj;j+=1) {//For every row in the Events sheet, create an event for every week of the year. 52 events for this event type
thisWeeksDate = allDataInWeekSheet[j][1];//Get the date from the second column of the data in the Weeks# sheet
cal.createAllDayEvent(thisEventTitle, thisWeeksDate);
};
eventSh.getRange(i+2, 7).setValue("Created");//I starts at 0, data starts on row 2
};
};
I have not tested this, or even debugged it, so it may not run perfectly.

Google sheet - weekly minimum count

I have a google spreadsheet list, with two columns (200+rows and counting), that looks like this:
Monday 495,636,792
Tuesday 891,243,349
Wednesday 465,844,622
Thursday 425,461,946
Friday 412,401,861
Saturday 424,297,897
Sunday 462,782,430
Monday 454,216,725
Tuesday 1,661,014,800
Wednesday 502,935,706
Thursday 493,009,684
Friday 464,568,911
Saturday 670,963,371
Sunday 491,847,275
(I also have a regular date column, not just the weekdays - if needed)
I would like to count the weekly minimum.
This basically means that I would like an other list that would look like this:
Monday 10
Tuesday 15
Wednesday 20
Thursday 0
Friday 9
Saturday 7
Sunday 25
Monday - 10 would mean, that there were 10 weeks, where Monday had the smallest number during that week.
Sorry I did not understand correctly. This is mot as hard. See corrected code below. The sample sheet is also corrected.
function minDays() {
var s= SpreadsheetApp.getActiveSpreadsheet().getSheets()[1];
var ss = SpreadsheetApp.getActiveSpreadsheet().getSheets()[0];
var clr = s.getRange(2,2,7,1).clear()
var lr = ss.getLastRow()-1
var slr = 7
var sr = 2
var weeks = lr/7
for(w=1;w<weeks+1;w++){
if(w==1){sr=sr,slr==slr} else {sr=sr+7,slr=slr+7}
var sVal = ss.getRange(sr,1,slr,2).getValues();
var minVal =sVal[1][1]
var minDay =sVal[0][0]
for (var i = 1; i < 7;i++) {
if(sVal[i-1][1]<=minVal){minVal=sVal[i-1][1],minDay=sVal[i-1][0]} else{minVal=minVal,minDay=minDay}
var fVal=minVal
var fday = minDay
}
var target=s.getRange(2,1,7,2).getValues();
for(var n in target){
var row = target[n][0]
if(row.toString().match(fday)){
var cnt = target[n][1].valueOf()+1
target[n][1]=cnt
}}
var rDay =s.getRange(2, 1,7,2)
var data=rDay.getValues()
rDay.setValues(target)
}}
https://docs.google.com/spreadsheets/d/1AFHeNKeonLDuuOyg7GaTvMB4asvnYHbK2C0WAEbfSsI/edit?usp=sharing

How to find last day of month?

I am trying the new Google Dart language and I don't know how to get the last day of the current month?
This gives me current date:
var now = new DateTime.now();
Providing a day value of zero for the next month gives you the previous month's last day
var date = new DateTime(2013,3,0);
print(date.day); // 28 for February
If you want to get the last date of the current month, you need to refer to the 0th day of the next month
Try this in an easy way:
DateTime now = DateTime.now();
int lastday = DateTime(now.year, now.month + 1, 0).day;
Here's one way to find it:
var now = new DateTime.now();
// Find the last day of the month.
var beginningNextMonth = (now.month < 12) ? new DateTime(now.year, now.month + 1, 1) : new DateTime(now.year + 1, 1, 1);
var lastDay = beginningNextMonth.subtract(new Duration(days: 1)).day;
print(lastDay); // 28 for February
I have the current date, so I construct the first day of the next month, and then subtract one day out of it. I'm also taking the change of the year into account.
Update: Here's a little bit shorter code for the same thing, but inspired by Chris's zero-trick:
var now = new DateTime.now();
// Find the last day of the month.
var lastDayDateTime = (now.month < 12) ? new DateTime(now.year, now.month + 1, 0) : new DateTime(now.year + 1, 1, 0);
print(lastDayDateTime.day); // 28 for February
It has the additional check/code, in case you want to do this programmatically (e.g. you have a specific month as an integer).
Here's an extension that might help. (Ref. from Kai's and Chris's answers.)
extension DateTimeExtension on DateTime {
DateTime get firstDayOfWeek => subtract(Duration(days: weekday - 1));
DateTime get lastDayOfWeek =>
add(Duration(days: DateTime.daysPerWeek - weekday));
DateTime get lastDayOfMonth =>
month < 12 ? DateTime(year, month + 1, 0) : DateTime(year + 1, 1, 0);
}
Another way is using Jiffy. It has the endOf method that makes easy to get the last moment of several units, in this case the month:
Jiffy().endOf(Units.MONTH);
While all this answers are correct & do give you the last DAY of the month :
like so : year-month-lastDay 00:00:00.000 -> beginning of the last day of the month
You might need the last bound / DateTime of the month :
like so : year-month-lastDay 23:59:59.999 -> end of the last day of the month
Here is how to get the two bounds within a month with the help of an extension on DateTime :
extension MonthsBounds on DateTime {
DateTime get lastMillisecondOfMonth =>
month < 12 ? DateTime(year, month + 1, 1, 00, 00, 00, -1) : DateTime(year + 1, 1, 1, 00, 00, 00, -1);
DateTime get firstMillisecondOfMonth => DateTime(year, month, 1);
}
print('${DateTime(2022, 12, 14).lastMillisecondOfMonth}'); // 2022-12-31 23:59:59.999
DateTime first = DateTime(month.value.year, month.value.month, 1);
DateTime end = Jiffy(first).add(months: 1, days: -1).dateTime;

What hour repeats in Daylight standard time

I currently have a list of DateTimes stored as the timezone's UTC datetime. When I go to convert from UTC to local datetime and when the date falls on the start of Daylight Standard time, the hour that repeats is 1am and not 2am.
I use the following to convert from UTC to local time. Notice that 1am repeats in local1 and local2. I expected 2am to repeat.
Which is correct?
TimeZoneInfo tz = TimeZoneInfo.FindSystemTimeZoneById("Mountain Standard Time");
//UTC time
var utc1 = new DateTime(1990, 10, 28, 7, 0, 0); //This is start of daylight standard time.
var utc2 = new DateTime(1990, 10, 28, 8, 0, 0);
var utc3 = new DateTime(1990, 10, 28, 9, 0, 0);
utc1 = DateTime.SpecifyKind(utc1, DateTimeKind.Utc);
utc2 = DateTime.SpecifyKind(utc2, DateTimeKind.Utc);
utc3 = DateTime.SpecifyKind(utc3, DateTimeKind.Utc);
//Get the local time with adjustment for Daylight standard time, "fall back"
var local1 = TimeZoneInfo.ConvertTimeFromUtc(utc1, tz); //Returns 1am
var local2 = TimeZoneInfo.ConvertTimeFromUtc(utc2, tz); //Returns 1am. Should this be 2am?
var local3 = TimeZoneInfo.ConvertTimeFromUtc(utc3, tz); //Returns 2am
At 2am you "fall back" to 1am (1:59 -> 1), hence 1am is repeated and 2am only occurs one hour later. similarly when you "spring forward" there would be NO 2 AM (1:59 -> 3)
source: http://aa.usno.navy.mil/faq/docs/daylight_time.php (US Naval Observatory keeps the US DoD official time (source for that: http://www.usno.navy.mil/USNO/time))

Jquery UI Datepicker with EOM and MOM

I need implement a Jquery UI Calendar that when a users click any date, it select automatically to the next MOM or EOM.
For example, if the user clicks on April 9th, it must go to 'April 15th',
or if clicks on 22 February, it must go to 'Feb 28' or 'Feb 29'.
For clarification:
MOM is "Middle of Month, every time is 15th", from 1 to 15 of any month.
EOM is "End of Month, it's the last day of the month, jan 31, feb 28 or 29, mar 31, apr 30, may 31, jun 30, july 31, aug 31, sep 30, oct 31, nov 30, dec 31...
Thanks
I would do this as a standard jquery onchange handler for the text box. The reason is that a user can bypass the date-picker and type in a date manually. You want the date to automatically be changed no matter if the date is selected, typed in, or pasted in.
Use the onSelect event from datepicker. Be aware that if you have maxDate option set and its before EOM or MOM the value selected will be maxDate.
UPDATE: Close after select. Use onClose instead.
UPDATE2: jsFiddle using latest jQuery UI
onClose: function(dateText, inst) {
var day = inst.currentDay,
month = inst.currentMonth,
year = inst.currentYear;
if (day <= 15) {
day = 15;
}
else {
day = 0;
if (month>10){
month = 0;
year++;
}
else
month++;
}
var d = new Date(year, month, day);
$(this).datepicker("setDate", d);
}
The code that works with IE6/IE7/IE8/IE9 and FF, Chrome, etc.
<script type="text/javascript">
$(function() {
$("#payperiodcalendar input").datepicker({
dateFormat: 'dd-M-yy',
onSelect: function(dateText, inst) {
var selectedDay = inst.currentDay,
selectedMonth = inst.currentMonth,
selectedYear = inst.currentYear;
if (selectedDay <= 15) {
var now = new Date(selectedYear, selectedMonth, 15);
} else {
var now = new Date(selectedYear, selectedMonth, LastDayOfMonth(selectedYear, selectedMonth));
}
$(this).attr("value", now.format("dd-MMM-yyyy"));
}
});
function LastDayOfMonth(Year, Month) {
Month++;
return (new Date((new Date(Year, Month, 1)) - 1)).getDate();
}
});
</script>

Resources