Ability to select time after midnight - javascript

I've opening and closing hours select drop-down. This is basically to select opening and closing hours of a shop. I've created the list of hours with 15 min interval from 12:00 Morning to 12:00 Midnight.
$scope.availableTimes = [];
$scope.availableTimes.push({
'msValue': 0,
'display': '12:00 Morning'
});
for (var msValue = 900000; msValue <= 85500000; msValue += 900000) { // 90.000ms = 15 min, 85.500.000ms = 11:45PM
$scope.availableTimes.push({
'msValue': msValue,
'display': moment(msValue).utc().format("h:mm A")
})
}
var dayMS = 86400000 - 1;
$scope.availableTimes.push({
'msValue': dayMS,
'display': '12:00 Midnight'
});
But there might be some case they want to select the
Opening hour : 11:00am & Closing hour: 2:00am (after midnight) total 15 hours.
To handle this situation visually I made a workaround. I rearrange the closing hours based on the opening hour selection.
Example:
If opening hour selected as 11:00 am, available closing hours will start from 11:15 am upto 10:45 am.
Here the directive to make closing hours list:
app.directive('closingTimeSync',function(){
return {
template: `<div class="col-xs-6">
<div class="form-group">
<label for="exampleFormControlSelect1">Closing Hours</label>
<select class="form-control" data-ng-options="time.display for time in closingTimes" data-ng-model="selectedToTime">
</select>
</div>
</div>`,
replace: true,
transclude: true,
link: function(scope) {
scope.automaticallySelectClosingTime = function(msValue) {
scope.closingTimes = scope.availableTimes;
var dayMS = 86400000 - 1;
var remainingTimings = [];
var index = scope.closingTimes.map(function(obj){return obj.msValue;}).indexOf(msValue);
index = (index === scope.availableTimes.length-1) ? 1 : index+1;
scope.closingTimes = scope.closingTimes.slice(index,scope.availableTimes.length);
if(msValue !== dayMS) {
remainingTimings = scope.availableTimes.slice(1,index -1);
}
scope.closingTimes = scope.closingTimes.concat(remainingTimings);
scope.selectedToTime = scope.closingTimes[0];
};
}
};
});
Plunker
Problem:
You can see I'm just adding remainingTimings = scope.availableTimes.slice(1,index -1);. It gives the ability to select a time after midnight but technically in the millisecond level 2:00 am is less than 11:00 am.
How can I add one extra day in milliseconds if someone selects anything after 12:00 midnight?
Hope I was able to explain clearly.

Simply add 24 Hours if the closing time is lower than your opening time

I would not create lists.
The first list can just be written into the HTML directly, since it will never change.
Or you could create it with a simple angular loop instead of a scope lookup.
Every day starts at 00:00 and ends at 23:59
The second list is just the first list + the amount of time the store is open. And you know that in advance. ( 15 hours )
So I would go for something like this:
<select>
<option value="00:00">00:00</option>
<option value="00:15">00:15</option>
<!-- add more options -->
<option value="23:45">23:45</option>
</select>
And for the event handler:
function( event ) {
// Get the selected value in the dropdown.
const time_chunks = event.target.value.split( ':' );
// Get the current datetime.
const opening = new Date();
// Set the current datetimes hours and minutes to the selected value so opening equals todays opening time.
opening.setHours( time_chunks[ 0 ] );
opening.setMinutes( time_chunks[ 1 ] );
// 3600000 miliseconds = 1 hour
const hours_open = 15;
const ms_open = hours_open * 3600000;
const closing = new Date( opening.getTime() + ms_open );
// Add code to transform the datetime into the label you need.
// Add code to save the current state in $scope if needed.
// Add code to select the correct option in the second dropdown.
}
You can probably rewrite the same logic with actual angular and moment methods.
By using actual dates instead of trying to recreate timestamps in a list, you avoid all kinds of timestamp issues like daylight savings time, month barriers on the last day of a month, year barriers on 31 december, etc.
You can use the same principle to generate the lists, if for example, the closing hours don't always have to be 15 hours, the point is, do all calculations with full datetimes instead of only the times part so the date will actually change to the next day if the closing time is next day

