Googl Sheets - Time Range to Table - google-sheets

I want to take a time range and convert it to minutes within a table of 30 minute segments. For example, Bob works from 3:35 AM to 5:00 AM. So within the table from 3:30 AM - 4:00 AM should represent 25 minutes, because Bob was working a total of 25 minutes during that time slot. Then the time slots for 4:00 - 4:30 AM and 4:30 - 5:00 AM would both have 30 in their corresponding cells.
Apologies to leave this so broad but I honestly have no idea where to start and this forum has been immensely helpful.
https://docs.google.com/spreadsheets/d/1YpHU-UHlqXL6c8I27zSDZaRu72ViUw5W6RPru-HE3Iw/edit#gid=0
Any help is appreciated.

For each 30-minute interval, you have to check whether these two conditions are met:
The interval start time (3:30) falls between the employee start and end time (3:35 and 5:00).
The interval end time (4:00) falls between the employee start and end time.
If any of these conditions are met, the working time for that interval won't be 0. The working time will be the difference between the minimum of both end times (4:00 and 5:00) and the maximum of both start times (3:30 and 3:35).
Translated to sheets functions, you could do something like this:
=IF(MIN($D2,O$1)-MAX($C2,N$1)>0,TIMEVALUE(MIN($D2,O$1)-MAX($C2,N$1))*24*60,0)
Or, alternatively, this:
=IF(OR(AND($C2<N$1,N$1<$D2),AND($C2<O$1,O$1<$D2)),TIMEVALUE(MIN($D2,O$1)-MAX($C2,N$1))*24*60,0)

Related

Time function in sheets

I have the data of 4000 employees in google sheets along with their shift timings (9 hour long shift) spread across 24 hours. I wish to use a formula to understand the most common timing these employees are available in the office (09:00 to 18:00). My results would be 09:00 to 11:00, 11:00 to 13:00, 13:00 to 15:00, 15:00 to 18:00, 18:00 to 22:00, 22:00 to 09:00.
I could have used this formula to derive to the value:
=IF(AND(TIMEVALUE(A2)>=TIMEVALUE("09:00"), TIMEVALUE(A2)<=TIMEVALUE("11:00")), "09:00 to 11:00",
IF(AND(TIMEVALUE(A2)>=TIMEVALUE("11:00"), TIMEVALUE(A2)<=TIMEVALUE("13:00")), "11:00 to 13:00",
IF(AND(TIMEVALUE(A2)>=TIMEVALUE("13:00"), TIMEVALUE(A2)<=TIMEVALUE("15:00")), "13:00 to 15:00",
IF(AND(TIMEVALUE(A2)>=TIMEVALUE("15:00"), TIMEVALUE(A2)<=TIMEVALUE("18:00")), "15:00 to 18:00",
IF(AND(TIMEVALUE(A2)>=TIMEVALUE("18:00"), TIMEVALUE(A2)<=TIMEVALUE("22:00")), "18:00 to 22:00", "22:00 to 09:00")))))
but the problem is the timings are not in the time format but they are in text format
Here's my take:
Suppose Column A has clock ins, and Column B has clock outs. Let Column D have Times starting at 00:00 and going up to 33:00 (8am next day) in 5 minute (or 30, 60 etc) increments.
Let column E be the amount of clock in and outs that an employee was in the office at the time referred to in E.
We will define E to be =COUNTIFS($A$2:$A$9999,"<="&D2,$B$2:$B$9999,">="&D2).
Next, apply some conditional formatting to highlight the most busy times.
Note that you will need only the times of day, which it sounds like you have, but you will need to convert overnight shifts to not wrap around midnight.

count how many specific days are in a time period

I want to count say how many Mondays we have from 2022-02-01 - 2022-03-01. I found smth like this:
=SUMPRODUCT(WEEKDAY(B4:C4)=2) - B4 and C4 are the dates
But it returns 0. I assume it only checks if specific date is the specific day. Any ideas how I can do this but for a date range? So how count how many Mondays there are in February
I also found this
=NETWORKDAYS.INTL(B4;C4;"1000000")
but this returns 25
You can take advantage of the NETWORKDAYS.INTL function by using the string method to make all the days as weekend except for Monday.
The String method states:
weekends can be specified using seven 0’s and 1’s, where the first number in the set represents Monday and the last number is for Sunday. A zero means that the day is a work day, a 1 means that the day is a weekend. For example, “0000011” would mean Saturday and Sunday are weekends.
In this case since you only want to know the Mondays, the string would be "0111111" and the function would look like:
=NETWORKDAYS.INTL(StartDate,EndDate,"0111111")
I think this is right. It's counting inclusively so you would get five Mondays starting on Monday 7th Feb 2022 and ended on Monday 7th March 2022 for example.
=floor((B2-(A2+7-weekday(A2,12)))/7)+1
where A2 and B2 contain the start date end end date.
Obvs nul points for me again but for the record this could be generalised if you put the day number in C2 (e.g. 1 if you want to find Sundays, 2 for Mondays):
=floor((B2-(A2+7-weekday(A2,10+C2)))/7)+1

