Can someone explain this odd javascript date output? - javascript

https://jsfiddle.net/8cvhnwgs/1/
//new Date(year, month, day, hours, minutes, seconds, milliseconds)
$("#out").html(new Date(2015, 5, 31, 08, 25, 30, 0));
The date I give is May 31st, but it outputs July First, can someone explain why? Have I used arguments wrong?

The month parameter to the Date constructor is 0 indexed, so 5 is June, which only has 30 days.

Look at the Date. The month is an integer value starting from 0 to 11.
new Date(2015, 0, 31)
// Sat Jan 31 2015 00:00:00 GMT+0000 (UTC)
new Date(2015, 1, 31)
// Tue Mar 03 2015 00:00:00 GMT+0000 (UTC)
new Date(2015, 2, 31)
// Tue Mar 31 2015 00:00:00 GMT+0000 (UTC)
new Date(2015, 3, 31)
// Fri May 01 2015 00:00:00 GMT+0000 (UTC)
new Date(2015, 4, 31)
// Sun May 31 2015 00:00:00 GMT+0000 (UTC)
new Date(2015, 5, 31)
// Wed Jul 01 2015 00:00:00 GMT+0000 (UTC)

Try this:
$("#out").html(new Date(2015, 4, 31, 08, 25, 30, 0));
5 is June, and since there is no 31 in June, it goes to July 1st.

Related

How do you remove the last value in an array if it doesn't match the first value in the next array?

