1

I'm working on a script that calculates my salary, for each of my work days, since we don't get the plan send out electronic. We do earn extra withing some time periods.

every hour i earn 61.86 DKK, but at within some time periods i earn extra money, as seen below. (For simplicity i have calculated the time in 24h cycle, since that what i am used to)

Weekdays (18:00 - 06:00) 12.20 DKK
Saturday (15:00 - 24:00) 21.65 DKK
Sunday (whole day)       24.50 DKK

So fare i have worked out, how to calculate the extra money and the hourly rate fine. Although my problem is, if i have a work guard that starts 20:00 and ends next day 4:00 then it will give me and error. I have an IF statement that activates if the hour is above 18(which is when i get extra in the weekdays) then i subtract the hour count with 18 to get, how many hours that's i need to earn extra.

    if d2.isoweekday() <= 5: #If its a weekday
    if d2.hour >= 18:
        extra += ((d2.hour - 18) * weekdaySalary) + ((d2.minute / 60) * weekdaySalary)

How do i detect, exact how many hours that's between a specific period?

like if i have to dates

26-12-2014 17:00
27-12-2014 08:00

i need a way to see how many of those work hours is within the time period(18:00-06:00). how can this be done? it's like having 2 diffrent date ranges. 1st - for when i get extra. 2rd - for when i actually work.

26-12-2014 17:00
18:00 - extra money period start here
   |
   |how do i get the time between these to points?
   |
06:00 - extra money period ends here
27-12-2014 08:00

it could also be like this

26-12-2014 17:00
18:00 - extra money period start here
  |
  |how do i get the time between these to points?
  |
27-12-2014 04:00
06:00 - extra money period ends here

Every answer is highly appreciated, spent so much time trying to figure out with no really result.

