JavaScript Calculate time difference in known intervals - javascript

I'm Struggling with calculation of date time objects :(
We're getting three inputs from the user:
1. Start time of day
2. End time of day
3. Intervals between events (in minutes)
My target goal is to calculate how many events I have every day from start time to end time by the selected interval, and creating an array with the exact times of these events.
So far I'm getting the data in this way:
StartTime is a Datetime object.
EndTime is a Datetime object.
//Get start time
var HourOfStart = StartTime.getHours();
var MinuteOfStart = StartTime.getMinutes();
//Get end time
var HourOfEnd = EndTime.getHours();
var MinuteOfEnd = EndTime.getMinutes();
After calculating the differences of how many events in an hour and trying to cap the first and last events, I realised I must be doing something wrong (math is not my strong suit). Also converting to a unix timestamp got me baffled, because the events aren't starting at a round hour.
So in a nutshell, if the user enters:
Start time: 10:15
End time: 12:30
Interval: 15 minutes
I need to get the following array of event times:
10:30,10:45,11:00,11:15,11:30,11:45,12:00,12:15
Thanks!!

Here's a function that should do what you want. As suggested in the comments, just calculate the time in milliseconds and increment until you reach your stop time.
function calculate() {
var a = [];
var startValue = document.getElementById("startTime").value;
var endValue = document.getElementById("endTime").value;
var intervalValue = document.getElementById("interval").value;
var startDate = new Date("1/1/2015 " + startValue);
var endDate = new Date("1/1/2015 " + endValue);
var offset = intervalValue * 1000 * 60;
do {
startDate = new Date(startDate.getTime() + offset);
if (startDate < endDate)
a.push(startDate);
} while(startDate < endDate);
console.log(a);
}
<script src="http://gh-canon.github.io/stack-snippet-console/console.min.js"></script>
<label for="startTime">Start Time</label>
<input id="startTime" value="10:15" />
<br/>
<label for="endTime">End Time</label>
<input id="endTime" value="12:30" />
<br/>
<label for="interval">Interval</label>
<input id="interval" value="15" />
<br/>
<input type="button" onclick="calculate()" value="Calculate" />

Related

How do I grab the value of a date input?

So basically I want the price of "renting a boat" to change when a specific requirement is met. If the user selects a date that is on a weekday it will grab the value from the input field and the price will be 10$ per hour. If its a Saturday the price will be 15$ per hour, and if its a Sunday the price will be 20$ per hour. The user can rent it up to 10 hours and they will get a total price at the bottom.
All I have at the moment is the HTML code for the input fields, and I don't even know how to begin the JavaScript part. So if anyone can teach how to start that would be greatly appreciated!
<div id="main">
<label for="which_date">Which date do you want to rent?</label>
<input type="date" id="which_date_input" min="2022-05-02">
<button id="submit">Submit</button>
<label for="total_hours">How many hours do you want to rent? (Max 10 hours)</label>
<input type="number" id="total_hours_input" placeholder="0" min="1" max="10">
<p id="result"></p>
I'm sorry if the explanation of what I want is hard to understand, I'm a beginner when it comes to JavaScript.
Thanks
You can try something like this...
function getPrice() {
const whichDate = new Date(document.getElementById("which_date_input").value);
const totalHours = document.getElementById("total_hours_input").value;
let perHour = 10;
if (whichDate.getDay() === 6) {
perHour = 15;
}
if (whichDate.getDay() === 0) {
perHour = 20;
}
document.getElementById("result").innerText = "Total price: $" + totalHours * perHour;
}
<div id="main">
<label for="which_date">Which date do you want the ticket for?</label><br>
<input type="date" id="which_date_input" min="2022-05-02"><br>
<label for="total_hours">How many hours do you want to rent? (Max 10 hours)</label><br>
<input type="number" id="total_hours_input" placeholder="0" min="1" max="10">
<button id="submit" onclick="getPrice()">Submit</button><br>
<p id="result"></p>
</div>
This should give somewhat of a good indication of what you're trying to do.
You can use the input event along with target.value to get the value.
I'm getting value by destructuring: const {value} = target it's similar to target.value.
If you don't want to work with real-time results you can use something like submitButton.addEventListener('submit', ... instead where you set the submitButton via querySelector. but you will still need to read the same target.value from the "hours" input element if you decide to go that way.
// Do something with the results
const someAction = (amount) => {
console.log(`The amount is: £${amount}`)
}
// Get the input element
const totalHoursInput = document.querySelector("#total_hours_input")
// Listen to the input event
totalHoursInput.addEventListener("input", ({
target
}) => {
// Get the day name
const day = new Date().toLocaleString('en-us', {
weekday: 'long'
}).toLocaleLowerCase()
const { value } = target // The input value
// Determine the correct rate
let rate = 10 // Weekday default
if (day === "saturday") {
rate = 15
} else if (day === "sunday") {
rate = 20
}
// do something with the rate x value
someAction(rate * value)
})
<label for="which_date">Which date do you want the ticket for?</label>
<input type="date" id="which_date_input" value="" min="2022-05-02">
<button id="submit" onclick="getDate()">Submit</button>
<p id="result"></p>
<script>
function getDate() {
var x = document.getElementById("which_date_input").value;
document.getElementById("result").innerHTML = x;
}
</script>
now use what condition you want to apply on var X. the pick up date will store in x you can use for your conditions.

