{
  "name": "Weekly time card: clock punches to paid hours, and the split at the threshold you type",
  "page": "https://otherworldlabs.com/weekly-time-card-hours-and-pay/",
  "endpoint": "https://otherworldlabs.com/weekly-time-card-hours-and-pay/api.json",
  "question": "For one week of daily in and out clock punches with an unpaid break a day, what is each day's clock span, what are its paid hours once the typed break comes out, what does the week foot to in payroll decimal and in hours and minutes, how does that total split either side of the weekly overtime threshold the caller types, and what does each side come to at the rate the caller types for it?",
  "answers": "one week of seven days at a time, one card; the page keeps no history and this endpoint stores nothing",
  "version": "2026-10-20",
  "licence": "The arithmetic is not ours to license. Reuse the formulas; the page is free and needs no attribution.",
  "method": "static description plus a worked example; the same formulas run in the page in the reader's browser, with nothing sent anywhere",
  "currency": "whatever the rates are entered in; the page does no conversion and attaches no currency to a figure",
  "direction": "The calculation runs forward from punches that have already been made: it takes a week of in and out times, an unpaid break a day, a weekly overtime threshold and two rates, and prints the hours and the money. It does not plan a week, it does not schedule anybody, and it does not read any figure back from any week but the one typed.",
  "rounding": {
    "clock": "Each punch is read as a count of minutes after midnight from HH:MM, with hours 0 to 23 and minutes 0 to 59. Anything else - a blank field, a bare number, a word, an hour past 23 - is NOT A TIME, and a day with no usable pair of punches contributes nothing to the week and is named in its own row rather than carried as a zero-length day. In the one-line form, where a punch arrives as an hour and a minute rather than as HH:MM, the hour times sixty plus the minute is rounded to a whole minute first, which is what the workbook sold beside this page does with the same two cells.",
    "spans": "Whole minutes, exactly, with no rounding at all: a span is one count of minutes less another. Where the out punch is not later in the clock than the in punch the span is the minutes of a day (1440) less the in punch plus the out punch, which is the only arithmetic reading of a day that ends after midnight; two identical punches therefore read as 1440 minutes.",
    "decimal_hours": "round2(minutes / 60), two decimals. Each day's own decimal is rounded for printing; the week's decimal is computed from the week's total minutes and NOT from the sum of those rounded days, so a week does not inherit seven roundings. Both figures are printed, and where they part company the page says so. A count of whole minutes over sixty can never land on a third decimal of 5, so no tie is read there at all; the one-line form below can carry a fractional minute, and a tie in it is rounded away from zero like any other.",
    "money": "round2(x) = sign(x) x (Math.round(|x| x 100) / 100), which is half AWAY FROM ZERO in both directions: -0.005 comes out as -0.01, where Math.round(-0.005 * 100) / 100 would give -0 and so -0.00. The sign is taken out before the rounding and put back after. The magnitude is multiplied by a hundred on the double and that product is rounded half up, with nothing normalised first, because that is character for character what ROUND(x, 2) does in the workbook sold beside this page: 127.575 comes out as 127.58 and 1.005 as 1.00, and a fifteen-digit normalisation would disagree with the workbook on the second of those. Hours are rounded by the same function at two decimals, and a count of minutes at none.",
    "counts": "Whole, where the control's step is whole: the break is minutes, and a figure outside the range the control offers is brought to the nearer end of that range before anything is computed.",
    "typed_figures": "The threshold and the two rates are each brought inside their range AND THEN HELD TO TWO DECIMALS, half away from zero, before anything is computed with them: round2(clamp(x)). A threshold typed as 40.1 is computed as 40.10 and a rate typed as 22.125 as 22.13, which is the rate the card's own foot prints beside the money, so the figure the page computes with is the figure it shows. The step each control advertises - a quarter of an hour on the threshold, a cent on the rates - is what the control OFFERS and not a constraint on what may be typed: a figure off the step is held to two decimals as above and never snapped to the step, because snapping would turn a reader's own typed threshold into a different one. This entry was missing until 2026-10-24: the page rounded and this description did not say so, which moved a printed pay figure by twenty cents at a state the page itself declares (REVIEW-round1 blocking 2, and its minor 1 on the step)."
  },
  "clamping": "Every figure is brought inside the range the page's own control offers before anything is computed, and the ranges in `inputs` below are those controls' own min, max and step. Three fields have no meaningful zero typed by default and are carried as NOT TYPED rather than clamped up to the bottom of their range: thresholdHours, rateRegular and rateOver are each null while blank, and while any of them is null the page prints no figure that depends on it. A day's break is carried as NOT TYPED while it is blank, which is what makes the day incomplete; a typed 0 is a real figure and completes the day. The two text fields and the week-ending date are echoed and parsed, never clamped.",
  "inputs": [
    {
      "name": "weekEnding",
      "type": "string",
      "required": false,
      "range": "YYYY-MM-DD, as the date control offers it",
      "note": "The last day of the week this card covers. The six rows before it are dated backwards from it, one day at a time, in UTC, so no figure depends on the reader's clock or time zone. Anything that is not a valid date leaves every row labelled by its own number (Day 1 to Day 7) and changes no figure."
    },
    {
      "name": "cardName",
      "type": "string",
      "required": false,
      "range": "up to 40 characters",
      "note": "Whose card it is, in the reader's own words, for the head of the printed card. It is echoed and nothing else; no figure depends on it. It is kept in the reader's own browser under one key so a second card starts with it, and it is sent nowhere."
    },
    {
      "name": "cardRef",
      "type": "string",
      "required": false,
      "range": "up to 24 characters",
      "note": "The reader's own reference for this card, echoed at the head of it. No figure depends on it."
    },
    {
      "name": "days",
      "type": "array",
      "required": true,
      "range": "exactly 7 members, one per day of the week",
      "note": "The week. Each member carries `in`, `out`, `breakMins` and `notWorked`, described below. The array is always seven long: there is no count input, because a week is seven days and a day is blank, punched, or ticked as not worked."
    },
    {
      "name": "days[].in",
      "type": "string",
      "required": false,
      "range": "HH:MM, 00:00 to 23:59, one minute steps",
      "note": "The in punch, read off the card, the clock printout or the timesheet. Not a time while blank or malformed."
    },
    {
      "name": "days[].out",
      "type": "string",
      "required": false,
      "range": "HH:MM, 00:00 to 23:59, one minute steps",
      "note": "The out punch. Where it is not later in the clock than the in punch, the day is read as crossing midnight and named as such in its own row."
    },
    {
      "name": "days[].breakMins",
      "type": "number",
      "required": false,
      "range": "0 to 720, whole minutes",
      "note": "The unpaid break that came out of that day. Blank is NOT TYPED, which leaves the day incomplete and the week waiting; a typed 0 is a figure and completes the day. Where the typed break runs past the day's own span, the day's paid figures are dashed and named and the week waits for the correction."
    },
    {
      "name": "days[].notWorked",
      "type": "boolean",
      "required": false,
      "range": "true or false; a tick in the page, a choice of `not worked` or `worked` in the workbook sold beside it, 1 or 0 in a declared state",
      "note": "A day typed as worked by nobody, which completes the day and contributes no minutes. It is read through one function that accepts all three spellings, so the page, the gates and the workbook cannot disagree about what a tick is."
    },
    {
      "name": "thresholdHours",
      "type": "number",
      "required": false,
      "range": "0 to 168; the control steps in quarter hours, and a figure typed off that step is held to two decimals rather than snapped to it - see rounding.typed_figures",
      "note": "The weekly overtime threshold, TYPED BY THE CALLER from the caller's own arrangement. Nothing here supplies, defaults or suggests a threshold, for any place, any trade or any arrangement. While it is blank, no hours figure prints at all."
    },
    {
      "name": "rateRegular",
      "type": "number",
      "required": false,
      "range": "0.00 to 1000.00, two decimals",
      "note": "The rate for hours inside the threshold, money an hour, typed by the caller. Nothing here supplies or suggests a rate."
    },
    {
      "name": "rateOver",
      "type": "number",
      "required": false,
      "range": "0.00 to 1000.00, two decimals",
      "note": "The rate for hours past the threshold, money an hour, typed by the caller. It is a RATE and not a multiplier: this endpoint applies no multiple of any rate to anything, which is how it prices overtime without naming an overtime rule."
    },
    {
      "name": "inHour / inMinute / outHour / outMinute / breakMinutes / notWorkedChoice",
      "type": "number or string",
      "required": false,
      "range": "0 to 23, 0 to 59, 0 to 23, 0 to 59, 0 to 720, `worked` or `not worked`",
      "note": "The one-line form, for the workbook sold beside the page, whose record keeps a line per day with each punch as an hour and a minute. A state carrying these instead of `days` is folded into a week in which that line is the only day worked and the other six are ticked as not worked, so one line of the record and one state of the page are the same arithmetic. This is how machinery/kit/check_kit.py compares the two."
    }
  ],
  "outputs": [
    {
      "name": "daysEntered",
      "unit": "days",
      "formula": "the count of the seven days that are either ticked as not worked, or READ right through: two usable punches, no tick, a typed break, and that break inside the day's own span. 0 to 7. A day whose paid figures the card dashes is not one of them, so the week never foots a total over a day it could not read."
    },
    {
      "name": "daysNotEntered",
      "unit": "days",
      "formula": "7 - daysEntered. While it is above 0 no hours figure prints, and the page prints this count instead."
    },
    {
      "name": "daysWorked",
      "unit": "days",
      "formula": "the count of entered days that are not ticked as not worked."
    },
    {
      "name": "daysNotWorked",
      "unit": "days",
      "formula": "the count of days ticked as not worked. A week of seven such days is a complete week whose every figure is nothing, and every figure prints."
    },
    {
      "name": "daysCrossingMidnight",
      "unit": "days",
      "formula": "the count of punched, unticked days whose out punch is not later in the clock than the in punch."
    },
    {
      "name": "daysBreakPastSpan",
      "unit": "days",
      "formula": "the count of punched, unticked days whose typed break runs past the day's own span. Such a day's paid figures are dashed and named, and it is not entered, so the week waits: daysNotEntered counts it, hoursWaiting is true while it stands, and no weekly figure prints."
    },
    {
      "name": "spanMinutesWeek",
      "unit": "minutes",
      "formula": "the sum of the seven days' spans, counting a ticked day as 0; a day with no usable pair of punches contributes 0."
    },
    {
      "name": "breakMinutesWeek",
      "unit": "minutes",
      "formula": "the sum of the seven days' typed breaks, counting a ticked day as 0 and a blank break as 0."
    },
    {
      "name": "paidMinutesWeek",
      "unit": "minutes",
      "formula": "the sum of the seven days' paid minutes, where a day's paid minutes are its span less its typed break, and are 0 unless the day is punched, unticked, carries a TYPED break, and that break does not run past its span. A blank break is not a break of nothing: the day counts no paid minutes and the week waits for the figure."
    },
    {
      "name": "weekPaidDecimal",
      "unit": "decimal hours",
      "formula": "round2(paidMinutesWeek / 60). Footed from the week's own minute count, never from the sum of the rows' rounded decimals."
    },
    {
      "name": "rowsDecimalSum",
      "unit": "decimal hours",
      "formula": "the sum of the seven days' own rounded decimals, printed beside weekPaidDecimal for comparison and never used to compute anything. The two may differ by a hundredth or two, which is the whole point of printing both."
    },
    {
      "name": "weekRegularHours",
      "unit": "decimal hours",
      "formula": "min(weekPaidDecimal, thresholdHours); null while the week is incomplete or no threshold is typed, because the split cannot be read without both."
    },
    {
      "name": "weekOvertimeHours",
      "unit": "decimal hours",
      "formula": "round2(weekPaidDecimal - weekRegularHours), which is 0 wherever the week stops inside the threshold; null in the same states weekRegularHours is null. The two sides add back to weekPaidDecimal exactly, at two decimals, by construction."
    },
    {
      "name": "weekRegularPay",
      "unit": "money",
      "formula": "round2(weekRegularHours x rateRegular); null while THE PAY WAITS, which is while the hours wait (a day not entered, or no threshold typed) or EITHER rate is blank. It is not null only while its own two terms are null: no money prints on this page while a rate is missing, because a figure priced at one typed rate and one missing one would be a rate the page supplied."
    },
    {
      "name": "weekOvertimePay",
      "unit": "money",
      "formula": "round2(weekOvertimeHours x rateOver); null while the pay waits, on the same rule as weekRegularPay above - the hours waiting, or either rate blank. No multiple of rateRegular is used here or anywhere: the second rate is typed."
    },
    {
      "name": "weekTotalPay",
      "unit": "money",
      "formula": "round2(weekRegularPay + weekOvertimePay); null while the pay waits, on the same rule as the two sides above."
    },
    {
      "name": "weekRegularHoursOrZero",
      "unit": "decimal hours",
      "formula": "weekRegularHours, or 0 in the states where it is null. The page prints nothing in those states; this field exists so that one line of the workbook sold beside the page can be compared with the page at a state the page holds a figure back in, where a null and a zero would otherwise read as a disagreement."
    },
    {
      "name": "weekOvertimeHoursOrZero",
      "unit": "decimal hours",
      "formula": "weekOvertimeHours, or 0 where it is null; the same reason."
    },
    {
      "name": "weekRegularPayOrZero",
      "unit": "money",
      "formula": "weekRegularPay, or 0 in every state where it is null, which is every state where the pay waits; the same reason. This is the field the workbook's own line is compared on, so the rule above is the rule check_kit.py holds the two files to."
    },
    {
      "name": "weekOvertimePayOrZero",
      "unit": "money",
      "formula": "weekOvertimePay, or 0 in every state where it is null, which is every state where the pay waits; the same reason."
    },
    {
      "name": "weekTotalPayOrZero",
      "unit": "money",
      "formula": "weekTotalPay, or 0 in every state where it is null, which is every state where the pay waits; the same reason."
    },
    {
      "name": "hoursWaiting",
      "unit": "true or false",
      "formula": "daysNotEntered > 0 OR thresholdHours is null. While it is true the page prints no hours figure and no pay figure, and says how many of the seven days are not entered yet - a day punched with its break not typed among them, which is why the sentence says ENTERED and not blank."
    },
    {
      "name": "payWaiting",
      "unit": "true or false",
      "formula": "hoursWaiting OR rateRegular is null OR rateOver is null. While it is true and hoursWaiting is false, the hours print and the money does not."
    },
    {
      "name": "daySpanMinutes1",
      "unit": "minutes",
      "formula": "day 1 of the week: that day's clock span: out - in where the out punch is later in the clock, and 1440 - in + out where it is not. 0 where the day has no usable pair of punches. In the one-line form each punch is rounded to a whole minute before the subtraction."
    },
    {
      "name": "daySpanMinutes2",
      "unit": "minutes",
      "formula": "day 2 of the week: that day's clock span: out - in where the out punch is later in the clock, and 1440 - in + out where it is not. 0 where the day has no usable pair of punches. In the one-line form each punch is rounded to a whole minute before the subtraction."
    },
    {
      "name": "daySpanMinutes3",
      "unit": "minutes",
      "formula": "day 3 of the week: that day's clock span: out - in where the out punch is later in the clock, and 1440 - in + out where it is not. 0 where the day has no usable pair of punches. In the one-line form each punch is rounded to a whole minute before the subtraction."
    },
    {
      "name": "daySpanMinutes4",
      "unit": "minutes",
      "formula": "day 4 of the week: that day's clock span: out - in where the out punch is later in the clock, and 1440 - in + out where it is not. 0 where the day has no usable pair of punches. In the one-line form each punch is rounded to a whole minute before the subtraction."
    },
    {
      "name": "daySpanMinutes5",
      "unit": "minutes",
      "formula": "day 5 of the week: that day's clock span: out - in where the out punch is later in the clock, and 1440 - in + out where it is not. 0 where the day has no usable pair of punches. In the one-line form each punch is rounded to a whole minute before the subtraction."
    },
    {
      "name": "daySpanMinutes6",
      "unit": "minutes",
      "formula": "day 6 of the week: that day's clock span: out - in where the out punch is later in the clock, and 1440 - in + out where it is not. 0 where the day has no usable pair of punches. In the one-line form each punch is rounded to a whole minute before the subtraction."
    },
    {
      "name": "daySpanMinutes7",
      "unit": "minutes",
      "formula": "day 7 of the week: that day's clock span: out - in where the out punch is later in the clock, and 1440 - in + out where it is not. 0 where the day has no usable pair of punches. In the one-line form each punch is rounded to a whole minute before the subtraction."
    },
    {
      "name": "dayBreakMinutes1",
      "unit": "minutes",
      "formula": "day 1 of the week: that day's typed break, clamped to 0 to 720 and rounded to a whole minute; 0 where it is blank."
    },
    {
      "name": "dayBreakMinutes2",
      "unit": "minutes",
      "formula": "day 2 of the week: that day's typed break, clamped to 0 to 720 and rounded to a whole minute; 0 where it is blank."
    },
    {
      "name": "dayBreakMinutes3",
      "unit": "minutes",
      "formula": "day 3 of the week: that day's typed break, clamped to 0 to 720 and rounded to a whole minute; 0 where it is blank."
    },
    {
      "name": "dayBreakMinutes4",
      "unit": "minutes",
      "formula": "day 4 of the week: that day's typed break, clamped to 0 to 720 and rounded to a whole minute; 0 where it is blank."
    },
    {
      "name": "dayBreakMinutes5",
      "unit": "minutes",
      "formula": "day 5 of the week: that day's typed break, clamped to 0 to 720 and rounded to a whole minute; 0 where it is blank."
    },
    {
      "name": "dayBreakMinutes6",
      "unit": "minutes",
      "formula": "day 6 of the week: that day's typed break, clamped to 0 to 720 and rounded to a whole minute; 0 where it is blank."
    },
    {
      "name": "dayBreakMinutes7",
      "unit": "minutes",
      "formula": "day 7 of the week: that day's typed break, clamped to 0 to 720 and rounded to a whole minute; 0 where it is blank."
    },
    {
      "name": "dayPaidMinutes1",
      "unit": "minutes",
      "formula": "day 1 of the week: that day's span less its typed break; 0 where the day is blank, ticked as not worked, carries no typed break yet, or has a typed break running past its own span."
    },
    {
      "name": "dayPaidMinutes2",
      "unit": "minutes",
      "formula": "day 2 of the week: that day's span less its typed break; 0 where the day is blank, ticked as not worked, carries no typed break yet, or has a typed break running past its own span."
    },
    {
      "name": "dayPaidMinutes3",
      "unit": "minutes",
      "formula": "day 3 of the week: that day's span less its typed break; 0 where the day is blank, ticked as not worked, carries no typed break yet, or has a typed break running past its own span."
    },
    {
      "name": "dayPaidMinutes4",
      "unit": "minutes",
      "formula": "day 4 of the week: that day's span less its typed break; 0 where the day is blank, ticked as not worked, carries no typed break yet, or has a typed break running past its own span."
    },
    {
      "name": "dayPaidMinutes5",
      "unit": "minutes",
      "formula": "day 5 of the week: that day's span less its typed break; 0 where the day is blank, ticked as not worked, carries no typed break yet, or has a typed break running past its own span."
    },
    {
      "name": "dayPaidMinutes6",
      "unit": "minutes",
      "formula": "day 6 of the week: that day's span less its typed break; 0 where the day is blank, ticked as not worked, carries no typed break yet, or has a typed break running past its own span."
    },
    {
      "name": "dayPaidMinutes7",
      "unit": "minutes",
      "formula": "day 7 of the week: that day's span less its typed break; 0 where the day is blank, ticked as not worked, carries no typed break yet, or has a typed break running past its own span."
    },
    {
      "name": "dayPaidDecimal1",
      "unit": "decimal hours",
      "formula": "day 1 of the week: round2(that day's paid minutes / 60)."
    },
    {
      "name": "dayPaidDecimal2",
      "unit": "decimal hours",
      "formula": "day 2 of the week: round2(that day's paid minutes / 60)."
    },
    {
      "name": "dayPaidDecimal3",
      "unit": "decimal hours",
      "formula": "day 3 of the week: round2(that day's paid minutes / 60)."
    },
    {
      "name": "dayPaidDecimal4",
      "unit": "decimal hours",
      "formula": "day 4 of the week: round2(that day's paid minutes / 60)."
    },
    {
      "name": "dayPaidDecimal5",
      "unit": "decimal hours",
      "formula": "day 5 of the week: round2(that day's paid minutes / 60)."
    },
    {
      "name": "dayPaidDecimal6",
      "unit": "decimal hours",
      "formula": "day 6 of the week: round2(that day's paid minutes / 60)."
    },
    {
      "name": "dayPaidDecimal7",
      "unit": "decimal hours",
      "formula": "day 7 of the week: round2(that day's paid minutes / 60)."
    }
  ],
  "formula": [
    "inMinutes = HH x 60 + MM, or NOT A TIME",
    "punched = inMinutes is a time AND outMinutes is a time",
    "crossing = punched AND outMinutes <= inMinutes",
    "span = crossing ? 1440 - inMinutes + outMinutes : outMinutes - inMinutes, and 0 where not punched",
    "breakTyped = the typed break clamped to [0, 720], or NOT TYPED while blank; break = breakTyped or 0",
    "breakPast = punched AND break > span",
    "readable = punched AND NOT notWorked AND breakTyped is not NOT TYPED AND NOT breakPast - a day READ right through",
    "paid = readable ? span - break : 0",
    "dayDecimal = round2(paid / 60)",
    "entered = notWorked OR readable: a day whose paid figures the card dashes is never a day the week counts",
    "daysEntered = the count of entered days; daysNotEntered = 7 - daysEntered",
    "spanMinutesWeek = sum over days of (notWorked ? 0 : span)",
    "breakMinutesWeek = sum over days of (notWorked ? 0 : break)",
    "paidMinutesWeek = sum over days of paid",
    "weekPaidDecimal = round2(paidMinutesWeek / 60)",
    "rowsDecimalSum = the running sum over days of dayDecimal, with round2() applied after each day is added, so the figure is held to two decimals throughout and never carries the residue of seven additions",
    "hoursWaiting = daysNotEntered > 0 OR thresholdHours is NOT TYPED",
    "weekRegularHours = weekPaidDecimal < thresholdHours ? weekPaidDecimal : thresholdHours",
    "weekOvertimeHours = round2(weekPaidDecimal - weekRegularHours)",
    "payWaiting = hoursWaiting OR rateRegular is NOT TYPED OR rateOver is NOT TYPED",
    "weekRegularPay = round2(weekRegularHours x rateRegular)",
    "weekOvertimePay = round2(weekOvertimeHours x rateOver)",
    "weekTotalPay = round2(weekRegularPay + weekOvertimePay)"
  ],
  "identities": [
    "weekRegularHours + weekOvertimeHours equals weekPaidDecimal exactly at two decimals, wherever neither is null: the overtime side is defined as the week less the regular side rather than as the week less the threshold, so the two sides cannot fail to add back to the week even where the threshold falls between two hundredths.",
    "weekRegularHours is at most thresholdHours, and weekOvertimeHours is 0 wherever weekPaidDecimal is at most thresholdHours.",
    "weekRegularPay + weekOvertimePay equals weekTotalPay to half a cent, wherever none is null.",
    "paidMinutesWeek equals spanMinutesWeek - breakMinutesWeek summed over the days that are readable; it is NOT that subtraction over the whole week, because a day the card cannot read right through - its typed break past its own span, or no break typed on it yet - contributes its span and its break to those two totals and contributes no paid minutes at all. That is the one place the three weekly minute counts do not line up by subtraction, and it is a reading of such a day rather than a loss of minutes.",
    "rowsDecimalSum may differ from weekPaidDecimal, and the difference is at most a hundredth of an hour per day. Both are printed; neither is computed from the other.",
    "every day's paid minutes are at most its span, and no printed figure on the page is negative: a day crossing midnight is read forward rather than subtracted backwards, and a day whose break runs past its span is dashed and named rather than counted below nothing."
  ],
  "example": {
    "note": "A week ending Sunday 18 October 2026: five day shifts of differing lengths, one night shift punched in at 22:00 and out at 06:00, a short Saturday, and the Sunday ticked as not worked. The threshold typed is 40 hours and the two rates typed are 22.00 and 33.00 an hour. The week foots to 2,740 paid minutes, which is 45.67 payroll hours and 45:40 in hours and minutes.",
    "inputs": {
      "weekEnding": "2026-10-18",
      "cardName": "Line 3 crew",
      "cardRef": "WK-42",
      "thresholdHours": 40,
      "rateRegular": 22,
      "rateOver": 33,
      "days": [
        {
          "in": "08:00",
          "out": "18:00",
          "breakMins": 30,
          "notWorked": false
        },
        {
          "in": "08:00",
          "out": "16:30",
          "breakMins": 30,
          "notWorked": false
        },
        {
          "in": "22:00",
          "out": "06:00",
          "breakMins": 45,
          "notWorked": false
        },
        {
          "in": "08:00",
          "out": "17:15",
          "breakMins": 30,
          "notWorked": false
        },
        {
          "in": "08:00",
          "out": "16:30",
          "breakMins": 30,
          "notWorked": false
        },
        {
          "in": "09:00",
          "out": "13:10",
          "breakMins": 0,
          "notWorked": false
        },
        {
          "in": "",
          "out": "",
          "breakMins": null,
          "notWorked": true
        }
      ]
    },
    "outputs": {
      "daysEntered": 7,
      "daysNotEntered": 0,
      "daysWorked": 6,
      "daysNotWorked": 1,
      "daysCrossingMidnight": 1,
      "daysBreakPastSpan": 0,
      "spanMinutesWeek": 2905,
      "breakMinutesWeek": 165,
      "paidMinutesWeek": 2740,
      "weekPaidDecimal": 45.67,
      "rowsDecimalSum": 45.67,
      "weekRegularHours": 40,
      "weekOvertimeHours": 5.67,
      "weekRegularPay": 880,
      "weekOvertimePay": 187.11,
      "weekTotalPay": 1067.11,
      "weekRegularHoursOrZero": 40,
      "weekOvertimeHoursOrZero": 5.67,
      "weekRegularPayOrZero": 880,
      "weekOvertimePayOrZero": 187.11,
      "weekTotalPayOrZero": 1067.11,
      "hoursWaiting": false,
      "payWaiting": false,
      "daySpanMinutes1": 600,
      "dayBreakMinutes1": 30,
      "dayPaidMinutes1": 570,
      "dayPaidDecimal1": 9.5,
      "daySpanMinutes2": 510,
      "dayBreakMinutes2": 30,
      "dayPaidMinutes2": 480,
      "dayPaidDecimal2": 8,
      "daySpanMinutes3": 480,
      "dayBreakMinutes3": 45,
      "dayPaidMinutes3": 435,
      "dayPaidDecimal3": 7.25,
      "daySpanMinutes4": 555,
      "dayBreakMinutes4": 30,
      "dayPaidMinutes4": 525,
      "dayPaidDecimal4": 8.75,
      "daySpanMinutes5": 510,
      "dayBreakMinutes5": 30,
      "dayPaidMinutes5": 480,
      "dayPaidDecimal5": 8,
      "daySpanMinutes6": 250,
      "dayBreakMinutes6": 0,
      "dayPaidMinutes6": 250,
      "dayPaidDecimal6": 4.17,
      "daySpanMinutes7": 0,
      "dayBreakMinutes7": 0,
      "dayPaidMinutes7": 0,
      "dayPaidDecimal7": 0
    }
  },
  "not_covered": [
    "What any overtime threshold is, or should be, anywhere, for anybody. The threshold is typed by the caller every time and this endpoint holds none.",
    "What anybody should be paid. Both rates are typed by the caller, and no multiple of either is applied to anything.",
    "Wage law of any kind: no statute, no agency, no entitlement, no daily or weekly rule, no break rule, no rounding practice, no state or city variation. None of those figures or rules is in this file, and nothing here tells a caller which of them applies.",
    "Whether anybody is exempt or non-exempt, an employee or a contractor, salaried or hourly. This endpoint reads punches and does not classify anybody.",
    "Tax, deductions, net pay, a paycheck or a payslip. It stops at hours and money an hour.",
    "Whether a card satisfies an employer, a payroll office, an audit or any requirement. It is arithmetic on typed punches and it certifies nothing.",
    "More than one week, more than one card, and any history at all. One week of seven days, and nothing is stored."
  ],
  "no_advice": "Arithmetic on figures the caller types. It recommends no threshold, no rate, no rounding practice and no way of recording a shift, it names no rule and no authority, and it asks for nothing that identifies anybody."
}
