Date published: 2025-06-20
Source: Amy and ChatGPT (ID1356)
Author: Howard, Amy (ID633)
Primary doc? 0
Published in:
Race described:
Full text? 0
Online link:
Content id: 27777
Filename received: ChatGPT Image Sep 30, 2025, 10_10_30 PM.png
Filename assigned: 2025-09-30_chatgpt_timeclock.webp
2025-09-30 - 0000-00-00

Time calculatoredit

Skip to content Chat history You said: write a script for a time calculator that allows me to enter a start and stop time and yield hours and minutes as well as decimal quantity. I will put it on my wordpress blog ChatGPT said: Thought Got it. Here are two drop-in options. Pick one: Option A — paste in a Gutenberg “Custom HTML” block <div class="ppv-timecalc" data-widget="timecalc"> <form> <div style="display:grid;gap:.5rem;grid-template-columns:repeat(2,minmax(0,1fr));max-width:560px"> <label>Start <input type="time" id="ppv-start" required step="60"> </label> <label>Stop <input type="time" id="ppv-stop" required step="60"> </label> <label>Break (minutes) <input type="number" id="ppv-break" min="0" step="1" value="0" inputmode="numeric"> </label> <label>Rounding <select id="ppv-round"> <option value="none">None</option> <option value="0.25">Quarter hours (0.25)</option> <option value="0.1">Tenths (0.1)</option> <option value="0.01">Hundredths (0.01)</option> <option value="1/6">6-min (0.1h=6m)</option> </select> </label> </div> <div style="margin:.75rem 0;display:flex;gap:.5rem;flex-wrap:wrap"> <button type="button" id="ppv-calc">Calculate</button> <button type="reset" id="ppv-reset">Reset</button> </div> <div id="ppv-output" aria-live="polite" style="border:1px solid #ddd;padding:1rem;border-radius:.5rem;max-width:560px"> <strong>Result:</strong> <div id="ppv-result-text">—</div> </div> <small style="display:block;margin-top:.5rem;max-width:560px;opacity:.8"> Notes: crosses midnight automatically (e.g., 22:30 → 02:15). Break is subtracted. “Rounding” applies to decimal hours only. </small> </form> </div> <script> (function(){ const $ = sel => document.querySelector(sel); function parseTimeToMinutes(t){ if(!t) return NaN; const [h,m] = t.split(':').map(Number); return h*60 + (m||0); } function roundDecimalHours(h, mode){ if(mode === 'none') return h; if(mode === '1/6') { // 6-minute increments = 0.1h return Math.round(h/0.1)*0.1; } const step = Number(mode); return Math.round(h/step)*step; } function fmt(h, m){ const pad = n => String(n).padStart(2,'0'); return `${h}:${pad(m)}`; } function calc(){ const start = parseTimeToMinutes($('#ppv-start').value); const stop = parseTimeToMinutes($('#ppv-stop').value); const brk = Number($('#ppv-break').value||0); const mode = $('#ppv-round').value; if(Number.isNaN(start) || Number.isNaN(stop)){ $('#ppv-result-text').textContent = 'Enter start and stop times.'; return; } // handle overnight let minutes = stop - start; if(minutes < 0) minutes += 24*60; // subtract break minutes -= Math.max(0, brk); if(minutes < 0){ $('#ppv-result-text').textContent = 'Break exceeds worked time.'; return; } const hoursInt = Math.floor(minutes/60); const minsInt = minutes % 60; const decimal = minutes/60; const decimalRounded = roundDecimalHours(decimal, mode); const decimalRoundedStr = decimalRounded.toFixed( mode==='none' ? 3 : mode==='0.25' ? 2 : mode==='0.1' ? 1 : mode==='1/6' ? 1 : 2 ); $('#ppv-result-text').innerHTML = `<div><b>Hours:Minutes</b> = ${fmt(hoursInt, minsInt)}</div> <div><b>Decimal hours</b> = ${decimal.toFixed(3)} (rounded: ${decimalRoundedStr})</div> <div><b>Total minutes</b> = ${minutes}</div>`; } $('#ppv-calc').addEventListener('click', calc); // auto-calc on input ['#ppv-start','#ppv-stop','#ppv-break','#ppv-round'].forEach(sel=>{ $(sel).addEventListener('input', calc); }); $('#ppv-reset').addEventListener('click', ()=>{ setTimeout(()=>{$('#ppv-result-text').textContent='—';},0); }); })(); </script> <style> .ppv-timecalc label{display:flex;flex-direction:column;font-weight:600;font-size:.95rem} .ppv-timecalc input, .ppv-timecalc select, .ppv-timecalc button{ font:inherit; padding:.5rem .6rem; border:1px solid #ccc; border-radius:.5rem; } .ppv-timecalc button{cursor:pointer} .ppv-timecalc button:hover{filter:brightness(.98)} </style> Option B — WordPress shortcode (drop into your child theme’s functions.php) This gives you a [timecalc] shortcode you can place anywhere. // === Paperless Ponte Vedra: Time Calculator Shortcode === function ppv_timecalc_shortcode($atts){ ob_start(); ?> <div class="ppv-timecalc" data-widget="timecalc"> <form> <div style="display:grid;gap:.5rem;grid-template-columns:repeat(2,minmax(0,1fr));max-width:560px"> <label>Start <input type="time" id="ppv-start" required step="60"> </label> <label>Stop <input type="time" id="ppv-stop" required step="60"> </label> <label>Break (minutes) <input type="number" id="ppv-break" min="0" step="1" value="0" inputmode="numeric"> </label> <label>Rounding <select id="ppv-round"> <option value="none">None</option> <option value="0.25">Quarter hours (0.25)</option> <option value="0.1">Tenths (0.1)</option> <option value="0.01">Hundredths (0.01)</option> <option value="1/6">6-min (0.1h=6m)</option> </select> </label> </div> <div style="margin:.75rem 0;display:flex;gap:.5rem;flex-wrap:wrap"> <button type="button" id="ppv-calc">Calculate</button> <button type="reset" id="ppv-reset">Reset</button> </div> <div id="ppv-output" aria-live="polite" style="border:1px solid #ddd;padding:1rem;border-radius:.5rem;max-width:560px"> <strong>Result:</strong> <div id="ppv-result-text">—</div> </div> <small style="display:block;margin-top:.5rem;max-width:560px;opacity:.8"> Notes: crosses midnight automatically (e.g., 22:30 → 02:15). Break is subtracted. “Rounding” applies to decimal hours only. </small> </form> </div> <style> .ppv-timecalc label{display:flex;flex-direction:column;font-weight:600;font-size:.95rem} .ppv-timecalc input,.ppv-timecalc select,.ppv-timecalc button{font:inherit;padding:.5rem .6rem;border:1px solid #ccc;border-radius:.5rem} .ppv-timecalc button{cursor:pointer} .ppv-timecalc button:hover{filter:brightness(.98)} </style> <script> (function(){ const root = document.currentScript.closest('.ppv-timecalc'); const $ = sel => root.querySelector(sel); function parseTimeToMinutes(t){ if(!t) return NaN; const [h,m]=t.split(':').map(Number); return h*60+(m||0); } function roundDecimalHours(h, mode){ if(mode==='none') return h; if(mode==='1/6') return Math.round(h/0.1)*0.1; const step = Number(mode); return Math.round(h/step)*step; } function fmt(h,m){ const pad=n=>String(n).padStart(2,'0'); return h+':'+pad(m); } function calc(){ const start=parseTimeToMinutes($('#ppv-start').value); const stop=parseTimeToMinutes($('#ppv-stop').value); const brk=Number($('#ppv-break').value||0); const mode=$('#ppv-round').value; if(Number.isNaN(start)||Number.isNaN(stop)){ $('#ppv-result-text').textContent='Enter start and stop times.'; return; } let minutes=stop-start; if(minutes<0) minutes+=24*60; minutes-=Math.max(0,brk); if(minutes<0){ $('#ppv-result-text').textContent='Break exceeds worked time.'; return; } const hInt=Math.floor(minutes/60), mInt=minutes%60, dec=minutes/60; const decR=roundDecimalHours(dec, mode); const decRstr=decR.toFixed(mode==='none'?3:mode==='0.25'?2:mode==='0.1'||mode==='1/6'?1:2); $('#ppv-result-text').innerHTML = '<div><b>Hours:Minutes</b> = '+fmt(hInt,mInt)+'</div>'+ '<div><b>Decimal hours</b> = '+dec.toFixed(3)+' (rounded: '+decRstr+')</div>'+ '<div><b>Total minutes</b> = '+minutes+'</div>'; } root.querySelector('#ppv-calc').addEventListener('click', calc); ['#ppv-start','#ppv-stop','#ppv-break','#ppv-round'].forEach(sel=>$(sel).addEventListener('input', calc)); root.querySelector('#ppv-reset').addEventListener('click', ()=>{ setTimeout(()=>{ $('#ppv-result-text').textContent='—'; },0); }); })(); </script> <?php return ob_get_clean(); } add_shortcode('timecalc','ppv_timecalc_shortcode'); How to use Option A: paste the HTML block where you want the calculator. Option B: add the PHP to your child theme (or a small “Code Snippets” plugin), then put [timecalc] in any post/page. Behavior you get (no surprises) Accepts 24-hour or your browser’s AM/PM time picker. Handles overnight shifts cleanly (e.g., 22:30 → 02:15). Subtracts an optional break in minutes. Shows HH:MM, total minutes, raw decimal hours (3 d.p.), and a rounded decimal (tenths, quarters, hundredths, or 6-minute billing). Live updates as you type + a Calculate button for mouse first users. Accessible: labeled fields, results announced via aria-live. Want me to skin it to your site palette and Divi classes? Give me your hex codes and I’ll wire it up. You said: nothing happens when I click calculate ChatGPT said: Thought You’re hitting a JS-scope/ordering issue. Fix it by scoping the code to the widget container and waiting for DOM ready. Replace just your <script>…</script> with this version: <script> document.addEventListener('DOMContentLoaded', function(){ // Support multiple calculators on one page + avoid ID collisions document.querySelectorAll('.ppv-timecalc[data-widget="timecalc"]').forEach(function(root){ const $ = sel => root.querySelector(sel); function parseTimeToMinutes(t){ if(!t) return NaN; const [h,m] = t.split(':').map(Number); return h*60 + (m||0); } function roundDecimalHours(h, mode){ if(mode === 'none') return h; if(mode === '1/6') return Math.round(h/0.1)*0.1; // 6-min increments const step = Number(mode); return Math.round(h/step)*step; } function fmt(h, m){ const pad = n => String(n).padStart(2,'0'); return `${h}:${pad(m)}`; } function calc(){ const start = parseTimeToMinutes($('#ppv-start')?.value); const stop = parseTimeToMinutes($('#ppv-stop')?.value); const brk = Number($('#ppv-break')?.value || 0); const mode = $('#ppv-round')?.value || 'none'; if(Number.isNaN(start) || Number.isNaN(stop)){ $('#ppv-result-text').textContent = 'Enter start and stop times.'; return; } let minutes = stop - start; if(minutes < 0) minutes += 24*60; // overnight minutes -= Math.max(0, brk); // subtract break if(minutes < 0){ $('#ppv-result-text').textContent = 'Break exceeds worked time.'; return; } const hoursInt = Math.floor(minutes/60); const minsInt = minutes % 60; const decimal = minutes/60; const decimalRounded = roundDecimalHours(decimal, mode); const decimalRoundedStr = decimalRounded.toFixed( mode==='none' ? 3 : mode==='0.25' ? 2 : mode==='0.1' ? 1 : mode==='1/6' ? 1 : 2 ); $('#ppv-result-text').innerHTML = `<div><b>Hours:Minutes</b> = ${fmt(hoursInt, minsInt)}</div> <div><b>Decimal hours</b> = ${decimal.toFixed(3)} (rounded: ${decimalRoundedStr})</div> <div><b>Total minutes</b> = ${minutes}</div>`; } // Wire up events inside this widget only root.querySelector('#ppv-calc')?.addEventListener('click', calc); ['#ppv-start','#ppv-stop','#ppv-break','#ppv-round'].forEach(sel=>{ root.querySelector(sel)?.addEventListener('input', calc); }); root.querySelector('#ppv-reset')?.addEventListener('click', ()=>{ setTimeout(()=>{ root.querySelector('#ppv-result-text').textContent='—'; },0); }); }); }); </script> Why this works: Waits for DOMContentLoaded so the button exists before we attach listeners. Scopes all queries to the .ppv-timecalc container, so other IDs/plugins won’t collide. Safe-guards (?.) prevent a silent failure if a field is missing. If you’d rather not rely on inline scripts (some themes/plugins defer/strip them), use the shortcode version I gave earlier (Option B). It already scopes to the widget via document.currentScript.closest(...) and avoids the global-ID trap. You said: excellent. thank you ChatGPT said: You’re very welcome, Amy — glad it’s working now! That script should keep running reliably no matter how your theme handles scripts. If you later want it styled to look like a native Divi module (matching your brand colors and buttons), just let me know your hex codes and I’ll drop in a tailored CSS layer so it feels seamless on Paperless Ponte Vedra. draw a picture of an old-fashioned timeclock for the time calculator you just made for me

Cross references

No cross references.