473,386 Members | 2,042 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

Determining if a time falls within a given set of time intervals.

Hi (using javascript) -

I have a schedule divided into periods
Period 1: 8:00 am - 9:10
Period 2: 9:15 am - 10:00 am
Period 3: 10:15 am - 11:05 am
...
...
...
Remember your days in school?..:)

I have a login time and a logout time (login at 8:10 am and logout at 9:45 am)

I need to know
1.) what period they logged in,
2.) what period they logged out and
3.) if they missed more than 25 minutes of any period

I am assuming I would build an array of start and end times for the periods, but after that I dont even know where to start. Any advice or ides would be greatly appreciated!

Dan B
Sep 23 '07 #1
4 1527
pbmods
5,821 Expert 4TB
Changed thread title to better describe the problem (did you know that threads whose titles do not follow the Posting Guidelines actually get FEWER responses?).
Sep 24 '07 #2
pbmods
5,821 Expert 4TB
Heya, Dan.

Convert each of your time strings into a Date object:
Expand|Select|Wrap|Line Numbers
  1. var periods =
  2. [
  3.     { 'time': new Date('2007-01-01 08:00:00').getTime(), 'period': 1, 'start': true },
  4.     { 'time': new Date('2007-01-01 09:10:00').getTime(), 'period': 1, 'start': false },
  5.     .
  6.     .
  7.     .
  8. ];
  9.  
And so on. The date that you use ('2007-01-01') is not important, as long as you use the same one for each period.

Then convert your login/logout times to Dates similarly.

Date::getTime() returns a Unix timestamp, which is just an integer, which makes it easy to use standard comparison operators (>, <, etc.).

All you have to do then is run a couple of binary searches through periods until you find the first element in periods where periods[i].time <= login and the first element in periods where periods[i].time >= logout.

Using the results of the search, you now know during which period the User logged in and during which period the User logged out. You also know the start and end times of the periods closest to the User's login/logout times so that you can tell if the User logged in late.

Note that you also know if the User logged in and/or out *during* a period, or if he did it during a break.
Sep 24 '07 #3
"All you have to do then is run a couple of binary searches through periods until you find the first element in periods where periods[i].time <= login and the first element in periods where periods[i].time >= logout."

Can you give an example?

Thanks,

Dan B
Sep 24 '07 #4
pbmods
5,821 Expert 4TB
Heya, Dan.

Suppose you had a sorted Array (it has to be sorted; this is key):
Expand|Select|Wrap|Line Numbers
  1. var theArray = new Array(1, 4, 9, 16, 25, 36);
  2.  
Also suppose you had a value, and you wanted to determine which number was the first one that came before your value:
Expand|Select|Wrap|Line Numbers
  1. var testStart = 8;
  2. var testEnd = 18;
  3.  
Now looking at the array, 4 is the number just before testStart, and 25 is the number just after testEnd. It's easy enough for us humans to figure that part out. Now how to go about making the computer see it.

The idea behind a binary search is 'divide and conquer'. By dividing a *sorted* array in half each time, we can readily eliminate 1/2 of the remaining array each time. The end result is that we know exactly where the item 'fits' very quickly.

There's a bit of a trick because for one number (in this case, testStart), we need to know which number is smaller than our test value, but we need to know which number is larger than our test value.

Ok. Let's get started.

In order to 'divide' the Array, we need to define our boundaries:
Expand|Select|Wrap|Line Numbers
  1. var min = 0;
  2. var max = theArray.length - 1;
  3.  
  4. var foundStart = false;
  5.  
  6. /***************
  7. *
  8. *    Quick checks:
  9. */
  10. if( testStart < theArray[min] )
  11. {
  12.     /***************
  13.     *
  14.     *    Start occurs before the array starts, which means that there is no value in theArray that is < foundStart.
  15.     */
  16.     foundStart = null;
  17. }
  18. else if( testStart > theArray[max] )
  19. {
  20.     /***************
  21.     *
  22.     *    Start occurs after the array ends, which means that the last value in theArray is the largest value that is < foundStart.
  23.     */
  24.     foundStart = theArray[max];
  25. }
  26. else
  27. {
  28.     /***************
  29.     *
  30.     *    Begin divide and conquer.
  31.     */
  32.     do
  33.     {
  34.         var target = Math.floor((min + max) / 2);
  35.  
  36.         if( testStart == theArray[target] )
  37.         {
  38.             /***************
  39.             *
  40.             *    This one's easy.
  41.             */
  42.             foundStart = theArray[target];
  43.             break;
  44.         }
  45.         else if( testStart > theArray[target] )
  46.         {
  47.             /***************
  48.             *
  49.             *    testStart occurs after theArray[target].  Divide theArray to eliminate all values before target.
  50.             */
  51.             min = target;
  52.         }
  53.         else
  54.         {
  55.             /***************
  56.             *
  57.             *    testStart occurs before theArray[target].  Divide theArray to eliminate all values after target.
  58.             */
  59.             max = target;
  60.         }
  61.  
  62.         /***************
  63.         *
  64.         *    Continue dividing the array until it is indivisible.
  65.         */
  66.     }
  67.     while( (max - min) > 1 );
  68.  
  69.     /***************
  70.     *
  71.     *    At this point, either foundStart has been set (teststart == theArray[target]), or we have divided theArray to the point where we know which elements testStart fits in between.
  72.     */
  73.     if( foundStart === false )
  74.     {
  75.         /***************
  76.         *
  77.         *    Since we are looking for the first value that is < testStart, we use the min boundary.
  78.         */
  79.         foundStart = theArray[min];
  80.     }
  81. }
  82.  