Automate end date depending on session type (=duration in calendars days), start date AND if bank holiday?

I am developing an automated calendar for a school on AirTable, but I am struggling to add if there is a bank holiday between the start date and end date. If the bank holiday falls on a weekday, it needs to add +1 day to the end date.
I have created a "bank holiday" table, as well as a full calendar table (containing everyday of the year and what weekday it falls on).
I'd like for the user to have the end date generated automatically by only writing the start date.
For example:
I have a session starting on Monday, 7th of march. The "session type" would be "Course 1", which has a duration of 10 days (two weeks, monday to friday - I don't know if the duration should be 14 days instead?). If there's a bank holiday in the 10 days after the start date, and it's on a weekday, it needs to add +1 to the end date. If the end date falls on a sunday, it needs to add +2 so that it ends on a Monday.
The course is divided in multiple classes, it would also be awesome to have a timeline view with the full Course and all the classes.
Here are some screenshots of my tables :
I know there is a possibility to write a script in Python with an AirTable API... but is there an easier way ?
I've dealt with a problem like this before: when an event happened in relation to other events mattered.
You'd think by the use of the words "in relation" that you could deal with this in a relational way, but I see it as a rule:
If Event A happens at Time 1, and it's so much or so little time from Event B, then do with Event A...
And, again by my way of thinking, rules are expressed in code.
And if you actually even can express that with a relation, I think it'd be very convoluted.
So, for your problem, you need to encode every schedule-able day that's 10 working days or less before a Bank Holiday (BH) so that if the day is selected you know it's less than 10 days from a BH and can conditionally add another day to the end date.
I looked at your examples, and here's my solution. I have a Calendar table which has all days, and two supporting "Bank Holiday" fields: does the date fall on a BH, and if not, is the date 10 days or less from a BH. We're looking at my All view, here:
I also have the view, Weekday, not bank holiday, and that's the view that you can pick a day from to schedule an event from the Event table.
The Event table:
You pick a day from the Start day field. Start day < 10 work days to Bank holiday? is a lookup field from the Calendar table for that day. End day is this formula:
DATETIME_FORMAT(
DATEADD(
{Start date},
IF(
{Start day < 10 work days to Bank holiday?},
14,
13),
'day'),
'ddd, MMM Do')

How to SUM duration in Google Sheets?

Time started time end Duration
6:02:53 PM 6:11:07 PM 0:08:13
6:11:22 PM 6:20:33 PM 0:09:11
6:20:48 PM 6:32:21 PM 0:11:34
6:32:44 PM 6:39:04 PM 0:06:20
6:39:28 PM 7:00:41 PM 0:21:13
7:01:00 PM 7:09:16 PM 0:08:16
7:09:40 PM 7:16:03 PM 0:06:23
7:16:03 PM 7:24:21 PM 0:08:17
7:24:45 PM 7:30:57 PM 0:06:12
7:31:27 PM 7:37:21 PM 0:05:54
7:37:21 PM 7:44:06 PM 0:06:45
I want sum of all duration entries in x hours x minutes x seconds like i have more then 1000 rows of duration when i try to use =SUM(C2:C100) I am not getting sum of total duration after sum of 24:00:00 24 hours it starts from 00:00:00
for example sum of total duration gets 24:00:00 between range of c1:c8 it will start from 00:00:00 from c9: next range kindly assist me how to overcome this issue
try:
=ARRAYFORMULA(TEXT(SUM(IFERROR(TIMEVALUE(C:C))), "[h]:mm:ss"))
spreadsheet demo
Wherever you put the =SUM(), Select that cell and do Format>Number>More Formats>Custom Number formatting, and put the same formatting that Player0 put in his answer:
What worked for me to resolve a similar problem was a suggestion by user ttarchala in Google Sheets Query multi condition sum of time duration.
I used N() function as he said, and my final formula for the duration is:
=IF(To<>"", N(To-From+(To<From))*24, "")
with To and From being Named ranges for End Time and Start Time respectively.
N() function converts the time delta into a number. Multiplied by 24, this gives the hours in decimal format, such as 2 hours 30 minutes = 2.5 hours.
From there on, there is no problem with using the built-in Sum function to calculate the total duration as a decimal. Such as, the total duration of 27 hrs 10 minutes is shown as 27.16. This sufficed for my purposes.
Time delta is calculated using a formula from https://webapps.stackexchange.com/questions/104829/calculate-time-difference-between-times-past-midnight to take into account past-midnight differences.
And the first condition, To<>"", makes sure the formula is not showing in empty cells. As soon as the End Time is filled into "To" column, the decimal duration is calculated. Then it can be used in the regular Sum function.
This seemed shorter and easier than the formulas suggested above so I am sharing it in the hopes it may help someone else. Using thus formula, I just added up the Sum of time I spent looking for this solution: 3.34 hours :)
It's a formatting problem. You formatted your reply as HH:MM:SS, therefore the number displayed is not showing the date, which would have been incremented by one. If you multiply your sum by 24, and then format the result as a pure number, you will get a number that goes above 24, and will show you the number of hours, and its decimals. If you use those hours in further calculations, the result will be correct.
In cell C1, use the formula
=IF((B1-A1)>=0, B1-A1, 1+B1-A1)
Explanation: the problem is durations that exceed the 24 hour limit, as you say.
Google Sheets has become a bit deceptive here, as it will show the correct duration for the individual time interval, but if you SUM over it, it will actually deduct the value!
A B C
23:39 1:10 1:31
When you SUM then Google Sheets will see the value in cell C1 as if it was the beginning of the same day as the time in A1. So when you in C1 do =B1-A1 then it will register as a negative duration! But it won't show up as that!
In C1 use this formula, =IF((B1-A1)>=0, B1-A1, 1+B1-A1) for individual cells in column C, when you see that cells in column B has exceeded the 24-hour limit once. The duration in C1 should still show 1:31, but now the result when doing SUM over a range of cells in column C, like =SUM(C1:C2), will now show the correct and strictly additive sum. You can safely copy this formula to all cells in column C.
PS: cells in all of the columns can have Automatic or no formatting (which I think defaults to Automatic), if your time inputs look like the above. So you don't need to format all of those cells to Time or Duration. BUT remember to format the SUM cell to Format -> Number -> Duration.
PPS: if you are manually inputting the times (for for instance time tracking), then the easiest way to keep the much simpler =B1-A1 formula is to split the time up into two rows, like this:
A B C
23:39 0:00 0:21
0:00 1:10 1:10
Then the SUM of cells in column C still becomes 1:31.