RasmusGP
  • 4,696
  • 5
  • 21
  • 28
  • Just to be clear: in your example, the answer would be 13 (7 hours on the 26th and 6 on the 27th)? – Scott Hunter Dec 26 '14 at 16:45
  • Yes, Scott but only extra money for 6 hours on the 26th and 6 on the 27th. the other ones are just regular. – RasmusGP Dec 26 '14 at 17:10
  • For each day in question, you have a span of time, say A..B. Add the amount of time from A to 6:00 with the amount of time from 18:00 to B; that will be the amount of time worked for that day. (It wasn't clear from your question how you want to handle partial hours.) – Scott Hunter Dec 26 '14 at 17:11
  • I'm srry my question wasn't clear just edited it. So you would take it day for day and them add them together in the end? – RasmusGP Dec 26 '14 at 17:21
  • It's very hard to explain what i need to know. I see my question has been marked as duplicated. But the one that my question has been compared to, is just to figure out if a date is between 2 other dates. My question is how to figure out how many hours or mins that's within 2 dates. – RasmusGP Dec 26 '14 at 17:27
  • related: [Difference Between Two Times (python)](http://stackoverflow.com/a/27651318/4279) – jfs Dec 27 '14 at 07:21

1 Answers1

1

Based on the two ranges you provided, presuming they are when your shift starts and ends, the following will calculate pay from start of shift to end, increasing by basic rate or basic rate plus extra pay based on the time of day:

def calculate_ot(t1,t2):
    t1 = datetime.strptime(t1, "%d-%m-%Y %H:%M")
    t2 = datetime.strptime(t2, "%d-%m-%Y %H:%M")
    days = ((t2 - t1).days * 86400)
    hours, rem = divmod((t2 - t1).seconds + days, 3600)
    start_ot = datetime.strptime("18:00 {}".format(t1.date()), "%H:%M %Y-%m-%d")
    end_ot = datetime.strptime("06:00 {}".format(t2.date()), "%H:%M %Y-%m-%d")

    total_pay = 0
    for x in range(hours): # loop in total hour time difference
        # if we are within the range of extras pay increase by normal rate plus ot
        if start_ot <= t1 < end_ot and t1 < t2:
            total_pay += 62 # or 62.20 you have conflicting examples
        else:
            # else just add basic pay rate
            total_pay == 50
        t1 += timedelta(hours=1) # keep adding another hour
    return total_pay
Padraic Cunningham
  • 176,452
  • 29
  • 245
  • 321
  • I may have not explained myself well enough, but this is just finding hours between 2 dates, i need to find how many hours that's within 2 dates. Like i have 2 time ranges. t1 = "26-12-2014 18:00" t2 = "27-12-2014 06:00" Only time is required here t1 = "17:00" t2 = "08:00" how many hours is within 17:00 till 08:00 next morning? – RasmusGP Dec 26 '14 at 18:01
  • there are 15 hours, if you just want hours just use the hours. `5pm - 12am -> 7hrs` `12am - 8am -> 8hrs` `8 + 7 = 15`. You have to use the dates or the answer will be 9 hrs – Padraic Cunningham Dec 26 '14 at 18:02
  • I am sorry I don't understand there are either 9hrs if you consider them the same day or 15hrs if you are actually talking about two different days – Padraic Cunningham Dec 26 '14 at 18:07
  • But what if i need to know, how many hours that a time ranges goes into another. – RasmusGP Dec 26 '14 at 18:07
  • so you are talking about four times then t1,t2 start of sub range and end of sub range – Padraic Cunningham Dec 26 '14 at 18:08
  • @RasmusGP, I added another part to my answer, let me know if that is closer to what you are asking – Padraic Cunningham Dec 26 '14 at 18:22
  • so 6am is the cutoff? – Padraic Cunningham Dec 26 '14 at 19:18
  • [Picture](https://lh6.googleusercontent.com/DbR26WdSbmFkg4QpFLnBUiXQjMZum2cU4_8TmBDwgSt8-Amu0mRSEfcvIeGJ04WxqJIYFsjqxkI=w1342-h523) Well still not what im looking for. I have made a picture, to show what im looking for. As you see i, my work day starts 17:00 and ends 20:00. Then the first hour, i only get the regular salary, then from from 18:00 till 20:00 i get regular salary + extra 12.20 DKK. So i need to know how many hours, my workday goes into the extra money period(18:00-06:00next day) – RasmusGP Dec 26 '14 at 19:31
  • 6am is when the extra money period stops. from 18pm till 6am i get addtional 12.20 DKK. If i start working 17pm and stop 19pm, then i get get 50DKK for each our i work so thats 100DKK. BUT because i work in extra money zone(18pm - 6am) i get additional we say 12DKK each hour so that's 100 + 12 = 112DKK in total – RasmusGP Dec 26 '14 at 19:36
  • I will expand the answer when i get back on my laptop but the logic is still the same – Padraic Cunningham Dec 26 '14 at 19:38
  • @RasmusGP, I added a final attempt, it does exactly what your last comment suggests is correct. – Padraic Cunningham Dec 27 '14 at 00:08
  • Thank you @Padraic Cunningham such a huge help! That is what i needed :D Thanks for taking some time helping me. I'm srry i explained myself that bad, i'll try improve that for next time. – RasmusGP Dec 27 '14 at 15:26
  • If i want to change it to minutes how should i do that? – RasmusGP Dec 27 '14 at 20:17
  • 1. If you don't want to use `timedelta.total_seconds()` for some reason then refactor `.seconds, .days` manipulation into a separate function e.g., 1st code example ignores `.days`. 2. Separate input (and its parsing) and pure computations into different functions (better design) 3. Your solution ignores timezone issues. When you are dealing with money, correctness is important otherwise either employees or the employer will be pissed after DST transitions. To handle timezones correctly, see [my answer to the related question that I've linked above](http://stackoverflow.com/a/27651318/4279). – jfs Dec 28 '14 at 11:07
  • @RasmusGP, so you want to calculate partial hours? – Padraic Cunningham Dec 28 '14 at 12:44
  • @Padraic Cunningham if your answer you calculated hours, and it works great, but if i wanted to calculate the rest minutes like: work day starts: 6pm and ends 10:15pm then i worked 4 hours and 15 minutes if i use your method you posted, i'll get 4 as a answer if i want to get it as minutes instead what do i then do? – RasmusGP Dec 30 '14 at 01:10
  • @RasmusGP, I will update the answer tomorrow when I get a chance – Padraic Cunningham Dec 30 '14 at 01:12