Split a time range into pieces by other time ranges
As you specifically asked for "some insight" rather than a full working answer, I'd personally go with arrays populated with "minutes".
$shift = array(
'start' => '15:30:00',
'end' => '18:30:00',
'original' => array(),
'unavailable' => array(),
'modified' => array()
);
You'd then do some jiggery pokery to convert 15:30:00
into 930 and 18:30:00
into 1110 (number of minutes) which will give you the difference between start and end times.
Use range()
to quickly fill up the original
array, load in your unavailable
in a similar format and then use things like array_intersect()
and array_diff()
to work out which minutes from the original shift are unavailable.
From that, build up the modified
array, and read directly from there to your output.
Split a time range into pieces by other time ranges in javascript
I has created an example as you want. I think code is something tough and long so if it helpful for you then use otherwise ignore it.
var obj = { s: '14:30', e: '18:30' } var deviation = [{ s: '15:30', e: '16:30' }, { s: '17:30', e: '18:30' }]
$(document).ready(function () { deviation.push(obj); var newArr = []; $(deviation).each(function (index, value) { newArr.push(value.e); newArr.push(value.s); }); var newArr = newArr.sort(); var $timeArr = []; lastVal = ''; $(newArr).each(function (index, value) {
if (index == 0) { lastVal = value; } else { var stTime = lastVal; var endTime = value;
lastVal = endTime; var pushObj = { s: stTime, e: endTime } var lsstKey = newArr.length - 1; if (index != lsstKey) { $timeArr.push(pushObj); } } }); document.getElementById("myarray").innerHTML = JSON.stringify($timeArr); });
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script><p id="myarray"></p>
Split Time range into multiple time periods based on interval in Python
You can do arithmetic on datetime
objects by adding timedelta
objects.
You probably need to decide exactly what behaviour is required if the interval per period is not an exact divisor of the total, but this example would give a final short period in that case.
import datetime
tstart = datetime.datetime(2020,8,24,9,30)
tend = datetime.datetime(2020,8,24,11,30)
interval = datetime.timedelta(minutes=30)
periods = []
period_start = tstart
while period_start < tend:
period_end = min(period_start + interval, tend)
periods.append((period_start, period_end))
period_start = period_end
print(periods)
This gives (with newlines inserted for readability):
[(datetime.datetime(2020, 8, 24, 9, 30), datetime.datetime(2020, 8, 24, 10, 0)),
(datetime.datetime(2020, 8, 24, 10, 0), datetime.datetime(2020, 8, 24, 10, 30)),
(datetime.datetime(2020, 8, 24, 10, 30), datetime.datetime(2020, 8, 24, 11, 0)),
(datetime.datetime(2020, 8, 24, 11, 0), datetime.datetime(2020, 8, 24, 11, 30))]
For the string output format that you want, you could do something like this:
def format_time(dt):
return dt.strftime("%Y-%m-%d %H:%M")
print(['{} - {}'.format(format_time(start), format_time(end))
for start, end in periods])
to give:
['2020-08-24 09:30 - 2020-08-24 10:00',
'2020-08-24 10:00 - 2020-08-24 10:30',
'2020-08-24 10:30 - 2020-08-24 11:00',
'2020-08-24 11:00 - 2020-08-24 11:30']
Split up date range into chunks to join back into one table KDB+/Q
Something like this should chunk it for you:
raze{select from t where date within x}each(first;last)@\:/:d group"m"$d:sd+til 1+ed-sd
Do not use where date.month=x
as you had suggested - at least not for historical queries
How to split the time range into multiple rows
Here is a recursive CTE solution:
with cte as (
select
employeecode,
startdatetime,
dateadd(hour, 1, datetimefromparts(year(startdatetime), month(startdatetime), day(startdatetime), datepart(hour, startdatetime), 0, 0, 0)) enddatetime
enddatetime maxdatetime
from mytable
union all
select employeecode, enddatetime, dateadd(hour, 1, enddatetime), maxdatetime
from cte
where enddatetime < maxdatetime
)
select employeecode, startdatetime,
case when enddatetime < maxdatetime then enddatetime else maxdatetime end as enddatetime
from cte
Basically, the anchor of the CTE performs computes the end of the first range, using datetimefrompart()
. Then we iteratively generate the following ranges, until the maximum date time is reached. We can then display the results with the outer query, while adjusting the end date of the last range.
Dividing a date range into equal chunks containing a set number of day chunks in JavaScript?
Start with the start date and add maxDays to get the end of the block. If the block date is greater than the end date, use the end date instead. Then add maxDays to the start and go again until the start is >=
than the end.
Copy dates before pushing into the array so don't affect original or ongoing processing.
function getDateBlocks(start, end, maxDays) {
let result = [];
// Copy start so don't affect original
let s = new Date(start);
while (s < end) {
// Create a new date for the block end that is s + maxDays
let e = new Date(s.getFullYear(), s.getMonth(), s.getDate() + maxDays);
// Push into an array. If block end is beyond end date, use a copy of end date
result.push({start:new Date(s), end: e <= end? e : new Date(end)});
// Increment s to the start of the next block which is one day after
// the current block end
s.setDate(s.getDate() + maxDays + 1);
}
return result;
}
console.log(getDateBlocks(new Date(2021,0,1), new Date(2021,0,20), 6));
Split an array of date range items each with a start and an end timestamp which can overlap each other into separate arrays of non overlapping ranges?
A generic approach has to work itself recursively through any given original timetable
(source array) in order to detect/generate as much time tables which each feature just non-overlapping time range items.
A recursive implementation would call itself repeatedly as long as there are, within a processed array, still overlapping time range items found.
Part of the approach is, that such a self recursive function does create a shallow copy of the passed time table and also does sort it exactly once, at the time of being called initially.
function parseTime(value) {
return new Date(value).getTime();
}
function getParsedTimeRangeFromItem({ start, end }) {
return {
start: parseTime(start),
end: parseTime(end),
}
}
function orderByTimeRangeAscending(a, b) {
const { start: aStart, end: aEnd } = getParsedTimeRangeFromItem(a);
const { start: bStart, end: bEnd } = getParsedTimeRangeFromItem(b);
return (aStart - bStart) || (aEnd - bEnd);
}
function createTimetablesOfNonOverlappingTimeRanges(timetable, result) {
// at initial call time only ...
if (!Array.isArray(result)) {
// ... create the result array ...
result = [];
// ... and also a shallow and sorted copy
// of the initially passed `timetable`.
timetable = [...timetable].sort(orderByTimeRangeAscending);
}
const rejected = [];
let idx = -1;
let item, nextItem;
while (
(item = timetable[++idx]) &&
(nextItem = timetable[idx + 1])
) {
// detect `nextItem` as overlapping time range item ...
if (parseTime(item.end) > parseTime(nextItem.start)) {
// ... and reject it from the `timetable` reference.
rejected.push(timetable.splice((idx + 1), 1)[0])
--idx;
}
}
// add the sanitized but mutated `timetable` to `result`.
result.push(timetable);
// in case of any rejected time range item trigger self recursion.
if (rejected.length >= 1) {
result =
createTimetablesOfNonOverlappingTimeRanges(rejected, result);
}
return result;
}
const timetable = [
{ class: 'one', start: '2021-11-16T09:00:00', end: '2021-11-16T10:00:00' },
{ class: 'two', start: '2021-11-16T10:00:00', end: '2021-11-16T11:00:00' },
{ class: 'three', start: '2021-11-16T09:00:00', end: '2021-11-16T10:00:00' },
{ class: 'four', start: '2021-11-16T09:00:00', end: '2021-11-16T10:00:00' },
{ class: 'five', start: '2021-11-16T10:00:00', end: '2021-11-16T11:00:00' },
{ class: 'six', start: '2021-11-16T09:00:00', end: '2021-11-16T10:00:00' },
];
console.log(
'[...timetable].sort(orderByTimeRangeAscending) ...',
[...timetable]
.sort(orderByTimeRangeAscending)
);
console.log(
'createTimetablesOfNonOverlappingTimeRanges(timetable) ...',
createTimetablesOfNonOverlappingTimeRanges(timetable)
);
console.log('un-mutated original source array ...', { timetable });
.as-console-wrapper { min-height: 100%!important; top: 0; }
Related Topics
PHP Script to Execute at Certain Times
Opposite of Nl2Br? Is It Str_Replace
How to Remove <Br /> Tags and More from a String
Calling Perl Script from PHP and Passing in Variables, While Also Using Variablized Perl Script Name
Regex Matching Table Rows in HTML
Static Class Initializer in PHP
How to Display the Users Profile Pic Using the Facebook Graph API
How to Generate a Custom Menu/Sub-Menu System Using Wp_Get_Nav_Menu_Items in Wordpress
Get the Index of a Certain Value in an Array in PHP
Php, Merging Arrays with Common Keys
Override External Product Url to "Add to Cart" Product Button
How to Convert Excel File into MySQL Database
Convert All Node's Attributes into Child Nodes
Laravel Password Validation Rule
Magento - Passing Data Between a Controller and a Block
Inspect Xml Created by PHP Soapclient Call Before/Without Sending the Request