Timesheet Batch Aggregator

Turn a raw punch CSV into per-employee, per-week regular, overtime, night and holiday hours - computed entirely in your browser, never uploaded.

Your attendance data never leaves this browser tab. Nothing is uploaded — open your browser's DevTools › Network tab and watch: aggregating the timesheet makes zero requests.

This tool only aggregates hours. It does not judge legal violations or recompute pay — the 52-hour cap check and the ordinary-wage recalculation are separate tools that take this output as their input.

One date per line or comma-separated. Or map a "holiday" column below (any non-empty value marks a holiday).

…or drop a .csv / .tsv file into this box

Nothing loaded yet. Paste your punches above, or load the sample data. Nothing is uploaded — every row is parsed inside this browser tab.

Frequently asked questions

How are regular, overtime, night and holiday hours each defined and calculated?

For every punch this timesheet calculator computes worked minutes = (clock-out − clock-in) − break. It then splits the week into buckets. Overtime depends on the country: in Korea it is the daily hours over 8 (with weekly hours over 40 noted for reference); night hours are the overlap of the worked interval with 22:00–06:00; holiday hours are hours worked on a holiday, weighted 1.5× within 8h and 2× beyond. The "converted hours" column is a premium-weighted total (regular + overtime × factor + night × factor + holiday premium) — it is an hours figure, not a pay amount, because no wage is entered.

Why do the overtime rules differ by country (Korea daily, US FLSA weekly, California, EU)?

Overtime thresholds are statutory and differ by jurisdiction, so this overtime hours calculator branches on a country setting: Korea counts daily hours over 8; US federal FLSA counts weekly hours over 40; California counts daily hours over 8 (and over 12 as double-time, plus a 7th-consecutive-day rule); the EU applies no premium here but flags working-time compliance (weekly hours over 48, no weekly rest day, less than 11 hours rest between shifts). The premium factors and thresholds are static constants you pick from the country selector — defaulting from your browser locale and overridable.

How is an overnight shift that crosses midnight assigned to a day and week, and how are night hours caught?

When the clock-out time is at or before the clock-in time, the shift is treated as ending the next day (+24h) and tagged "overnight" rather than dropped. The whole shift is attributed to the week of its clock-in date, so a Sunday-night-into-Monday shift stays in the earlier week. Night hours are the exact intersection of the worked interval with the 22:00–06:00 window, computed across the midnight boundary, so a 22:00–06:00 shift yields a full 8 night hours. Shifts longer than 16 hours are treated as unreasonable and excluded with a reason.

How are dirty rows like a missing clock-out or a duplicate punch handled?

Nothing is silently dropped. Rows with a missing employee ID, an unparseable date, a missing or unparseable clock-in/clock-out, a non-numeric or negative break, a break longer than the shift, or an unreasonable span are excluded and listed in an "excluded rows" report with a per-reason count. Exact duplicate punches (same employee, date, clock-in, clock-out and break) keep the first and exclude the rest as duplicates. That way your totals never quietly absorb a bad row.

Is our attendance data sent to a server, and how can I verify it?

No. CSV parsing, encoding detection, the time and date parsers, sorting and the per-employee, per-week roll-up all run inside your browser tab, so employee IDs and clock times never reach any server, and there is no signup, email or upload. You can verify it yourself: open your browser's developer tools, go to the Network tab, then load your file and aggregate — you will see zero requests carrying your data. That is why security teams clear it where uploading attendance to a SaaS would be blocked.