Check for minutes not evenly divided by 5 - sql

I have a time stored as a decimal(9,2) column in an sql-server 2005 database.
The time is represented like
Time timeInDecimal
1H 20Min 1.33
1H 30Min 1.50
and so on
I´m looking for an easy way to check whether the number of minutes except whole hours is not evenly divided by 5.
The value I'm hoping to find is where the time is 1H:23Min but not 1H:25MIN.
I just wan´t to compare the minute part of the time.
The way I do now is:
RIGHT(CONVERT(varchar(5),DATEADD(minute,ROUND(timeInDecimal * 60,0),0),108),1) not in ('0','5')
But it does hardly seems to be the ideal way to deal with this.
Feels like I can use the modulo operator for this, but how?
Or is there an even better way?
Hope for a quick answer.
Kind Regards
Andreas

Using the modulus operator, twice:
ROUND((timeInDecimal % 1) * 60, 0) % 5 <> 0
That will:
Get the fractional part and convert it to minutes.
Round it to the nearest minute (.33 hours -> 20 minutes, not 19.80).
Check whether that's divisible by 5.

Related

Google Bigquery table decorators

I need to add decorators that will represent from 6 days ago till now.
how should I do it?
lets say the date is realative 604800000 millis from now and it's absolute is 1427061600000
#-604800000
#1427061600000
#now in millis - 1427061600000
#1427061600000 - now in millis
Is there a difference by using relative or absolute times?
Thanks
#-518400000--1
Will give you data for the last 6 days (or last 144 hours).
I think all you need is to read this.
Basically, you have the choice of #time, which is time since Epoch (your #1427061600000). You can also express it as a negative number, which the system will interpret as NOW - time (your #-604800000). These both work, but they don't give the result you want. Instead of returning all that was added in that time range, it will return a snapshot of your table from 6 days ago....
Although you COULD use that snapshot, eliminate all duplicates between that snapshot and your current table, and then take THOSE results as what was added during your 6 days, you're better off with :
Using time ranges directly, which you cover with your 3rd and 4th lines. I don't know if the order makes a difference, but I've always used #time1-time2 with time1<time2 (in your case, #1427061600000 - now in millis).

How to calculate punctuality in SQL

I have two times : actual_arr and sched_arr. Both times are in the format char (YYYYMMDDHH24MISS).
Now I've to calculate the punctuality of each movement. The rows are stored as below :
MovtName Actual_Arr Sched_Arr
mvt1 20140206215900 20140206210000
Now my definition of punctuality is (in percentage) : (actual time - sched time)/sched time*100.
I know how to calculate the difference for each movement. The code snippet I used is :
Trunc((To_Date(actual_arr,'YYYYMMDDHH24MISS')-To_Date(sched_arr,'YYYYMMDDHH24MISS'))*24*60,2)
This gives the delay in minutes.
Now what do I divide this value with? This is what I cannot wrap my head around. How do I convert the sched_arr into minutes? Or in other words what is the valid denominator for the equation for punctuality?
If anybody has a more correct definition for punctuality and how to calculate it, I'm all ears.
Thanks in advance.
For a single meeting, just use the lateness in minutes as a measurement of punctuality.
When you have multiple meetings you can start to define punctuality in non-dimensional terms, such as the percentage of meetings which started more then five minutes late.

Finding maximum input (time complexity)

Assume a computer operating at 1GHz speeds — i.e. it executes 10^9 instructions/second. For each of the following time complexities, what is the largest size input n that could be completely processed in 1 week?
a) n²
b) n³
c) 2^n
This is homework. I don't need the answer I just don't know how to start the problem. Can someone please show me how to solve the first one. I could then figure out the rest. Thank you!
The way I see it is take 10^9 and subtract 10² to get the maximum input but that seems too easy.
60 seconds in a minute, 60 minutes in an hour, 24 hours in a day, 7 days in a week. That's 604800 seconds.
If you can execute 10^9 instructions per second, you can execute 604800*10^9 instructions per week - that's 6.048*10^14.
The square root of 6.048*10^14 is 24,592,681, i.e. we can process 24,592,681^2 instructions in a week, so we can process 24,592,681 sized input if it is n^2 time complexity.
The rest are pretty similar.

Print a number in decimal