Limit the date to today and block the previous dates

I am beginner in JavaScript, I know the subject exists on StackOverFlow as here below but I don't understand.
Compare two dates with JavaScript
I would like to handle the previous dates for example: We are on 28-05-2020, if the user enters on 27-05-2020 an error message should appear.
For information, I am obliged to use JavaScript to handle the dates.
function validation()
{
const date_start = document.getElementById('date_start').value;
const inputDate = new Date(date_start);
const dayFromImputDate = inputDate.getFullYear(); // previous day
const now = new Date();
const dateNow = now.getFullYear();
if(dayFromImputDatee < dateNow) {
document.getElementById('date_startError').innerHTML = " ** Error date ! ";
return false;
}
if(date_start == ""){
document.getElementById('date_startError').innerHTML = " ** date empty ! ";
return false;
}
console.log("Date is valid");
return true;
}
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8">
<title>Titre de la page</title>
<link rel="stylesheet" href="style.css">
<script src="script.js"></script>
</head>
<body>
<form action="#" onsubmit="return validation()" >
<br>
<label>Date start : </label>
<br>
<input type="date" name="date_start" id="date_start">
<br>
<span id="date_startError"></span>
<br>
<input type="submit" value="ok">
</form>
</body>
</html>
Thank you very much for your help and your time.
You can check if input date is less than today's date using < operator
const form = document.querySelector('form');
const error = document.getElementById('date_startError');
function validation(event) {
event.preventDefault();
const startDate = form.elements['date_start'].value;
if (!startDate) {
error.innerHTML = " ** date empty ! ";
return;
}
const inputDate = new Date(startDate).getDate();
const today = new Date().getDate();
if (inputDate < today || !inputDate.valueOf()) {
error.innerHTML = " ** Error date ! ";
return;
}
error.innerHTML = "date is valid";
}
<form action="#" onsubmit="validation(event)">
<br>
<label>Date start : </label>
<br>
<input type="date" name="date_start" id="date_start" placeholder="2020-05-28">
<br>
<span id="date_startError"></span>
<br>
<input type="submit" value="ok">
</form>
Because HTML5 already has min and max attributes for the date input type, you don't need to implement a separate validation function to accomplish this. Here is a simpler way:
var date = new Date();
var iso_date = date.toISOString().substring(0, 10);
document.getElementById("date_start").setAttribute('min', iso_date);
Basically, you just get a new Date() object, extract and format it into an ISO 8601 date format, and set it into the min attribute. This also limits the browser selection calendar to future dates only.
If I understand the problem correctly you are trying to restrict a date form input to the current day or some future date.
To check whether a date is valid you could do this:
let earliestPossibleDate = new Date(
now.getFullYear(), now.getMonth(), now.getDate()
);
let isValidDate = date_start >= earliestPossibleDate
Three things:
You need to get your Current Date and set time to start of day.
You need to get your Selected Date and set time to start of day
Compare whether Selected Date is Greater or Equal to the Current Date.
Note that when you compare dates, you need to also consider the time.
Most calendar tools, include the time as a response to the selected date. You need to be aware of that.
This doesn't include other date validations. This will only solve the current problem at hand. Hope this helps! =)
const isValidDate = (selectedDate) => {
const currentDate = new Date();
// reset to start of day
currentDate.setHours(0);
currentDate.setMinutes(0);
currentDate.setSeconds(0);
currentDate.setMilliseconds(0);
const newDate = new Date(selectedDate);
newDate.setHours(0);
newDate.setMinutes(0);
newDate.setSeconds(0);
newDate.setMilliseconds(0);
return newDate.getTime() >= currentDate.getTime();
}
To use, simply throw the selected date in the function. Should return true if the date is greater or equal to the date today.
isValidDate(selectedDateFromDatePicker);

How to show different time period on Sunday - Jquery datetimepicker

