Skip to content
PN Scripts

Development

Night work and overtime in a Bulgarian shift rota: the 8/7 coefficient with a worked example

  • PN Scripts
  • 9 min read

This guide explains the rules as published; it is not legal advice. Your internal rules, your collective agreement and your accountant or lawyer have the final word on your rota and your payroll.

A hotel reception, a security post, a hospital ward or a bakery that starts at four cannot fit its work into five days of eight hours. In Bulgaria such teams usually work under summarised working time: hours are counted over a period instead of day by day, and night hours are converted into day hours before they are compared with the norm. That conversion, the 8/7 coefficient, is where many hand-made rotas go wrong. A night porter who worked 154 hours in December can be two hours over the norm, not six hours short. Here are the rules with their sources, the arithmetic in Python, and one month worked through.

#The rules in one place

Night work is work between 22:00 and 06:00 (Labour Code, article 140(2)). The normal working day is up to 8 hours (article 136(3)), and the normal night is up to 7 hours with a five-day week (article 140(1)). A shift that mixes day and night counts as a night shift when it has 4 or more night hours, and as a day shift when it has fewer (article 141(2)).

With summarised working time (article 142(2)) the employer sets a period of 1 to 4 months (article 142(3); up to 12 months through a collective agreement). A shift can then be up to 12 hours, and a week up to 56 hours (article 142(6)). The detailed rules are in the Ordinance on working time, rest and leave (Наредба за работното време, почивките и отпуските):

  • The norm for the period is the number of working days in the calendar times the daily hours in the contract, less the days of paid leave taken on working days (article 9b(2)); sick leave and pregnancy, birth or parental leave take off the hours the schedule had for those days instead (article 9b(3)).
  • The employer approves named schedules for the period and keeps them for at least 3 years (article 9a(1)).
  • Before the scheduled hours are compared with the norm, the night hours of every shift with 4 or more night hours are converted into day hours with the coefficient of article 9(2) of the Ordinance on the structure and organisation of pay. There is no conversion where reduced working time applies to the job, or where the contract is for night work only (article 9a(4)).
  • Hours worked above the norm at the end of the period are reported as overtime (article 9g).

The coefficient is the ratio between the normal day and the normal night for the workplace (Ordinance on pay, article 9(2)). With an 8-hour day and a 7-hour night it is 8/7, about 1.143. Every converted night hour counts as 1.143 hours against the norm.

#The arithmetic in code

Three small functions are enough. The sample is plain Python and was run as printed.

from datetime import date, datetime, timedelta

NIGHT_FROM, NIGHT_TO = 22, 6   # Labour Code, art. 140(2)
COEF = 8 / 7                   # 8-hour day (art. 136(3)) to 7-hour night (art. 140(1))


def night_hours(start: datetime, end: datetime) -> float:
    """Hours of a shift that fall between 22:00 and 06:00."""
    total = 0.0
    day = datetime.combine(start.date() - timedelta(days=1), datetime.min.time())
    while day < end:
        a = day + timedelta(hours=NIGHT_FROM)
        b = day + timedelta(days=1, hours=NIGHT_TO)
        total += max(0.0, (min(end, b) - max(start, a)).total_seconds() / 3600)
        day += timedelta(days=1)
    return total


def schedule_hours(shifts: list[tuple[datetime, datetime, float]]) -> float:
    """Hours that count against the norm. Night hours of a shift with 4 or more of them are
    converted to day hours (ordinance on working time, art. 9a(4))."""
    total = 0.0
    for start, end, break_hours in shifts:
        worked = (end - start).total_seconds() / 3600 - break_hours
        night = night_hours(start, end)
        total += worked + (night * (COEF - 1) if night >= 4 else 0)
    return total


def norm(year: int, month: int, days_off: set[date], hours_a_day: float = 8) -> float:
    """Working days of the month (Monday to Friday, less holidays and moved days off) x hours a day."""
    d, n = date(year, month, 1), 0
    while d.month == month:
        n += d.weekday() < 5 and d not in days_off
        d += timedelta(days=1)
    return n * hours_a_day

night_hours() walks over the nights that a shift can touch, so a shift from 20:00 to 08:00 gives 8 night hours and a shift from 15:00 to 23:30 gives 1.5. schedule_hours() adds the extra seventh of an hour for each night hour, but only for shifts with at least 4 of them. Here the break is taken off the worked hours but not off the night hours; if your internal rules place breaks inside the night, count them the way your rules say.

#A worked example: one receptionist in December 2026

December 2026 has 23 weekdays. Three of them are days off: 24 and 25 December, and Monday 28 December, which replaces 26 December because that falls on a Saturday (article 154(2)). That leaves 20 working days, so a receptionist on 8 hours a day has a norm of 160 hours. We covered the holiday calendar in our guide to Bulgarian working days and holidays.