Related

Momentjs / Angularjs - Checking if 2 dates are in the same period - TimeSheet project

I am working on a simple Timesheet app, I am trying to implement an auto calculator that will sum up your hours for each day (Sunday, Monday, Tuesday, etc ...). A problem I noticed is that in some cases, users will enter activities that will be within the same date time periods.
For example:
$scope.Example = [
{Description:"Example activity",Start:"2018-06-24 8:00",End:"2018-06-24 10:00",Total:2},
{Description:"Example activity2",Start:"2018-06-24 9:00",End:"2018-06-24 10:00",Total:1},
{Description:"Example activity3",Start:"2018-06-24 10:00",End:"2018-06-24 11:00",Total:1}];
$scope.Calculate_all_entries = function(){
$scope.Total.Sunday = 0;
if($scope.Example){
angular.forEach($scope.Example, function(element){
if(moment(element.Start).format("dddd") === "Sunday"){
$scope.Total.Sunday = $scope.Total.Sunday + element.Total;
}
})
}
}
In this case the total should be 3 hours and not 4 hours as we dont charge for work within the same hours. I'm need to implement a system that would check if the dates are within the same period and provide the appropriate total.
I found this in the documentation on momentjs that seemed to be close to what i need but only takes one value:
moment('2010-10-19 11:00').isBetween('2010-10-19 10:00', '2010-10-25 00:00'); // true
Would anyone know of any other methods to check wether or not the start and end time are in the same period as other entries in the same day?
Sure, you can use momentjs's unix() function to convert those date times to an integer which then can easily be used to check whether the timestamp is in between two other timestamps.
Here is an example:
var timeToCheck = moment('2010-10-19 11:00').unix();
var startTime = moment('2010-10-19 10:00').unix();
var endTime = moment('2010-10-25 00:00').unix();
console.log(timeToCheck >= startTime && timeToCheck <= endTime); // true

How to make two timepickers behave like google calendar?

