for in loop not working as expected javascript - javascript

I have an object, Object { 2014-01-30=[1], 2014-02-01=[1]}
and an array called fechasPeriodo,
so why is the following code:
fechasPeriodo = [];
for(var property in SelectedDates) {
fechasPeriodo.push(new Date(property));
}
producing this result [Date {Wed Jan 29 2014 18:00:00 GMT-0600}, Date {Fri Jan 31 2014 18:00:00 GMT-0600}]
Edit: I'd expect the result to be Thu Jan 30 2014 etc. , Sun 02 Feb 2014.
Actually it's a problem only because I'm trying to define a range of dates in datepicker using a Google Calendar feed. So the following code:
if(fechasPeriodo.length > 1) {
r[1] = fechasPeriodo[0] <= date && date <= fechasPeriodo[1] ?"Highlighted"+SelectedDates[key][0].replace(/\s/g, "_"):"Highlighted-unknown";
}
I'd expect to highlight a range from the 30th Jan to the 02nd of February. But if you can guide me as to why it isn't working, I'd be very grateful, I'm following this fiddle:
http://jsfiddle.net/qaEuj/
At the risk of being downvoted again I have to say that I still don't understand why my last bit of code above isn't working like the fiddle I mention, so here's my complete code:
$(document).ready(function() {
var fechaDefecto = new Date('2014/01/01');
var fechaFin = new Date('2014/08/31');
SelectedDates = null;
/*SelectedDates[new Date('12/25/2014')] = new Date('12/25/2014');
SelectedDates[new Date('12/12/2014')] = new Date('12/12/2014');
SelectedDates[new Date('06/06/2014')] = new Date('06/06/2014');*/
$('#tiposFechas').change(function() {
$.getJSON("https://www.google.com/calendar/feeds/cide.edu_sm151i2pdhu2371vq8hamcver4#group.calendar.google.com/public/full?q="+encodeURI($(this).val()), {"alt" : "json"}, function(data) {
SelectedDates = {};
$.each(data.feed.entry, function(i, entry) {
var key = entry.gd$when[0].startTime.substr(0, 10)
var clave = entry.gd$when[0].endTime.substr(0, 10);
if(key in SelectedDates === false || clave in SelectedDates === false) {
SelectedDates[key] = [];
SelectedDates[clave] = [];
}
SelectedDates[key].push(entry.title.$t);
SelectedDates[clave].push(entry.title.$t);
});
$('#cal').datepicker("refresh");
});
});
$('#cal').datepicker(
{
beforeShowDay: function (date) {
var r = [true, ""];
if (SelectedDates === null) {
r[1] = "Highlighted-unknown";
}
else {
fechasPeriodo = [];
for(var property in SelectedDates) {
fechasPeriodo.push(new Date(property));
//alert(property);
}
var key = $.datepicker.formatDate("yy-mm-dd", date);
if(key in SelectedDates) {
if(fechasPeriodo.length > 1) {
r[1] = fechasPeriodo[0] <= date && date <= fechasPeriodo[1] ?"Highlighted"+SelectedDates[key][0].replace(/\s/g, "_"):"Highlighted-unknown";
}
else {
r[1] = "Highlighted"+SelectedDates[key][0].replace(/\s/g, "_");
}
r[2] = SelectedDates[key].join(", ");
}
}
return r;
},
minDate : fechaDefecto,
maxDate : fechaFin,
numberOfMonths: [3,3]
});
});
I'm hoping someone points out a cause, even if it's a criticism, because it's getting late.
I must say I tried this:
r[1] = new Date(fechasPeriodo[0].getYear(), fechasPeriodo[0].getMonth(), fechasPeriodo[0].getDate()) <= date && date <= new Date(fechasPeriodo[1].getYear(),fechasPeriodo[1].getMonth(),fechasPeriodo[1].getDate()) ?"Highlighted"+SelectedDates[key][0].replace(/\s/g, "_"):"Highlighted-unknown";
But didn't work either. May there be a problem in the way I'm representing the dates when I call new Date in the line fechasPeriodo.push(new Date(property)); and the way I'm comparing them?

