How to find out how many (if any) weekends occur in a given period - unix-timestamp

I have two numbers; dates in Unix Epoch format.
Say I have two Unix Epoch timestamps:
1349422200 = 05/10/2012 08:30
1350489600 = 17/10/2012 17:00
I am able to find out how many days are between the two date/times, no problem.
What I would like to be able to work out is how many of those days are Saturdays or Sundays (Non-Weekdays). I'm sure there has to be an easy way to go about this but I can't for the life of me figure it out without doing a load of for() loops.
Any help greatly appreciated.

Be more specific with your definition of weekend. Do you only want to include whole weekends (the entire 48 hour period of saturday and sunday)? Or does any range of time containing midnight on Friday night/Saturday morning count as a weekend? Do half weekends count as half, or do you round to the nearest whole number?
In any case:
Figure out what comprises a weekend
Find the first and last weekends in your range of time
Find the time difference between them, in days, and divide by 7
Edit: you're seeking the exact amount of weekend time, with no rounding.
First, split the timespan into 3 chunks:
Everything from the beginning of the range up until the first possible Monday morning at midnight
Everything from the end of the previous block up to the last possible Monday morning at midnight
Everything from the end of the previous block to the end of the range
Then calculate the amount of weekend in each block, and sum them up.
The first block will contain no weekend time if it has a length of zero. If it has a length of 48 hours or less, its weekend time will equal its length. Otherwise, its weekend time will be 48 hours.
The middle block's weekend time is its duration multiplied by 2/7 (trivial, since by our restrictions on its start and end, it is a whole number of weeks.)
The final block will contain no weekend time if its duration is less than or equal to five days. If its duration is greater than five days, its weekend time will equal its duration minus five days.
Special cases
If the block contains no monday midnights, consider the second and third blocks to have a length of zero. Find the beginning and the end of the one weekend inside the block (if it exists) and calculate the overlap.
If the block contains exactly one monday midnight, consider the first block the time before it, the second block to be of zero length, and the third block the time after it, and calculate as usual.

I'm sure there are some much faster and less-processor hungry methods to getting around this. But for me this method was good enough and gets the job done.
//$sDateRaw = First day at 00:00 in Unix Epoch
//$eDateRaw = Last day(+1) at 00:00 in Unix Epoch
//86400 = Number of seconds in 1 day
for($i=$sDateRaw;$i<$eDateRaw; $i+=86400){
if(date("N",$i) != 6 && date("N",$i) != 7){
$weekDays += 1;
}
}
//$weekDays = Total number of days excluding weekends

Related

Trying to Average number of accounts by hour, day of week, and month