I try to make my timepickers behave like the ones in google calendar. What I try to achieve is that if I set the start time from 10:00 to 11:00, the 2nd should follow from 11:00 to 12:00. If I set the 2nd picker from 11 to 13, the difference is now 2 hours and if I adjust the first one, the 2nd should move +2 or -2 hours depending if its earlier or later on the day.
My current jquery code is now
var d = new Date();
var start_time = $('#calendarentryform-start_time').val();
var end_time = $('#calendarentryform-end_time').val();
var diff = ( new Date('1970-01-01 ' + end_time) - new Date('1970-01-
01 ' + start_time) ) / 1000 / 60 / 60;
var new_end_time = start_time + diff;
$('#calendarentryform-start_time').on('change',function() {
$('#calendarentryform-end_time').val(new_end_time);
}
);
It manage to find for example the hour difference on 1 hour, like the calculation is correct. But when I try to add that hour for new_end_time it just post 12:001 instead of 13:00 or whatever the time is supposed to be set to. I also want it to be able to find 1,5 hours, 2,5 hours etc.
I just dont seem to get it right.

How can I run my node js script automatically using scheduler

I have created a nodejs file.
Currently i need to schedule the task to run that file automatically at multiple occasion in a single day.
var schedule = require('node-schedule');
var rule = new schedule.RecurrenceRule();
rule.hour = 12;
var j = schedule.scheduleJob(rule, function(){
console.log('Hello world!');
});
The documentation say date and not day
RecurrenceRule properties:
second
minute
hour
date
month
year
dayOfWeek
https://github.com/node-schedule/node-schedule
For starters, you need to set the date, not the day, but either way, setting the date = 1 doesn't make the time interval equal 1 day, it makes the date that this rule occurs on equal to 1. In this case, because the week starts on sunday and it begins at 0, you set the rule to occur every Monday at midnight.
For the scheduler, everything defaults to 0 unless you set it. Because you set the rule.date = 1, everything else, the minute, hour, etc all =0.
If you want it to occur every day, you would need to set a range of days:
rule.dayOfWeek = [new schedule.Range(0, 6)];
Then you would need to set the time that this occurs at. For example, if you wanted it to occur at 10:30 am, you would set:
rule.minute = 30
rule.hour = 10
You should use this
var j = schedule.scheduleJob('0 0 0 * * *', function(){
console.log('for 12:00 am daily' );
});
and for particular time use this
0 30 8 * * *
8:30 am

JavaScript to check selected date is today's date and time is 2pm using Moment.js

How do I compare today's time and date with user selected date. If user selects today's date or tomorrow's date and time is 2pm or more than 2pm then I should show alert saying delivery time over.
I have tried something like this
$scope.checkDateTime=function(){
angular.forEach($scope.orders.start_date,function(s){
console.log(s);
var curTime = moment().format('YYYY-MM-DD HH:mm:ss');
var orderTime = s+' 14:00:00';
console.log(moment(orderTime).diff(curTime,'seconds'));
if(moment(orderTime).diff(curTime,'seconds')>86400) {
console.log('hooray!')
}
})
}
I have orders.start_date is a input field inside ng-repeat so I am using forEach loop. I just want to check if selected date is today's or tomorrow's date. Then I have to check time, and if it's greater than 2pm then I should not allow. Otherwise I can allow.
I am not sure when the acceptable order period starts (since checking if the day is today or tomorrow means that everything from 00:00 to 14:00 is a fair game) , but here is the is one way to do it based on your code:
$scope.checkDateTime = function(){
angular.forEach($scope.orders.start_date, function(s){
console.log(s);
var selectedTime = moment(s);
// create boundaries for time ranges
var today_end = moment("14:00","HH:mm"); // today 14:00
var today_start = moment().subtract(1,'day').endOf('day'); // end of yesterday (since we need to include 00:00 of today)
var tomorrow_end = moment("14:00","HH:mm").add(1,'day'); // tomorrow 14:00
var tomorrow_start = moment().endOf('day'); // end of today (since we need to include 00:00 of tomorrow)
// check if time in questions fits any of the ranges
if( ( selectedTime.isBetween(today_start, today_end) ||
( selectedTime.isBetween(tomorrow_start, tomorrow_end) )
console.log('hooray!')
}
})
}
Note, that isBetween(t1, t2) does not include t1 and t2 into the accepted range.

JavaScript - Moment.js - isBetween() method check if time falls in a range

I am trying to see if timeNow falls between a time range opening and closing :
var timeFormat2 = "HH:mm:ss";
var timeNow = "23:12:00"; //(11:12:00 pm)
var opening = "08:00:00"; //(08:00:00 am) morning time
var closing = "00:12:00"; //midnight time (i.e 12:12:00 am)
var isAvailable = moment(timeNow, timeFormat2).isBetween(moment(opening, timeFormat2), moment(closing, timeFormat2));
console.log("will show false >>>> ", isAvailable); //it shows 'false'
var closing1 = "23:45:00";
var isAvailable1 = moment("23:12:00", timeFormat2).isBetween(moment(opening, timeFormat2), moment(closing1, timeFormat2));
console.log("Should show true >>>> ", isAvailable1);
Here is a JSfiddle to check it out:
https://jsfiddle.net/1wuf0rzg/8/
You need to introduce the concept of "next day". Here I have set the date to be the first day of the month. If the closing time is before the opening time, then I move the closing time to the 2nd day of the month.
function isAvailable(opening, closing, now){
var openingTime = moment(opening, timeFormat2).date(1);
var closingTime = moment(closing, timeFormat2).date(1);
var nowTime = moment(now, timeFormat2).date(1);
if(closingTime.isBefore(openingTime)){
closingTime.date(2);
}
return nowTime.isBetween(openingTime, closingTime);
}
https://jsfiddle.net/1wuf0rzg/14/
There's not enough data to compute.
00:12:00 means 12 minutes less than 8 hours before the opening time of the current Date.
Because of that, 23:12:00will fall out of range.
It would help using different kind of data:
opening time.
working hours (amount).
time now,
in order to be able to determine - if the 'time now' falls inside the time interval with ease.

Categories

Resources