I might not be asking the right question here.
I'm retrieving bookings that have the first night and last night date and I'm trying to display on a calendar which dates are not available.
The date comes in as: firstNight: "2022-02-05" and currently, it needs to go out as Sat Feb 05 2022
In order to get a list of booked dates, I am doing the following:
const bookedDates = bedsData?.map(({ firstNight, lastNight }) => {
const newArrivalDate = new Date(firstNight + "T00:00")
const newDepartureDate = new Date(lastNight + "T24:00")
var getDaysArray = function (start, end) {
for (
var arr = [], dt = new Date(start);
dt <= end;
dt.setDate(dt.getDate() + 1)
) {
arr.push(new Date(dt).toDateString())
}
return arr
}
var daylist = getDaysArray(newArrivalDate, newDepartureDate)
daylist?.map((v) => v)
return daylist.join(", ")
})
This returns
0: undefined
1: "Sat Feb 05 2022, Sun Feb 06 2022, Mon Feb 07 2022, Tue Feb 08 2022, Wed Feb 09 2022, Thu Feb 10 2022, Fri Feb 11 2022, Sat Feb 12 2022"
2: undefined
3: "Sat Feb 12 2022, Sun Feb 13 2022, Mon Feb 14 2022, Tue Feb 15 2022, Wed Feb 16 2022, Thu Feb 17 2022, Fri Feb 18 2022, Sat Feb 19 2022"
4: "Sat Feb 19 2022, Sun Feb 20 2022, Mon Feb 21 2022, Tue Feb 22 2022, Wed Feb 23 2022, Thu Feb 24 2022, Fri Feb 25 2022, Sat Feb 26 2022"
5: undefined
6: undefined
7: "Sat Feb 26 2022, Sun Feb 27 2022, Mon Feb 28 2022, Tue Mar 01 2022, Wed Mar 02 2022, Thu Mar 03 2022, Fri Mar 04 2022, Sat Mar 05 2022"
8: "Sat Mar 05 2022, Sun Mar 06 2022, Mon Mar 07 2022, Tue Mar 08 2022, Wed Mar 09 2022, Thu Mar 10 2022, Fri Mar 11 2022, Sat Mar 12 2022"
9: undefined
10: undefined
11: "Fri Mar 25 2022, Sat Mar 26 2022, Sun Mar 27 2022, Mon Mar 28 2022, Tue Mar 29 2022"
To show which dates are booked I'm am using
if (bookedDates.join().includes(calDates)) {
style.textDecoration = "line-through"
style.color = "rgba(0, 0, 0, 0.25)"
}
The issue I'm facing is with dates that don't have a check out and check in on the same day. The "last day" and the "first day" of the next booking are still being included in the list of "bookedDates". However, they need to be "available" to check out or check in still.
I hope that makes sense... pretty lost with this one!
Thanks
I am not sure I understud, but isn't it just a confusion with start and end limits of your for loop ?
Did you try initializing with
if (firstNight!==lastNight) {
const newArrivalDate = new Date(firstNight + "T24:00")
const newDepartureDate = new Date(lastNight + "T00:00")
} else {
const newArrivalDate = new Date(firstNight + "T00:00")
const newDepartureDate = new Date(lastNight + "T00:00")
}
I presume that in new Date(lastNight + "T24:00") that lastNight is in the format YYYY-MM-DD. Because there is no offset, the string will be parsed as local and the date will be set to 00:00 on the following day, i.e. 2022-02-06T24:00 will create a date with an identical time value to 2022-02-07T00:00.
It seems your souce data is booked nights, which you want to do use to disable dates that can't be selected as checkout days. So wherever there is an un–booked night, the following day can be selected as a checkout day even if it's booked.
So when making the array of dates to disable, check for gaps and remove the first booked date. You'll have to deal with this in the UI to indicate that the date can't be booked for checkin.
Another method would be to create the booked nights array, then wherever there's a gap delete the following night as gaps must always be two dates. The first is available for check in only, the last for checkout only.
E.g.
// Parse YYYY-MM-DD as local, not UTC
function parseLocal(s) {
let [y,m,d] = s.split(/\D/);
return new Date(y, m-1, d);
}
// Format as YYYY-MM-DD
function format(date = new Date()) {
return date.toLocaleDateString('en-CA'); // YYYY-MM-DD
}
// Add day to date (modifies date)
function addDay(date = new Date()) {
date.setDate(date.getDate() + 1);
return date;
}
let bookings = [
{id: 0,
firstNight: '2022-02-05',
lastNight: '2022-02-09'
},
{id: 1,
firstNight: '2022-02-10', // Contiguous booking, no gap
lastNight: '2022-02-15'
},
{id: 2,
firstNight: '2022-02-17', // Gap, 17th available for check out
lastNight: '2022-02-20'
},
{id: 3,
firstNight: '2022-02-21', // No gap, not avilable for checkout
lastNight: '2022-02-21'
},
{id: 4,
firstNight: '2022-02-22', // No gap, not avilable for checkout
lastNight: '2022-02-22'
},
{id: 4,
firstNight: '2022-02-24', // Gap, avilable for checkout
lastNight: '2022-02-24'
},
{id: 4,
firstNight: '2022-02-25', // No gap, not avilable for checkout
lastNight: '2022-02-25'
}
]
let bookedDates = bookings.map(
({firstNight, lastNight}) => [parseLocal(firstNight), parseLocal(lastNight)]
).reduce((dates, [firstNight, lastNight], i, mapDates) => {
// If lastNight of previous booking is not prevNight,
// don't add firstNight to array
let prevBookedNight = i? mapDates[i-1][1] : null;
if (i && format(addDay(prevBookedNight)) != format(firstNight)) {
addDay(firstNight);
}
while (firstNight <= lastNight) {
dates.push(format(firstNight));
firstNight.setDate(firstNight.getDate() + 1);
}
return dates;
},[]);
console.log('Not available for check in or out:\n' + bookedDates.join('\n'));

Getting value of specific time in next week

I am trying to get the value of next week ( + 7 days) at 09:00. I can get the Date using
new Date().setDate(new Date().getDate() + 7)
For example, it returns: 1619343639426
which translates to
new Date(1619343639426)
Sun Apr 25 2021 15:10:39 GMT+0530 (India Standard Time)
I want to get the value for Sun Apr 25 2021 09:00:00 GMT+0530 (India Standard Time)
how to do that ?
Try
new Date(new Date().setDate(new Date().getDate() + 7)).setHours(9, 0, 0, 0)

Why this JavaScript date() is weird?