I would like to set a specific time period only on Sunday. So every other day the 'allowTimes' is from 18:00 to 22:30 but on sunday its 12:30 till 20:30. I am searching solution from last two days but haven't found it.
HTML
<div class="form-group">
<input type="text" id="date" name="txtDate" class="form-control" placeholder="Date">
</div>
<div class="form-group">
<input type="text" id="time" name="txtTime" class="form-control" placeholder="Time">
</div>
JQUERY
//Time Picker
$('#time').datetimepicker({
datepicker:false,
format:'H:i',
step:15,
allowTimes:['18:00','18:15','18:30','18:45','19:00','19:15','19:30','19:45','20:00','20:15','20:30','20:45','21:00','21:15', '21:30', '21:45', '22:00', '22:15','22:30']
});
// Date Picker
$('#date').datetimepicker({
timepicker:false,
format:'d/m/Y',
});
Your question is trickier than it seems because jQuery DateTimePicker in an instance and the fact that once initialized, you can't change the options.
But there always is a walk-around!
The trick here is to "destroy" the instance on the time input when the day number changes (0 for sunday to 6 for saturday) and reinitialise it with the right schedule. Now if the selected time does not exist in the new schedule, force the user to re-select the time.
Looks simple? See the code:
console.clear();
var schedule_week = ['18:00','18:15','18:30','18:45',
'19:00','19:15','19:30','19:45',
'20:00','20:15','20:30','20:45',
'21:00','21:15','21:30','21:45',
'22:00','22:15','22:30'];
var schedule_sunday = ['12:30','12:45',
'13:00','13:15','13:30','13:45',
'14:00','14:15','14:30','14:45',
'15:00','15:15','15:30','15:45',
'16:00','16:15','16:30','16:45',
'17:00','17:15','17:30','17:45',
'18:00','18:15','18:30','18:45',
'19:00','19:15','19:30','19:45',
'20:00','20:15','20:30'
];
var prev_dayNum;
var schedule_used = schedule_week; // Use the week schedule by default.
// Function to initialise the time picker input.
function initTime(){
$('#time').datetimepicker({
datepicker:false,
format:'H:i',
step:15,
allowTimes: schedule_used
});
}
// On load time initialisation.
initTime();
// Initialise the date input.
$('#date').datetimepicker({
timepicker:false,
format:'d/m/Y',
// On change callback
onChangeDateTime:function(dp,$input){
var dateVal = $input.val();
var timeVal = $('#time').val();
//console.log(dateVal +" - "+ (timeVal||"No Time"));
// Because of the d/m/Y format, have to process the date a bit to get the day number.
val = dateVal.split("/");
var dayNum = new Date(val[2]+"/"+val[1]+"/"+val[0]).getDay();
//console.log("dayNum: "+dayNum);
// if dayNum is zero (sunday), use sunday schedule... Else use the week schedule.
schedule_used = (dayNum == 0) ? schedule_sunday : schedule_week;
// If the dayNum changed.
if( prev_dayNum != dayNum ){
console.log("Changed day!");
// Re-initialise datetimepicker
$('#time').datetimepicker("destroy");
initTime();
// If the actual time value is not in schedule.
if($.inArray(timeVal,schedule_used) == -1){
console.log("Wrong time!");
// Clear the time value.
$('#time').val("");
// Focus the time input so it's obvious the user has to re-select a time.
$('#time').focus();
}
}
// Keep this dayNum in memory for the next time.
prev_dayNum = dayNum;
}
});
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jquery-datetimepicker/2.5.20/jquery.datetimepicker.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-datetimepicker/2.5.20/jquery.datetimepicker.full.js"></script>
<div class="form-group">
<input type="text" id="date" name="txtDate" class="form-control" placeholder="Date">
</div>
<div class="form-group">
<input type="text" id="time" name="txtTime" class="form-control" placeholder="Time">
</div>
Now as you can see, the time schedule is different for sundays than the other days. And it "forces" the user to enter/re-enter a time only when what's entered does not fit the schedule.
I left the console logs uncommented in CodePen.

Firefox date format