Well, it is a low-level question
Suppose I store a number (of course computer store number in binary format)
How can I print it in decimal format. It is obvious in high-level program, just print it and the library does it for you.
But how about in a very low-level situation where I don't have this library.
I can just tell what 'character' to output. How to convert the number into decimal characters?
I hope you understand my question. Thank You.
There are two ways of printing decimals - on CPUs with division/remainder instructions (modern CPUs are like that) and on CPUs where division is relatively slow (8-bit CPUs of 20+ years ago).
The first method is simple: int-divide the number by ten, and store the sequence of remainders in an array. Once you divided the number all the way to zero, start printing remainders starting from the back, adding the ASCII code of zero ('0') to each remainder.
The second method relies on the lookup table of powers of ten. You define an array of numbers like this:
int pow10 = {10000,1000,100,10,1}
Then you start with the largest power, and see if you can subtract it from the number at hand. If you can, keep subtracting it, and keep the count. Once you cannot subtract it without going negative, print the count plus the ASCII code of zero, and move on to the next smaller power of ten.
If integer, divide by ten, get both the result and the remainder. Repeat the process on the result until zero. The remainders will give you decimal digits from right to left. Add 48 for ASCII representation.
Basically, you want to tranform a number (stored in some arbitrary internal representation) into its decimal representation. You can do this with a few simple mathematical operations. Let's assume that we have a positive number, say 1234.
number mod 10 gives you a value between 0 and 9 (4 in our example), which you can map to a character¹. This is the rightmost digit.
Divide by 10, discarding the remainder (an operation commonly called "integer division"): 1234 → 123.
number mod 10 now yields 3, the second-to-rightmost digit.
continue until number is zero.
Footnotes:
¹ This can be done with a simple switch statement with 10 cases. Of course, if your character set has the characters 0..9 in consecutive order (like ASCII), '0' + number suffices.
It doesnt matter what the number system is, decimal, binary, octal. Say I have the decimal value 123 on a decimal computer, I would still need to convert that value to three characters to display them. Lets assume ASCII format. By looking at an ASCII table we know the answer we are looking for, 0x31,0x32,0x33.
If you divide 123 by 10 using integer math you get 12. Multiply 12*10 you get 120, the difference is 3, your least significant digit. we go back to the 12 and divide that by 10, giving a 1. 1 times 10 is 10, 12-10 is 2 our next digit. we take the 1 that is left over divide by 10 and get zero we know we are now done. the digits we found in order are 3, 2, 1. reverse the order 1, 2, 3. Add or OR 0x30 to each to convert them from integers to ascii.
change that to use a variable instead of 123 and use any numbering system you like so long as it has enough digits to do this kind of work
You can go the other way too, divide by 100...000, whatever the largest decimal you can store or intend to find, and work your way down. In this case the first non zero comes with a divide by 100 giving a 1. save the 1. 1 times 100 = 100, 123-100 = 23. now divide by 10, this gives a 2, save the 2, 2 times 10 is 20. 23 - 20 = 3. when you get to divide by 1 you are done save that value as your ones digit.
here is another given a number of seconds to convert to say hours and minutes and seconds, you can divide by 60, save the result a, subtract the original number - (a*60) giving your remainder which is seconds, save that. now take a and divide by 60, save that as b, this is your number of hours. subtract a - (b*60) this is the remainder which is minutes save that. done hours, minutes seconds. you can then divide the hours by 24 to get days if you want and days and then that by 7 if you want weeks.
A comment about divide instructions was brought up. Divides are very expensive and most processors do not have one. Expensive in that the divide, in a single clock, costs you gates and power. If you do the divide in many clocks you might as well just do a software divide and save the gates. Same reason most processors dont have an fpu, gates and power. (gates mean larger chips, more expensive chips, lower yield, etc). It is not a case of modern or old or 64 bit vs 8 bit or anything like that it is an engineering and business trade off. the 8088/86 has a divide with a remainder for example (it also has a bcd add). The gates/size if used might be better served than for a single instruction. Multiply falls into that category, not as bad but can be. If operand sizes are not done right you can make either instruction (family) not as useful to a programmer. Which brings up another point, I cant find the link right now but a way to avoid divides but convert from a number to a string of decimal digits is that you can multiply by .1 using fixed point. I also cant find the quote about real programmers not needing floating point related to keeping track of the decimal point yourself. its the slide rule vs calculator thing. I believe the link to the article on dividing by 10 using a multiply is somewhere on stack overflow.

Excel Time Formula

I have the following formula:
=IF(MROUND(((D4-C4+IF(C4>D4,1)-INT(D4-C4+IF(C4>D4,1)))*24), 0.25) < 0.15, 0.25, MROUND(((D4-C4+IF(C4>D4,1)-INT(D4-C4+IF(C4>D4,1)))*24), 0.25))
this formula gets the time between a start and stop time and rounds it up to the nearest 15 minutes. I have a problem with it when no time is entered and it = 15 minutes.
If anyone can help so it says 0 or even a less complex solution that would be great thank, I am thinking a macro what does everyone think?
The formula as written says:
If the first term occurs later than the second one, assume that the first term occurs the next day.
Ignore any day information (invalidating the last point).
If the difference in hours rounded to the nearest fifteen minutes is less than 0.15 of an hour (9 minutes), return fifteen minutes, else return said difference.
So if you want for it to give zero if neither time is entered, just simplify the formula like this:
=MROUND(24*MOD(A14-C14,1),0.25)
which gives zero if the difference is between 0 and 7.5 minutes (Excel just assumes that an empty cell is zero, midnight in this case), otherwise it gives the same results.