I'm in healthcare and we're trying to assess the number of discharges we have per hour of day, but we'd also like to be able to filter them down by day of week, or specific month, or even a particular day of week in a particular month (e.g. " what is the average number of discharges per hour on Mondays in January?")
I'm confident that Tableau can do this, but haven't been able to make the averages show up in my line graph... every time that I convert it from COUNT to AVG, the line simply goes straight. I got close when I did a table calculation to find the Average (dividing the count per hour by the number of days captured in the report), but when I add a filter for either the month or day of week, selecting one of the options of the filter reduces the total number that is being counted, rather than re-averaging the non-filtered items. (i.e. if the average of the 7 days of the week is "10" for a particular hour, and I deselect the first three days of the week, it's now saying that my average for that hour is roughly 6, despite the fact that all of the days are very close to 10 at that hour.)
Currently, my data table has the following columns:
Account#/MonthYear/HourOfDay/DayOfWeek
ex.12345678/ Jan-17 / 12 /Sunday
I would just create a few calculated fields to differentiate the parts of the calendar you might want to filter/aggregate on. Mixing the month and day of the week with filtering is pretty straight forward with the calculated fields. Then do standard summing to get what you are looking for because an average count of records is always one unless you are throwing some other calculation into the mix. I threw a quick example up on Tableau Public for you to get the idea.

PostgreSQL: Calculate elapsed hours across time change

How can I calculate the number of hours between two times, taking into account the change from standard to daylight savings time between them?
I need to determine which crew is working in my customer's plant. There are four possibilities, changing in a known order from one to the next every four days, so the crew pattern recurs every 16 days. I had planned to store a reference time in my database. To calculate the crew, I would calculate the elapsed hours between the reference time and the current time, modulo it by 384, and use crew A if the result is below 96, crew B for 96-192, and so on.
I am pretty sure that in the spring, when an hour is repeated at the time change, the crew shift is 13 hours long, and in the fall, the crew shift is only 11 hours long. My scheme, at least if it relied on timestamp with time zone objects, would be wrong for an hour every shift for half the year.
Thank you.

Find and Rank Time Series MATLAB

I know there must be a simple way that I can learn to do this but I cannot imagine how to start. I am tasked with finding a top 10 matching daily wind power time series in a 30-day plus/minus window from the first day in the time series (Jan 1st) matching a single daily wind power time series and it is out of my level of experience in MATLAB. I have successfully done this matching a single time series of the current year with the exact calendar days from previous years, but I need a more robust searching method to find the best correlated time series in a +/- window of time. For example, I'm comparing a 120 day time series (without leap years) with 25 previous years during the same 120-day period (Jan-Apr). The end result will show me the top 10 time series with the years and Julian day or cumulative day listed and a correlation or RMSE value associated with it. My data looks like this arranged in a 365 (days) X 25 (years) array and I thank you very much for your help!
1182573 470528 1638232 2105034 1070466 478257 1096999
879997 715531 1111498 1004556 1894202 1372178 1707984
636173 937769 2119436 742710 1625931 1275567 1228515
967360 1103082 2218855 1643898 1822868 554769 1325642

MATLAB Datenum does not work properly with find

I have two sets of time series data which are collected with different time intervals. One is measured every 15 minutes and the other every 1 minute.
The measured variables are oxygen concentration, oxygen saturation and time, all three of which are measured using the two different instruments which have the different time intervals (6 column arrays in total).
I have two times between which I want to find the index's of all the entries at 15 minute intervals in the time column that sit between them.
co=1;
for i = datenum('03/11/2014/10/00/00','dd/mm/yyyy/HH/MM/SS'):datenum('03/11/2014/00/15/00','dd/mm/yyyy/HH/MM/SS')-datenum('03/11/2014/00/00/00','dd/mm/yyyy/HH/MM/SS'):('03/11/2014/16/00/00','dd/mm/yyyy/HH/MM/SS');
u=find(xyl_time==i);
New_O2(co,1)=xyl_o2conc(u);
New_O2(co,2)=xyl_o2sat(u);
v=find(sg_time==i);
New_O2(co,3)=sg_o2conc(v);
New_O2(co,4)=sq_o2sat(v);
co=co+1;
end
however, this does not work. I have narrowed it down and its something to do with the time interval that I'm using. I want it at every 15 minutes, but when I produce the 15 minute interval and then datestr that number, it comes up with '12:15AM'. I think this is causing the problem, but have no idea how to produce just times alone i.e I just want 00:15 not 12:15 not 00:15 AM or PM. just spacings of 15 minutes for my for loop.

calculating number of days between 2 days tcl

I am calculating the number of days between two dates(the 2 dates are in seconds). The following gives me the coorect result but it gives me a negative value.
For example -7.0. I am not sure why..
Also can I remove the decimal point and display?
set interval [expr { $start_date - $get_date }]
set days [expr { floor($interval / (60*60*24)) }]
puts "Start Date: $start_date <br>"
puts "Stop Date: $get_date <br>"
puts "Total number of dates betwen 2 days: $days"
You're subtracting the end (assuming that's what $get_date is) from the start. Think of it like numbers, where a later date is a bigger number - if you subtract a large number from a small number, you get a negative value, right?
So you probably just want to reverse the arithmetic:
set interval [expr { $get_date - $start_date }]
I've no idea about the decimal point part, I'm afraid... perhaps (based on this documentation) just:
set days [expr { int($interval / (60*60*24)) }]
EDIT: As noted in comments, some care is required when it comes to "days" between two events. Do you mean elapsed days, 24 hours per day, or "local" days? Are your input values in local time, UTC, or something else? Could you perhaps use a dedicated date/time library to handle this? (I have no idea whether tcl has such a thing, but I'd expect it to.)
You should think really carefully about exactly what behaviour you want in what situation, and write tests accordingly.
Not all days are 86400 seconds long, because of little things like daylight savings time. Because of this, you need to do some rounding in your calculation (and use floating point division):
set days [expr {round($interval / double(60*60*24))}]
You also usually subtract the start from the end when calculating the length of an interval, not the other way round. Gets the sign right.