Ruby convert decimal duration (day|week|month|year) to end date

I have a start_at, a decimal quantity and an interval which is one of day | week | month | year.
start_at = Time.parse('2016-01-01 00:00:00 UTC') # leap year
quantity = BigDecimal.new('1.998') # changed from 2.998, should end on 2/29/16 sometime
interval = 'month' # could be any of day|week|month|year
With whole numbers, I've used duration i.e. 1.month, and I looked at Date#advance, though it only recognizes integer values.
It would seem simple but I cannot find anything in the standard libraries or in ActiveSupport.
References:
SO answer potentially used for input to Date#advance?
SO explanation of duration
Question
How can I establish the end_at date from a decimal?
Why? What purpose?
Proration to the second for a given amount and given interval.
Expectations
I'm looking for an end_at to the second as accurate as possible with respect to advancing the next interval(s) by the decimal quantity. Given interval = 'month', for the fractional part, when you pass the start of the month, means you are in that month and using it's duration. For example, January 2016 is 31 days, while February (leap) is 29 days (only in the leap year).
I'd say your best option is to use Ruby's date methods to advance time based on the whole number of the decimal, then calculate how many seconds your fraction is of your current interval.
So for 1.998 months, advance time 1 month. Find the current month you are in and get the .998 of the seconds in that month (i.e. for July, 31x24x60x60x.998) and then advance time that many seconds.
What does advancing time a fractional month mean?
Lets say we have the following date 2015-01-01 00:00:00 UTC. It is easy to advance exactly 1 whole month, we simply increment the number that represents months: 2015-02-01 00:00:00 UTC. Alternatively, we could view this as adding 31 days, which we know is the number of days in January.
But what if we want to advance 0.5 months from 2015-01-01 00:00:00 UTC?
We can't just increment like we did when advancing a whole month. Since we know January has 31 days, perhaps we could just advance 15.5 days: 2015-01-16 12:00:00 UTC. That sort of works.
How about 1.5 months from 2015-01-01 00:00:00 UTC? If we combine our previous approaches, we'd first increment, getting us to 0.5 left to advance and 2015-02-01 00:00:00 UTC. Then we'd take half of 28 and get to 2015-02-15 00:00:00 UTC.
But wait, what if instead we took the total number of days between the two months and then took 3/4 of that? Like 2(month) * (3/4), which would simplify to (3(month)) / 2, or 1.5(month). Lets try it.
(28 days + 31 days) * 0.75 = 44.25 days
Now adding that to 2015-01-01 00:00:00 UTC we get 2015-02-14 06:00:00 UTC. That's three-quarters of a day off from our other answer.
The problem here is that the length of a month varies. So fractional months are not consistently definable.
Imagine you have two oranges. One contains a little bit more juice than the other (perhaps 31ml and 29ml of juice). Your recipe calls for the juice of 1.5 oranges. Depending on which one you decide to cut in half, you could have either 44.5 ml or 45.5 ml. But if your recipe calls for 40 ml of orange juice, you can pretty consistently measure that. Much like you can consistently (kind of) increment a date by 40 days.
Time is really tricky. We have leap seconds, leap years, inconsistent units (months), timezones, daylight saving time, etc... to take into account. Depending on your use case, you could attempt to approximate fractional months, but I'd highly recommend trying to avoid the need for dealing with fractional months.

Resources