I have row of data like this that represent a business opening hours
day / opentime / closetime / isOpen
0 09:00:00 17:00:00 true
1 09:00:00 17:00:00 true
2 08:00:00 17:00:00 true
3 09:00:00 17:00:00 true
4 09:00:00 17:00:00 true
5 false
6 09:00:00 17:00:00 true
with day being an Integer from 0-6 (mon to sunday) and iOpen
Before Re-inventing the wheel and start thinking on a new algorithm I would like to know if there already some algo that would do something similar to this:
MON - TUE 9am - 5pm
WED 8am - 5pm
THU - FRI 9am - 5pm
SUN 9am - 5pm
basically grouping the day that have the opening and closing time together ?
I'm not asking for a ready to go algorithm but more of an advice to where to look if there is already something similar that has been done.
ps: bonus question. Is the way I store the data efficient to achieve my goal ?
This is a fairly straightforward algorithm. Just write down in code what you would do as a human.
As a human, when I look at the data you give me, I start with Monday, and I write down the open/close times on a sheet of paper and write "Monday" next to them. Then I look at Tuesday. If Tuesday has the same open/close times as the previous day, then I simply go to where the time was already written on my paper and add "Tuesday" right next to Monday. I keep doing this until I find an open/close time that is not the same as the previous day's. In that case, I go to a new line on my paper and write down the new open/close times and continue on like this until the end.
If I were to program this in C, I would use an array of structs, where the struct merely had the open time, the close time, and an array of character arrays (ie, an array of strings) to store the dates associated with those hours. (Note: there could be more efficient ways of storing this, but this seems good enough for your purposes)
Related
I need to come up with an algorithm that can find free intervals on the timeline.
There is a time scale. From 00:00 to 24:00. Initially, when there are no vacancies, all the time is free, and the free interval is (0...1440) (in minutes).
For example, we add a vacancy, I mean that we set the working time for example from 08:00 to 21:00.
Now we will already have 2 free intervals. From 00:00 to 08:00. And from 21:00 to 24:00.
I'll attach pictures below to make it clear what I mean.
*Default variant
*Intervals of vacancies (working hours) may overlap
*Intervals of vacancies can be set without restrictions on the number, and intersect with anything, most importantly within 24 hours (1 day)
The result that I expect: Initially, we have an array with 1 free interval from 0 to 1440 (in minutes), we call the function and pass working time to it, and at the output we get an updated array of intervals, in which there are already 2 intervals. Then we can add 1 more working time, and the output function will always give us the actual array with the correct number of intervals and the free time of the intervals themselves
For writing code I use swift, but I will understand the solution in Python or similar
I really hope for your help! I hope at least that the community will help put me on the right path, at the moment, I can't figure out which way to go. :(
Turn intervals into pairs of start/end events, sort the events by time, then run through the list and keep a count of how many more start than end.
Any stretch of time where the two are equal becomes an interval in your answer.
Here is an explanatory example. Suppose we have the following intervals:
04:00 - 09:00
15:00 - 20:00
08:00 - 12:00
We get the following list of events from them.
04:00 start
09:00 end
15:00 start
20:00 end
08:00 start
12:00 end
Add 2 more to bookend the day
00:00 analysis_start
24:00 analysis_end
Which get sorted into:
00:00 analysis_start
04:00 start
08:00 start
09:00 end
12:00 end
15:00 start
20:00 end
24:00 analysis_end
And now we process them to come up with the following counts of open intervals:
00:00 - 04:00 0
04:00 - 08:00 1
08:00 - 09:00 2
09:00 - 12:00 1
12:00 - 15:00 0
15:00 - 20:00 1
20:00 - 24:00 0
And now the answer is where our tally was 0:
00:00 - 04:00
12:00 - 15:00
20:00 - 24:00
One possible way to do it could be to have an array of size 1440 (number of minutes). You can initialize all to 0 indicating all are free minutes.
For each vacancy interval you need to add, flip the values from 0 -> 1 in that interval, where 1 indicates working minute.
Whenever you need the array, you can iterate through the array and find "collections" of 0s and 1s for free-time and vacancies.
However, this is a very crude way of doing this and every query (update and select) takes linear time. You can do much better performancewise if you implement this whole thing as a segment tree (Read RMQ - range minimum query) where time complexity of your updates and selects will be logarithmic. Take this decision based on number of updates and selects and how you want your performance of code. eg. If total queries are ~10k, you need not go for segment tree. If they be ~10^5 or more, then you should.
I'm struggling with a formula where I have to calculate whether a person's absence time is hours or days. The normal formula works but when I change it to ARRAY it doesn't work anymore
data1
Data 2
note
01/01/2021 08:00:00
01/01/2021 09:10:00
only hour
04/01/2021 08:00:00
09/01/2021 08:00:00
days
normal formula:
=IF(IF(AND(DAY(D2)=DAY(E2);MONTH(D2)=MONTH(E2));1;0)=1;(HOUR(E2)-HOUR(D2))/10;DATEDIF(D2;E2;"d"))
array formula
=ArrayFormula(IF(IF(AND(DAY(D2:D)=DAY(E2:E);MONTH(D2:D)=MONTH(E2:E));1;0)=1;(HOUR(E2:E)-HOUR(D2:E))/10;DATEDIF(D2:D;E2:E;"D")))
example link
https://docs.google.com/spreadsheets/d/1EFxugOajxOAEDUgJQEalOXVpKrFwEm2YWSK_N2hq4gw/edit?usp=sharing
I have a database of time's that are not necessarily exact to the specified time. For example, if I want to pick 12:00 PM and my columns have times in column A:
[9:00 AM, 11:55 AM, 2:00 PM, 6:00 PM],
The closest before would be 11:55 AM, and closest after would be 2:00 PM. My attempt at the code:
=MAXIF(A:A, A:A, 12:00)
=MINIF(A:A, A:A, 12:00)
But to no avail, anythoughts?
You want the max where the time is less than or equal to the criteria and the Min for the time greater than or equal to the criteria:
=MAXIFS(A:A, A:A,"<=12:00")
=MINIFS(A:A, A:A,">=12:00")
I have time in UTC seconds format. Could any one assist on how to convert such numbers to GPS
time in normal timestamp (dd-mm-yyyy hh:mm:ss)? I need a C code or, perhaps, algorithm.
Update (June 2017): Currently 18 leap seconds.
GPS time is simply UTC time, but without leap seconds. As of this writing, there have been 15 leap seconds since the GPS epoch (January 6, 1980 # 00:00:00), so if it's 2012/02/13 # 12:00:00 (UTC), then it's 2012/02/13 # 12:00:15 in GPS time. If you want to do correct conversions for other times, you'll have to take into account when each leap second went into effect.
Here's how you can compute the current offset, from a couple different "authoritative" sources:
http://www.ietf.org/timezones/data/leap-seconds.list -- Count the number of lines starting from the 2571782400 20 # 1 Jul 1981 line. Or just subtract 19 from the last number in the list (e.g., 37-19 = 18) as of May 2017.
https://www.nist.gov/pml/time-and-frequency-division/atomic-standards/leap-second-and-ut1-utc-information -- Count the number of leap seconds inserted (from the Leap Seconds Inserted into the UTC Time Scale section), starting with (and including) the 1981-06-30 entry.
There is a Javascript library that can convert to and from unixtime. The library is available at
http://www.lsc-group.phys.uwm.edu/~kline/gpstime/
Whatever algorithm you use, you must update it when new leap seconds are announced.
for an algorithm check this site source code: UTC Converter
for built-in functions in c++ check here - especially ctime()
I have an idea for a story in which certain events happen repeatedly throughout the year of calendar dates that perfectly match each other for example 2011, 2005, 1994 one could replace these calendars with each other
I would like to be able to find calendar years past and future
If someone could help me please as I have no programming ability
Thanks in advance
Check Wikipedia.
You only need to compare the day of the week on which the first day of the year falls, and compare leap years and non-leap years separately (they will obviously differ). If the first day is the same and the days in the year are the same, so will the whole year be the same.
With this reduction, we need to first know what is a leap year. From wikipedia, the algorithm is
if year modulo 400 is 0
then is_leap_year
else if year modulo 100 is 0
then not_leap_year
else if year modulo 4 is 0
then is_leap_year
else
not_leap_year
Then we need to calculate the first day of the year. Before we start, we need a grounding. Let's take 2000, which starts on a Saturday. Every year we move forward, we move forward one day in the week except if the year follows a leap year in which case we move forward two days.
Let's walk through an example. 2000 starts on Saturday. 2001 starts on a Monday, 2 days later because 2000 is a leap year. 2002 starts on Tuesday. 2003 on a Wednesday. 2004 on a Thursday. 2005 on a Saturday, because 2004 is a leap year. From this we see that 2000 and 2005 start on the same day of the week, but the one is a leap year while the other is not. If we continue we'll find 2011 starts on a Saturday, and is therefore identical to 2005.
We can work backwards in similar fashion to find years in the past, or we can just choose an earlier starting year.
Dominical letter B: ... 1910 1921 1927 1938 1949 1955 1966 1977 1983 1994 2005 2011 2022 2033 2039 2050 2061 2067 2078 2089 2095 ...
Be careful about going back before 1752 and 1582, where 11 and 10 days were dropped from the calendar, respectively. see dataandtime.com. Otherwise there are exactly 14 possible calendars ... Half with a Feb 29th, half without. Each pair of calendars starts on a different day of the week. There should be an excel spreadsheet out there (its easy enough to generate one) that maps the years since 1752 into one of 14 columns.
2016 ends on the same days of the week as 1994, 2005 and 2011, but 2016 starts on Friday (leap year), while all the other years start on Saturday, therefore we need to wait until 2022 before the dates in 2011 match up again.