When I run the following JavaScript code it returns
new Date(2017, 5, 31)
// Sat Jul 01 2017 00:00:00 GMT+0530 (IST)
Here I understand months are zero based in Date() so it overflows to July. But when I run following
new Date(2017, 12, 31)
// Wed Jan 31 2018 00:00:00 GMT+0530 (IST)
Here why the date is Jan 31 instead of throwing an exception?
new Date(2017, 13, 31)
// Sat Mar 03 2018 00:00:00 GMT+0530 (IST). Why Mar 03 instead of Mar 31?
Thanks
new Date(2017, 5, 31)
// Sat Jul 01 2017 00:00:00 GMT+0530 (IST)
June has only 30 days, so the balance 1 day (31 - 30 = 1) overflow to become July 01.
new Date(2017, 12, 31)
// Wed Jan 31 2018 00:00:00 GMT+0530 (IST)
Similarly, year 2017 has only 12 months, so the balance 1 month overflow to become 2018 Jan. Coincidently, January has 31 days too, so it becomes 2018 Jan 31 (31 - 31 = 0).
new Date(2017, 13, 31)
// Sat Mar 03 2018 00:00:00 GMT+0530 (IST). Why Mar 03 instead of Mar 31?
By that logic, year 2017 has only 12 months, so the balance 2 months overflow to become 2018 February.
Unfortunately, Febraury of 2018 has only 28 days, so the balance 3 days (31 - 28 = 3) overflow to become March 03.

Why does Javascript's Date() function break for my birthday in Safari?

Javascript running in Safari has a problem with my birthday. This sometimes breaks validation in forms for me (as forms check the input with the javascript output, and the days don't match anymore). I'd love to know why this happens.
My birthday is 6th Oct 1985. In Javascript, I create this using:
new Date(1985, 09, 06)
(Note that months are zero-indexed, but days and years are not.)
// My birthday
console.log("1985, 09, 06: " + new Date(1985, 09, 06))
// One day earlier/later
console.log("1985, 09, 07: " + new Date(1985, 09, 07))
console.log("1985, 09, 05: " + new Date(1985, 09, 05))
// One month earlier/later
console.log("1985, 10, 06: " + new Date(1985, 10, 06))
console.log("1985, 08, 06: " + new Date(1985, 08, 06))
// One year earlier/later
console.log("1986, 09, 06: " + new Date(1986, 09, 06))
console.log("1984, 09, 06: " + new Date(1984, 09, 06))
Results running this in Safari are:
// My birthday (note the day is wrong, and the time is 11pm)
Sat Oct 05 1985 23:00:00 GMT+1000 (AEST)
// One day earlier/later
Mon Oct 07 1985 00:00:00 GMT+1100 (AEDT)
Sat Oct 05 1985 00:00:00 GMT+1000 (AEST)
// One month earlier/later
Wed Nov 06 1985 00:00:00 GMT+1100 (AEDT)
Fri Sep 06 1985 00:00:00 GMT+1000 (AEST)
// One year earlier/later
Mon Oct 06 1986 00:00:00 GMT+1100 (AEDT)
Sat Oct 06 1984 00:00:00 GMT+1000 (AEST)
https://jsfiddle.net/27bupLr9/
In Chrome, my birthday is created correctly:
console.log(new Date(1985, 09, 06))
Sun Oct 06 1985 00:00:00 GMT+1000 (AEST)
This has been resolved in macOS High Sierra.

Adding numbers bi-weekly in javascript

Just want a help for adding numbers bi-weekly.
Let's say,
Start date : Jan 15, 2012
End date : May 15, 2012
Value : 300.00
What I want to accomplish is that, every 15th and last day of the month 300 will be multiplied to how many 15th and last day before May 15, 2012
so
Jan 15, 2012 to Jan 31, 2012 the value must be 300.00
Feb 01, 2012 to Feb 15, 2012 the value must be 600.00
Feb 16, 2012 to Feb 28/29, 2012 the value must be 900.00
Mar 01, 2012 to Mar 15, 2012 the value must be 1200.00
Mar 16, 2012 to Mar 31, 2012 the value must be 1500.00
Apr 01, 2012 to Apr 15, 2012 the value must be 1800.00
Apr 16, 2012 to Apr 30, 2012 the value must be 2100.00
May 01, 2012 to May 15, 2012 the value must be 2400.00
hope you get what I mean.
Hoping for your helpful replies, Thanks.
You can loop as long as you have whole months, then check if there is a half month to add at the end:
var date = startDate;
var sum = 0;
while (date < endDate) {
sum += value * 2;
date.setMonth(date.getMonth() + 1);
}
if (date < endDate) sum += value;

Categories