The rota gives this receptionist seven day shifts from 08:00 to 20:00 and seven night shifts from 20:00 to 08:00, each with a one-hour break. The code gives:

  • Worked hours: 14 shifts of 11 hours, 154 hours.
  • Night hours: 8 in each night shift, 56 in all.
  • Converted: 56 night hours times 8/7 are 64 day hours, so the night shifts add 8 hours.
  • Scheduled hours: 154 plus 8, 162 hours, against a norm of 160.

Without the conversion the rota looks 6 hours short. With it the receptionist is already 2 hours over the norm. If the period is one month, those 2 hours are overtime: paid with an increase of at least 50 percent for summarised working time (article 262(1)(4)) and counted against the limits of article 146: 150 hours a year, and in a month no more than 30 hours of day or 20 hours of night overtime. Overtime is allowed only in the cases of article 144, so the better fix is usually to plan 160 hours, not to pay for 162.

Two more shifts show the threshold. An evening shift from 15:00 to 23:30 has 1.5 night hours: it stays a day shift and nothing is converted. A shift from 19:00 to 03:00 has 5 night hours, so it is converted: 8 hours become 8.71.

#Night pay is a separate rule

The conversion changes the hours that count against the norm; it is not a pay rate. Pay for night work is set separately: for every night hour, or part of one, between 22:00 and 06:00 there is a supplement of at least 0.15 percent of the national minimum wage, and not less than 0.51 euro (Ordinance on pay, article 8, as amended from 1 January 2026). With the 2026 minimum wage of 620.20 euro a month, 0.15 percent is about 0.93 euro an hour. The supplement is due for the evening shift's 1.5 night hours as well, even though they are not converted.

#What else a rota should check

  • At least 12 hours of rest between two working days (article 152).
  • With summarised working time, at least 36 hours of uninterrupted weekly rest (article 153(2)), or not less than 24 hours when the shifts change and the organisation of work requires it (article 153(3)).
  • Who may not work at night (article 140(4)): employees under 18 and pregnant employees; mothers of children under 6, and some other groups, only with their consent.
  • Employees who work at least 3 night hours as a rule are night workers: a medical examination before they start and periodic ones after (article 140a).

#A spreadsheet that does the counting

We built these rules into Smenka, a monthly shift rota workbook for Excel and LibreOffice in Bulgarian and English, with no macros. You pick a shift code for each person and day; it marks the official holidays and moved days off for 2026 to 2030, and works out each person's hours, norm, overtime or shortfall, night hours, holiday and weekend hours, leave and sick days. It flags rest under 12 hours and too many days in a row, and counts people per shift against the number you need. Smenka converts night hours with the coefficient from its Settings sheet only in shifts with 4 or more night hours, and a column next to the totals marks a person with reduced working time or a night-only contract, whose night hours stay as they are (article 9a(4)). Sick leave is entered with the sick code of the shift that was scheduled, so the norm loses that shift's hours (article 9b(3)). It was tested by letting LibreOffice Calc calculate 28 workbooks and comparing more than 3,000 values with an independent Python model, and is listed as Coming soon.

#Frequently asked questions

Why is the night coefficient 1.143?

It is the normal day divided by the normal night: 8 hours by 7 hours. The Ordinance on pay defines the coefficient as that ratio for the workplace, so a workplace with a different normal day has a different coefficient.

Are all night hours converted into day hours?

No. Under the ordinance on working time only shifts with 4 or more night hours are converted, and not where reduced working time applies or where the contract is for night work only.

Are the converted hours paid as overtime?

Only the hours above the norm at the end of the period are overtime. The conversion decides whether there are such hours; the extra pay is then at least 50 percent for summarised working time.

#Sources

Keep reading

Keep reading

Comments

Comments

Be the first to leave a comment.

Leave a comment

Next step

pnscripts.com/contact

Talk to the team

Ask about an article, or tell us about a project you want built. We reply within one business day.

Write to us

The PN Scripts family

Other PN Scripts sites

Hosting, games and the blog each have their own site, run by the same company.

  • pnscripts.com

    PN Scripts

    Software engineering

    Custom web, mobile, API and game development, plus our open-source products and plugins.

  • games.pnscripts.com

    Games

    Games and game servers

    The home for PN Scripts games: free browser games you can play right now, with game servers coming soon.

  • hosting.pnscripts.com

    Hosting

    Hosting and infrastructure

    Shared hosting, KVM VPS, dedicated servers and domains, from the same company that builds your project.

  • blog.pnscripts.com

    Blog

    Articles and field notes

    Practical articles on software development, hosting, open source and games, written by the people who build them.

    You are here