Let's work through this:
  • testStart = 8, min = 0, max = 5 (6 - 1)
  • Since 8 !< 1 (testStart !< theArray[min]), we know that foundStart cannot be null.
  • Since 8 !> 36 (testStart !> theArray[max]), we know that foundStart cannot be 36.
  • Begin divide and conquer:
    • target = Math.floor((0 + 5) / 2) => 2; theArray[2] = 9
    • 8 != 9 (testStart != theArray[2]), so continue.
    • 8 !> 9 (testStart !> theArray[2]), so continue.
    • max = 2 (max = target) because we know that 8 has to be < 9 since it's != and !>.
  • Since 2 - 0 > 1 (max - min > 1), re-iterate.
    • target = Math.floor((0 + 2) / 2) => 1; theArray[1] = 4
    • 8 != 9, so continue.
    • 8 is > 9, so min = 1
    • 2 - 1 !> 1, so break the loop.
  • foundStart is false (because testStart never == theArray[target]), so use theArray[min].
  • foundStart = 4

Let's try it on the other end of the array. Suppose testStart = 25.
  • min = 0, max = 5, foundStart = false
  • 25 !< 1 (testStart !< theArray[min])
  • 25 !> 36 (testStart !> theArray[max])
  • loop:
    • target = Math.floor((0 + 5) / 2) => 2, theArray[target] = 9
    • 25 != 9 (testStart != theArray[target])
    • 25 is > 9, so min = 2 (testStart is > theArray[target], so min = target)
  • 5 - 2 is > 1 (max - min is > 1), so re-iterate.
    • target = Math.floor((2 + 5) / 2) => 3, theArray[target] = 16
    • 25 != 16
    • 25 is > 16, so min = 3
  • 5 - 3 is > 1, so re-iterate.
    • target = Math.floor((3 + 5) / 2) => 4, theArray[target] = 25
    • 25 == 25, so foundStart = 25. Break out of the loop.
  • foundStart is not false, so we're done.
  • foundStart = 25

To search for foundEnd, simply reverse the signs so that you set max when testEnd < theArray[target] and min when testEnd > theArray[target].
Sep 24 '07 #5

Sign in to post your reply or Sign up for a free account.

Similar topics

2
by: androtech | last post by:
Hello, I'm looking for a function that returns a date range for a specified week number of the year. I'm not able to find functions like this anywhere. Any pointers/help would be much...
2
by: Shaun | last post by:
Hi, I have a table called Bookings which has two important columns; Booking_Start_Time and Booking_End_Time. These columns are both of type DATETIME. Given any day how can I calculate how many...
3
by: Dave | last post by:
Hi I am hoping someone might be able to help me out with this. I am writing a helpdesk system which records agents logging in and out of the system. I need to write a stored procedure which...
7
by: Brett Edman | last post by:
I created a UTC clock using this: UTCTime = MyTime.ToUniversalTime() Now that we've turned the clocks ahead 1 hour for daylight savings time, the clock is reporting the wrong UTC time. It is...
6
by: leorulez | last post by:
I was wondering if there is any way in C to read the date and time (either system time or from the keyboard) and see if it falls between certain date and time? I am not sure how to compare the 2...
4
by: P.Jaimal | last post by:
Hello,I have a database that records leaves taken by employees.Every record has employee name,leavefrom(to record the starting date of leave) & leaveupto( for the leave end date).My requirement is...
2
by: Rombolt | last post by:
Hi I have a MSSQL table with many time intervals stored as datetime. Each time interval is also assigned a numeric type that specifies what type of job was done during the time interval. I need to...
2
by: bb02 | last post by:
I have a login audit table that has a LoginDateTime and a LogoutDateTime. I am wanting to count the number of users whose datetime range falls between 15 minute intervals each day. For example: ...
1
by: DeanMiller | last post by:
I was wondering if there is an easy way to check if a date falls in a given selection range. I have the selection range already made and I want to be able to take a given date and see if it falls...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.