It's just the difference between the UTC and non-UTC representation.
new Date('2014-01-30').toString(); //Wed Jan 29 2014 19:00:00
new Date('2014-01-30').toUTCString(); //Thu, 30 Jan 2014 00:00:00
Try fechasPeriodo[0].toUTCString(); and I'm pretty sure it will return what you expect.

Related

Google Apps Script: Is a date part with a range

I would like to determine what season a date falls between. The date is in a cell and is not related to the current date.
I have gotten this far:
var myDate=myForm.getRange("C4").getValue();
if (Utilities.formatDate(myDate, "GMT", 'MM/dd')>'12/21' && Utilities.formatDate(myDate, "GMT", 'MM/dd')<'3/20'){
ui.alert("Winter")
}
I would repeat this obviously for other seasons.
My expectation is that 1/13/2023 evaluates to 1/13 by (Utilities.formatDate(myDate, "GMT", 'MM/dd') and falls with the range.
That is not happening
Thanks in advance.
Here is an example of comparing today's date with the season.
function getSeason() {
try {
// per Farmers Almanac
let season = ["Winter","Spring","Summer","Fall"];
let seasons = [["12/21/2021","3/20/2022","6/21/2022","9/22/2022","12/21/2022","3/20/2023"],
["12/21/2022","3/20/2023","6/21/2023","9/23/2023","12/21/2023","3/20/2024"],
["12/21/2023","3/19/2024","6/20/2024","9/22/2024","12/21/2024","3/20/2025"],
["12/21/2024","3/20/2025","6/20/2025","9/22/2025","12/21/2025","3/20/2026"],
["12/21/2025","3/20/2026","6/21/2026","9/22/2026","12/21/2026","3/20/2027"]];
let today = new Date();
let year = today.getFullYear()-2022;
today = new Date(today.getFullYear(),today.getMonth(),today.getDate());
let found = seasons[year].findIndex( (date,index) => {
return today >= new Date(date) && today < new Date(seasons[year][index+1]);
}
);
console.log(today);
console.log(season[found])
}
catch(err) {
console.log(err);
}
}
12:20:50 PM Notice Execution started
12:20:50 PM Info Mon Sep 12 2022 00:00:00 GMT-0700 (Pacific Daylight Time)
12:20:50 PM Info Summer
12:20:50 PM Notice Execution completed
Reference
Date object
Array.findIndex()
Season of the year:
function seasonOfTheYear(date) {
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName("Sheet0");
const ds = sh.getDataRange().getValues();
const sObj = { pA: [] };
ds.forEach(s => {
sObj[new Date(s[1]).valueOf()] = { start: new Date(s[1]), season: s[0] };
sObj.pA.push(new Date(s[1]).valueOf());
});
let dv = new Date(date).valueOf();
let ssn = sObj.pA.reduce((a, c, i) => {
if (dv >= c && dv < sObj.pA[(i + 1) % sObj.pA.length]) {
a["season"] = sObj[c].season;
}
return a;
}, {season:''}).season;
Logger.log(ssn);
}
I got this data from timeandate.com and put it into Sheet0
A
B
SPRING
Tuesday, March 1
SUMMER
Wednesday, June 1
FALL
Thursday, September 1
WINTER
Thursday, December 1

Converting any kind of date format to MM\DD\YYYY

I am converting this 2 sets of date to the format MM\DD\YYYY
1.Thu Aug 31 15:00:00 GMT+08:00 2017
2017-08-09
When I'm converting the 1st one I use this code.
var STD_Date = STD_data[i][4]; //<----This is where the date comes.
var date = convertDate(STD_Date);
var datearray = date.split("/");
var New_STDDate = datearray[1] + '/' + datearray[0] + '/' + datearray[2];
This is the function convertDate()
function convertDate(inputFormat) {
function pad(s) { return (s < 10) ? '0' + s : s; }
var d = new Date(inputFormat);
return [pad(d.getDate()), pad(d.getMonth()+1), d.getFullYear()].join('/');
}
This is how I format the second one.
This is the function
var toMmDdYy = function(input) {
var ptrn = /(\d{4})\-(\d{2})\-(\d{2})/;
if(!input || !input.match(ptrn)) {
return null;
}
return input.replace(ptrn, '$2/$3/$1');
};
This is how I use it.
var startdate = form.startdate //<--- comes from HTML Picker (Format "YYYY-MM-DD")
toMmDdYy(startdate)
My question is this how can I have a function that will format the date whether it is the 1st or the 2nd one?
Convert_TimeStamp_Date(){
//This is where to code will go to convert
//to MM\DD\YYYY
}
//Then call it
var startdate = "2017-08-08"
var timestamp = "Thu Aug 31 15:00:00 GMT+08:00 2017"
Convert_TimeStamp_Date(startdate);
Convert_TimeStamp_Date(timestamp);
//both of them the output must be "MM\DD\YYYY"
This is the current code but looking forward for a better one. WORKING
//Time Stamp to MM\DD\YYYY
function convertDate(inputFormat) {
function pad(s) { return (s < 10) ? '0' + s : s; }
var d = new Date(inputFormat);
var chopdate = [pad(d.getDate()), pad(d.getMonth()+1), d.getFullYear()].join('/');
var datearray = chopdate.split("/");
var newdate = datearray[1] + '/' + datearray[0] + '/' + datearray[2];
return newdate;
}
//YYYY-MM-DD tp MM\DD\YYYY
var toMmDdYy = function(input) {
var ptrn = /(\d{4})\-(\d{2})\-(\d{2})/;
if(!input || !input.match(ptrn)) {
return null;
}
return input.replace(ptrn, '$2/$3/$1');
};
//Convert Date based on input to MM\DD\YYYY
function ConverSpedDate(input){
if( input.lenght > 10 ) return toMmDdYy(input);
return convertDate(input);
}
This should work
convertDate = function( input ){
if( input.lenght > 10 ) return convertDate( input );
return toMmDdYy( input );
}
You can test each pattern and reformat accordingly. Your reformatting functions appear to be cumbersome and error prone, consider the following:
var startdate = "2017-08-23"
var timestamp = "Thu Aug 31 15:00:00 GMT+08:00 2017"
function reformatTimestamp(s) {
if (/\d{4}-\d\d-\d\d/.test(s)) {
return reformatISOtoMDY(s);
} else if (/[a-z]{3} [a-z]{3} \d\d \d\d:\d\d:\d\d \w{3}\+\d\d:\d\d \d{4}/i.test(s)) {
return reformatCustomToMDY(s);
}
}
// Reformat YYYY-MM-DD to MM\DD\YYYY
function reformatISOtoMDY(s) {
var b = s.split(/\D/);
return b[1] + '\' + b[2] + '\' + b[0];
}
function reformatCustomToMDY(s) {
var months = '. jan feb mar apr may jun jul aug sep oct nov dec'.split(' ');
var b = s.split(/ /);
return ('0' + months.indexOf(b[1].toLowerCase())).slice(-2) +
'\' + ('0' + b[2]).slice(-2) + '\' + b[5];
}
console.log(reformatTimestamp(startdate))
console.log(reformatTimestamp(timestamp))
The format MM\DD\YYYY is unusual and likely to confuse.
As you've tagged this as a GAS question, have you looked at Utilities.formatDate()? Documentation here, but in short it takes 3 parameters: a date object, a time-zone string & a format string. The TZ & format are taken from the Java SE SimpleDateFormat class.
In your instance, try this:
var ts = "Thu Aug 31 15:00:00 GMT+08:00 2017";
var d = new Date(ts);
Logger.log(Utilities.formatDate(d, "GMT+08:00", "MM/dd/yyyy")); // logs 08/31/2017
Note that you will have to set the time-zone in the output yourself. You could extract it from the timestamp via a regex, for example. As the JS Date primitive is milliseconds 1970-01-01T00:00:00 UTC, you can set your output TZ to suit your needs.
I also +1 the recommendations to stick to ISO date & time formats: MM/dd/yyyy absent locale information is just asking for trouble.

Google apps script if statement goes wrong

So, I am currently trying to check if a date from my Google spreadsheet cell matches some date I got from a HTML document. Here is the function that I use:
for (var i=0; i < data.length; i++) {
var testDate = subDaysFromDate(data[i][0],1)
var DateToCheck = Utilities.formatDate(testDate, "GMT", "dd-MM-yyyy");
var DateToCheckBefore = DateToCheck.split("-");
var DateToCheckAfter = new Date(DateToCheckBefore[2], DateToCheckBefore[1]-1, DateToCheckBefore[0]); //dit is de datum van een row
var d1 = $d1.split("-");
var d2 = $d2.split("-");
var from = new Date(d1[0], d1[1]-1, d1[2]); // -1 because months are from 0 to 11
var to = new Date(d2[0], d2[1]-1, d2[2]);
if(DateToCheckAfter >= from && DateToCheckAfter <= to){
var dataCheck = sheet.getRange("T2").getValue();
if(DateToCheckAfter == dataCheck){
Browser.msgBox('9 march?!', Browser.Buttons.OK);
}
Logger.log(dataCheck);
Logger.log(DateToCheckAfter);
}
}
As you can see it is obviously not finished yet, my question is; why does the following if statement not work??
if(DateToCheckAfter == dataCheck)
{
Browser.msgBox('9 march?!', Browser.Buttons.OK);
}
When I log the variables, the logger says:
[15-03-18 14:06:33:227 CET] Mon Mar 09 00:00:00 GMT+01:00 2015
[15-03-18 14:06:33:228 CET] Mon Mar 09 00:00:00 GMT+01:00 2015
So why is my if statement not working?
Well the answer was pretty simple..
DateToCheckAfter was a Date object and dataCheck was a string
if(DateToCheckAfter.toString() == dataCheck)
{
Browser.msgBox('9 march?!', Browser.Buttons.OK);
}
Fixed it

How to list all month between 2 dates with moment.js?

I've two dates
2015-3-30 2013-8-31
How can I make a month list like:
[ '2015-3', '2015-2', '2015-1', '2014-12', '2014-11', '2014-10', '2014-09', '2014-08', '2014-07', '2014-06', '2014-05'....., '2013-08' ]
Thanks.
This should do it:
var startDate = moment('2021-12-31');
var endDate = moment('2022-12-14');
var betweenMonths = [];
if (startDate < endDate){
var date = startDate.startOf('month');
while (date < endDate.endOf('month')) {
betweenMonths.push(date.format('YYYY-MM'));
date.add(1,'month');
}
}
I think the original answer isn't entirely correct, as you wouldn't get '2015-3' in your array. This is due to the fact your start date would eventually end up as '2015-3-31' and would fail the conditional in place. You could extend it like below.
UPDATE: I've now included cloning the dateStart variable so it isn't mutated at all.
var dateStart = moment('2013-8-31');
var dateEnd = moment('2015-3-30');
var interim = dateStart.clone();
var timeValues = [];
while (dateEnd > interim || interim.format('M') === dateEnd.format('M')) {
timeValues.push(interim.format('YYYY-MM'));
interim.add(1,'month');
}
You could try with this example
var one = moment("2015-3-30");
var two = moment("2014-8-31");
var dateDiffs = [];
var count = Math.round(moment.duration(one.diff(two)).asMonths());
month = two.month() + 1;
year = two.year();
for (var i=1; i<=count; i++) {
if (month > 12) {
month = 1;
year++;
}
dateDiffs.push(year+"-"+month);
console.log(month);
month++;
}
console.log(dateDiffs);
You are using multiple formats in the output: YYYY-MM and YYYY-M, so I picked the first. You can edit as you see fit.
var startDateString = "2012-5-30";
var endDateString = "2015-8-31";
var startDate = moment(startDateString, "YYYY-M-DD");
var endDate = moment(endDateString, "YYYY-M-DD").endOf("month");
var allMonthsInPeriod = [];
while (startDate.isBefore(endDate)) {
allMonthsInPeriod.push(startDate.format("YYYY-MM"));
startDate = startDate.add(1, "month");
};
console.log(allMonthsInPeriod);
document.getElementById("result").innerHTML = allMonthsInPeriod.join("<br />");
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.19.4/moment.min.js"></script>
<div id="result"></div>
const getMonths = (start, end) =>
Array.from({ length: end.diff(start, 'month') + 1 }).map((_, index) =>
moment(start).add(index, 'month').format('MM.YYYY'),
);
const months = getMonths(moment('01.2019','MM.YYYY'),moment('01.2020','MM.YYYY'))
console.log(months)
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.19.4/moment.min.js"></script>
This is the best way in my opinion.
const startDate = moment('2013-8-31', 'YYYY-M-DD');
const endDate = moment('2015-3-30', 'YYYY-M-DD');
const months = [];
const flag = startDate;
while (flag.diff(endDate) <= 0) {
months.push(flag.format('YYYY-M'));
flag.add(1, 'M');
}
Why don't you just https://date-fns.org/v2.13.0/docs/eachMonthOfInterval ??
// Each month between 6 February 2014 and 10 August 2014:
var result = eachMonthOfInterval({
start: new Date(2014, 1, 6),
end: new Date(2014, 7, 10)
})
//=> [
// Sat Feb 01 2014 00:00:00,
// Sat Mar 01 2014 00:00:00,
// Tue Apr 01 2014 00:00:00,
// Thu May 01 2014 00:00:00,
// Sun Jun 01 2014 00:00:00,
// Tue Jul 01 2014 00:00:00,
// Fri Aug 01 2014 00:00:00
// ]

Check if dates match in javascript

I'm creating a custom ASP.Net validator that checks if the data entered is a non working day.
The definition of "non working day" is:
The date is either a Saturday or Sunday
The date is a national holiday
I've coded the c# stuff and have created expando attributes for the error message and a string of holiday dates. Having done that, I've created a javascript function that contains this code to check for none working days. I've removed other code for brevity.
if (sender.NonWorkingDayErrorMessage && sender.Holidays) {
// Is weekend
if (date.getDay() == 6 || date.getDay() == 0) {
sender.innerHTML = sender.NonWorkingDayErrorMessage;
return;
}
// Is holiday
var holidays = sender.Holidays.split(";");
for (var i = 0; i < holidays.length; i++) {
var h = new Date(Date.parse(holidays[i]));
if (h === date) {
sender.innerHTML = sender.NonWorkingDayErrorMessage;
return;
}
}
}
The issue I have is that the code h === date is always false - here's the output I get when I add an alert and type in 26/8/2013.
Mon Aug 26 2013 00:00:00 GMT+0100 (GMT Standard Time) => Mon Aug 26 2013 00:00:00 GMT+0100 (GMT Standard Time) => false
As you can see I parse the holidays but I also test the input 'date' like this further up the function like this:
// Deconstruct string and reconstruct
// as date.
var parts = args.Value.split("/");
var day = parseInt(parts[0],10);
var month = parseInt(parts[1],10) -1;
var year = parseInt(parts[2],10);
var date = new Date(year, month, day);
// Valid date format but not a valid date
if (date.getFullYear() !== year || date.getMonth() !== month || date.getDate() !== day) {
sender.innerHTML = sender.InvalidErrorMessage;
return;
}
Anyone got ideas as to why these two dates aren't seen as matches?
Try like this
var a = new Date(2013,12,1);
var b = new Date(2013,12,1);
a.getTime() === b.getTime()

Categories