I have created a webpage which calculates the weeks and days between two dates.
In chrome this page works and gives me the output of 4 weeks and two days for the dates 01/01/2016 and 01/31/2016 but firefox gives me the output of 130 weeks and two days.
How would I got about changing this to get the output of chrome.
Many thanks
<html>
<head>
<title>Time Between Dates Calculator</title>
<script src="dateCalc.js"></script>
</head>
<body>
<h1>Calculate the Amount of Time Between Dates:</h1>
<form>
Enter Date 1 (mm/dd/yyyy): <input type="date" id="date1" name="date1" required> <br />
Enter Date 2 (mm/dd/yyyy): <input type="date" id="date2" name="date2" required> <br />
<input type="submit" onclick="datecalc()" Value="Get Weeks and days">
</form>
</body>
</html>
***********************************************************************
function datecalc()
{
firstDate = document.getElementById("date1").value;
secondDate = document.getElementById("date2").value;
/*window.alert(firstDate);
window.alert(secondDate);*/
firstDateMs = new Date(firstDate).getTime();
secondDateMs = new Date(secondDate).getTime();
msPerDay = 24 * 60 * 60 * 1000;
msLeft = (secondDateMs - firstDateMs);
daysLeft = Math.round(msLeft/msPerDay);
weeksLeft = Math.round(daysLeft/7);
total = (daysLeft-(weeksLeft*7))
window.alert("The difference between these days is: " + weeksLeft + " weeks and " + total + " days.");
}
one solution is to use .split("/") on your input strings, then use the
new Date(year, month, day); constructor.
Also January is 0 and December is 11 in Javascript date
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Date
this will remove any ambiguity from possible string interpretation of the date.
firstDate = document.getElementById("date1").value;
secondDate = document.getElementById("date2").value;
/*window.alert(firstDate);
window.alert(secondDate);*/
firstDate.split("/");
secondDate.split("/");
firstDateMs = new Date(parseInt(firstDate[2]), parseInt(firstDate[0]) - 1, parseInt(firstDate[1])).getTime();
secondDateMs = new Date(parseInt(secondDate[2]), parseInt(secondDate[0]) - 1, parseInt(secondDate[1])).getTime();
The submit listener should be on the form, not the submit button, since the form can be submitted without clicking the button. Also, the date strings should be manually parsed to dates and since they depend on user input, the values validated. It can also make life easier if a reference to the form is passed by the handler so controls are accessed by name rather than getElementById.
Input type date is not well supported and creates more issues than it solves for now, so better to use type text (or use your own date picker). The following uses input type text and manually parses and validates the string in m/d/y format.
For a real form, it would be better to validate each date separately and put an error message for the one(s) that are invalid, also to echo the parsed date to the screen so the user can see that the code is using the date as they expect (e.g. 1/2/2016 comes out as 2 January not 1 February).
Some code…
function datecalc(form) {
var d1 = parseMDY(form.date1.value);
var d2 = parseMDY(form.date2.value);
var msDay = 8.64e7;
var msWeek = msDay * 7;
var result;
// Deal with in valid input
if (isNaN(+d1) || isNaN(+d2)) {
result = 'Invalid date';
} else {
// Get weeks and days
var diff = d2 - d1;
result = (diff/msWeek | 0) + ' weeks ' +
Math.round((diff % msWeek)/msDay | 0) + ' days';
}
// Should return an array of say [weeks, days] and leave formatting
// to some other function.
form.result.value = result;
}
function parseMDY(s) {
var b = s.split(/\D/);
var d = new Date(b[2], --b[0], b[1]);
return d && d.getMonth() == b[0]? d : new Date(NaN);
}
<form onsubmit="datecalc(this); return false;">
Enter Date 1 (mm/dd/yyyy): <input type="text" name="date1" value="3/1/2016"><br>
Enter Date 2 (mm/dd/yyyy): <input type="text" name="date2" value="3/23/2016"><br>
<input type="reset"> <input type="submit" Value="Get Weeks and days"><br>
<input type="text" name="result" readonly>
</form>
I guess you're rounding the days to remove daylight saving errors, be careful with that. An alternative is to get the difference in days from the date values and not create date objects at all. That removes any issues with DST (but validating the dates takes about 3 lines more code).

PHP: Date range selection automatically

I have 3 input fields all together.
Contract period: 1 years(for example)
start date : 30 - 1- 2012 (for example)
end date : ????
(Can we get the end date automatically according to the contract period mentioned, which mean if the date after 1 year is 30-1-2013 can we get it automatically in the third field after mentioning the first and second field).
Possible, using onSelect option of jQuery datepicker.
1) get the value of contract year and parse it as integer.
var addYears = parseInt($('#contract').val(), 10);
2) Split the selected date in startDate, as below
var t = date.split('/');
3) Now add the years and parse it as Date object.
var fin = new Date(parseInt(t[2], 10) + addYears, --t[0], t[1]);
Finally,
HTML:
In years only:
<input id="contract" type="text" />
<input id="start" type="text" />
<input id="end" type="text" />
JS:
$('#end').datepicker();
$('#start').datepicker({
onSelect: function (date, args) {
var addYears = parseInt($('#contract').val());
var t = date.split('/');
var fin = new Date(parseInt(t[2], 10) + addYears, --t[0], t[1]);
$('#end').datepicker("setDate", fin);
}
});
JSFiddle

Categories

Resources