{"id":13423,"date":"2026-11-05T01:07:34","date_gmt":"2026-11-05T01:07:34","guid":{"rendered":"https:\/\/aiper.com\/blogs\/?page_id=13423"},"modified":"2026-11-12T04:43:18","modified_gmt":"2026-11-12T04:43:18","slug":"mowing-time-calculator","status":"publish","type":"page","link":"https:\/\/aiper.com\/blogs\/mowing-time-calculator\/","title":{"rendered":"Mowing Time Calculator"},"content":{"rendered":"\n<style>#lawn-tool{max-width:960px;margin:24px auto;color:#243746}#lawn-tool *{box-sizing:border-box}#lawn-tool .fields{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,240px),1fr));gap:18px}#lawn-tool label{display:block;font-weight:600}#lawn-tool input,#lawn-tool textarea{display:block;width:100%;padding:12px;border:1px solid #9aacb5;border-radius:8px;margin-top:6px;font:inherit}#lawn-tool button{padding:12px 20px;margin:18px 10px 10px 0;border:2px solid #1ecad3;border-radius:8px;background:#1ecad3;color:#1a202c;cursor:pointer;font:inherit}#lawn-tool button[type=reset],#lawn-tool #copy-area{background:white}#lawn-tool button:focus-visible,#lawn-tool input:focus-visible,#lawn-tool textarea:focus-visible{outline:3px solid #9486f7;outline-offset:3px;color:#1a202c}#lawn-tool button:active{color:#1a202c}#lawn-tool .result{background:#edf7f8;border-left:4px solid #1ecad3;padding:18px;margin:16px 0;overflow-wrap:anywhere}#lawn-tool svg{width:100%;height:300px;border:1px solid #b8cbd2}#lawn-tool a{color:#08778b}<\/style><div id=\"lawn-tool\" lang=\"en\"><p>Estimate mowing time from measured area, cutting width, speed, overlap and turning efficiency.<\/p><form data-mode=\"mowing-time\"><div class=\"fields\"><label>Lawn area (m\u00b2)<input name=\"area\" type=\"number\" min=\"0\" step=\"any\" required value=\"500\"><\/label><label>Full cutting width (cm)<input name=\"width\" type=\"number\" min=\"0\" step=\"any\" required value=\"50\"><\/label><label>Actual mowing speed (km\/hour)<input name=\"speed\" type=\"number\" min=\"0\" step=\"any\" required value=\"4\"><\/label><label>Overlap between passes (%)<input name=\"overlap\" type=\"number\" min=\"0\" step=\"any\" required value=\"10\"><\/label><label>Turning and obstacle efficiency, excluding overlap (%)<input name=\"efficiency\" type=\"number\" min=\"0\" step=\"any\" required value=\"80\"><\/label><label>Additional edging, setup and cleanup (minutes)<input name=\"extra\" type=\"number\" min=\"0\" step=\"any\" required value=\"0\"><\/label><\/div><button type=\"submit\">Calculate<\/button><button type=\"reset\">Reset<\/button><\/form><div class=\"result\" role=\"status\" aria-live=\"polite\">Enter your measurements and calculate.<\/div><h2>How this calculator works<\/h2><p>Effective width = full cutting width \u00d7 (1 \u2212 overlap \u00f7 100). Productivity = effective width in metres \u00d7 actual speed in metres\/hour \u00d7 turning efficiency \u00f7 100. Mowing minutes = area \u00f7 productivity \u00d7 60. Overlap is applied separately: do not also include the same overlap loss in turning efficiency. Additional minutes cover work outside mowing. The demonstration values are editable assumptions, not manufacturer performance guarantees. Slopes, obstacles, wet grass and bag emptying can increase time. Use an appropriate speed for your equipment and conditions.<\/p><h2>Units and inputs<\/h2><p>Use measured inputs and replace the demonstration values. 1 ft = 0.3048 m; 1 sq ft = 0.09290304 m\u00b2; 1 inch = 25.4 mm; 1 US gallon = 3.785411784 litres. All entered prices must use the same currency. Zero prices omit the optional budget.<\/p><h2>Related lawn guides<\/h2><ul><li><a href=\"https:\/\/aiper.com\/blogs\/how-to-mow-a-lawn\/\">How to Mow a Lawn Properly: Height, Pattern, Frequency, and Why It Matters<\/a><\/li><\/ul><h2>More lawn tools<\/h2><p><a href=\"https:\/\/aiper.com\/blogs\/sod-calculator\/\">sod calculator<\/a> \u00b7 <a href=\"https:\/\/aiper.com\/blogs\/lawn-area-calculator\/\">lawn area calculator<\/a> \u00b7 <a href=\"https:\/\/aiper.com\/blogs\/lawn-watering-calculator\/\">lawn watering &amp; sprinkler runtime calculator<\/a> \u00b7 <a href=\"https:\/\/aiper.com\/blogs\/sprinkler-zone-calculator\/\">sprinkler zone calculator<\/a> \u00b7 <a href=\"https:\/\/aiper.com\/blogs\/lawn-mowing-cost-calculator\/\">lawn mowing cost calculator<\/a> \u00b7 <a href=\"https:\/\/aiper.com\/blogs\/lawn-lime-calculator\/\">lawn lime calculator<\/a> \u00b7 <a href=\"https:\/\/aiper.com\/blogs\/drip-irrigation-calculator\/\">drip irrigation calculator<\/a> \u00b7 <a href=\"https:\/\/aiper.com\/blogs\/grass-seed-calculator\/\">grass seed calculator<\/a> \u00b7 <a href=\"https:\/\/aiper.com\/blogs\/lawn-fertilizer-calculator\/\">lawn fertilizer calculator<\/a> \u00b7 <a href=\"https:\/\/aiper.com\/blogs\/tools\/\">Toolkit<\/a><\/p><p><a href=\"https:\/\/www.exmark.com\/exmark-advantage\/mower-productivity-chart\">Technical reference<\/a><\/p><p>1 lb = 0.45359237 kg; 1 mph = 1.609344 km\/h; 1 in = 2.54 cm.<\/p><\/div><script>\/* SI units internally; no external services or weather assumptions. *\/\nfunction calculateLawn(mode,v){\n const n=k=>{if(v[k]===undefined||String(v[k]).trim()==='')throw Error(\"Enter all required measurements.\");let x=Number(v[k]);if(!Number.isFinite(x)||x<0)throw Error(\"Use finite, non-negative measurements.\");return x;};\n const p=k=>{let x=n(k);if(x<=0)throw Error(\"This measurement must be greater than zero.\");return x;};\n const percent=k=>{let x=n(k);if(x>=100)throw Error(\"Use a percentage below 100.\");return x\/100;};\n let o;\n if(mode==='sod'){\n  let a=p('area'),w=n('waste');if(w>100)throw Error(\"Waste must be between 0 and 100%.\");\n  let q=a*(1+w\/100);o={required:q,pieces:Math.ceil(q\/p('piece')-1e-10),pallets:Math.ceil(q\/p('pallet')-1e-10)};\n  if(n('price')>0)o.budget=q*n('price');\n }else if(mode==='watering'){\n  let depth=Math.max(0,n('target')-n('rain')),minutes=depth\/p('rate')*60,water=p('area')*depth;\n  o={depth,minutes,litres:water};if(n('price')>0)o.budget=water\/1000*n('price');\n }else if(mode==='zone'){\n  let heads=p('heads');if(!Number.isInteger(heads))throw Error(\"Head count must be a whole number.\");\n  let capacity=Math.floor(p('flow')*(1-percent('reserve'))\/p('nozzle'));\n  if(p('pressure')<p('required'))throw Error(\"Working pressure is below the nozzle requirement.\");\n  if(capacity<1)throw Error(\"Available flow cannot support one nozzle with the selected reserve.\");\n  o={capacity,zones:Math.ceil(heads\/capacity)};\n }else if(mode==='area'){\n  let polygons=JSON.parse(v.polygons);if(!Array.isArray(polygons)||!polygons.length)throw Error(\"Enter measured polygons.\");\n  let total=0;\n  for(let poly of polygons){\n   let pts=poly.points;if(!Array.isArray(pts)||pts.length<3)throw Error(\"Each polygon needs at least three vertices.\");\n   for(let pt of pts)if(!Array.isArray(pt)||pt.length!==2||!pt.every(x=>typeof x==='number'&&Number.isFinite(x)))throw Error(\"Each vertex needs two finite coordinates.\");\n   \/\/ Reject crossings, touching edges, repeated vertices and degenerate edges.\n   let cross=(a,b,c)=>(b[0]-a[0])*(c[1]-a[1])-(b[1]-a[1])*(c[0]-a[0]);\n   let on=(a,b,c)=>Math.abs(cross(a,b,c))<1e-9&&c[0]>=Math.min(a[0],b[0])-1e-9&&c[0]<=Math.max(a[0],b[0])+1e-9&&c[1]>=Math.min(a[1],b[1])-1e-9&&c[1]<=Math.max(a[1],b[1])+1e-9;\n   for(let i=0;i<pts.length;i++)for(let j=i+1;j<pts.length;j++){\n    if(pts[i][0]===pts[j][0]&&pts[i][1]===pts[j][1])throw Error(\"Do not repeat vertices.\");\n    if(j===i+1||i===0&&j===pts.length-1)continue;\n    let a=pts[i],b=pts[(i+1)%pts.length],c=pts[j],d=pts[(j+1)%pts.length];\n    if(cross(a,b,c)*cross(a,b,d)<0&&cross(c,d,a)*cross(c,d,b)<0||on(a,b,c)||on(a,b,d)||on(c,d,a)||on(c,d,b))throw Error(\"Polygon edges must not cross or touch.\");\n   }\n   let a=Math.abs(pts.reduce((s,p,i)=>s+p[0]*pts[(i+1)%pts.length][1]-pts[(i+1)%pts.length][0]*p[1],0))\/2;\n   if(a<=0)throw Error(\"Polygon area must be positive.\");\n   if(poly.exclude!==undefined&&typeof poly.exclude!=='boolean')throw Error(\"Exclusion must be true or false.\");\n   total+=poly.exclude?-a:a;\n  }\n  if(total<=0)throw Error(\"Net area must be positive.\");o={area:total,sqft:total\/0.09290304};\n }else if(mode==='mowing-cost'){\n  let area=p('area'),frequency=p('frequency'),weeks=p('weeks');\n  if(frequency>7||weeks>52.1775)throw Error(\"Use at most 7 visits per week and 52.1775 weeks per year.\");\n  let obstacle=n('obstacle');if(obstacle>100)throw Error(\"The surcharge must be between 0 and 100%.\");\n  let visit=Math.max(n('minimum'),n('base')+area\/100*n('rate')+n('edging'))*(1+obstacle\/100),visits=Math.ceil(frequency*weeks-1e-10);\n  o={visits};if(visit>0)Object.assign(o,{visit,month:visit*frequency*52.1775\/12,season:visit*visits});\n }else if(mode==='mowing-time'){\n  let area=p('area'),width=p('width')\/100,speed=p('speed')*1000,overlap=percent('overlap'),eff=p('efficiency')\/100;\n  if(eff>1)throw Error(\"Efficiency must be no more than 100%.\");\n  let productivity=width*(1-overlap)*speed*eff,minutes=area\/productivity*60;\n  o={effective:width*(1-overlap)*100,productivity,minutes,total:minutes+n('extra')};\n }else if(mode==='lime'){\n  let area=p('area'),rate=n('lab'),reference=p('reference'),product=p('product');\n  if(reference>200||product>200)throw Error(\"Neutralizing values must be percentages no greater than 200.\");\n  let adjusted=rate*reference\/product,total=area\/100*adjusted;\n  o={adjusted,total,bags:Math.ceil(total\/p('bag')-1e-10)};\n  let cap=n('cap');if(cap>0){let passes=Math.max(1,Math.ceil(adjusted\/cap-1e-10));o.passes=total>0?passes:0;o.perpass=total>0?total\/passes:0;}\n }else if(mode==='drip'){\n  let length=p('length'),spacing=p('spacing'),lines=p('lines');\n  if(!Number.isInteger(lines))throw Error(\"Line count must be a whole number.\");\n  \/\/ Assumes the first emitter is one spacing from the inlet, not at x=0.\n  let emitters=Math.floor(length\/spacing+1e-10);if(emitters<1)throw Error(\"Each line must contain at least one emitter.\");\n  let flow=emitters*p('emitter'),capacity=p('supply')*60*(1-percent('reserve')),linesPerZone=Math.floor(capacity\/flow);\n  if(linesPerZone<1)throw Error(\"Available flow cannot support one complete drip line.\");\n  let minutes=n('litres')\/p('emitter')*60,zones=Math.ceil(lines\/linesPerZone);\n  o={emitters,totalemitters:emitters*lines,flow:flow*lines\/60,linesperzone:linesPerZone,zones,minutes,totalminutes:minutes*zones,water:emitters*lines*n('litres')};\n }else throw Error(\"Unknown calculator.\");\n if(Object.values(o).some(x=>!Number.isFinite(x)))throw Error(\"Measurements exceed the supported range.\");\n return o;\n}\nif(typeof module!=='undefined')module.exports=calculateLawn;\n\n(()=>{const root=document.getElementById('lawn-tool'),form=root.querySelector('form'),result=root.querySelector('.result'),labels={\"effective\": \"Effective width after overlap (cm)\", \"productivity\": \"Estimated productivity (m\u00b2\/hour)\", \"minutes\": \"Mowing time (minutes)\", \"total\": \"Total time including additional work (minutes)\"};let last=null;\nfunction polygons(text){return text.trim().split(\/\\n\\s*\\n\/).map(block=>{let rows=block.trim().split(\/\\n\/),exclude=\/^[-\u2013\u2014]$\/.test(rows[0].trim());if(exclude)rows.shift();return {exclude,points:rows.map(row=>{let parts=row.trim().split(\/\\s*,\\s*\/);if(parts.length!==2||parts.some(p=>!p.trim()))throw Error(\"Use one x,y coordinate per line.\");return parts.map(Number);})};});}\nform.addEventListener('submit',e=>{e.preventDefault();last=null;try{let v=Object.fromEntries(new FormData(form));let polys;if(form.dataset.mode==='area'){polys=polygons(v.coordinates);v.polygons=JSON.stringify(polys);}let out=calculateLawn(form.dataset.mode,v);result.replaceChildren();for(let [key,value]of Object.entries(out)){let p=document.createElement('p');p.textContent=labels[key]+': '+value.toLocaleString(\"en\",{maximumFractionDigits:3});result.append(p);}if(polys){let svg=root.querySelector('#area-diagram'),all=polys.flatMap(p=>p.points),xs=all.map(p=>p[0]),ys=all.map(p=>p[1]),minx=Math.min(...xs),miny=Math.min(...ys),w=Math.max(...xs)-minx,h=Math.max(...ys)-miny;svg.replaceChildren();svg.setAttribute('viewBox',[minx-1,miny-1,w+2,h+2].join(' '));for(let poly of polys){let shape=document.createElementNS('http:\/\/www.w3.org\/2000\/svg','polygon');shape.setAttribute('points',poly.points.map(p=>p.join(',')).join(' '));shape.setAttribute('fill',poly.exclude?'#fff':'#b4e8c1');shape.setAttribute('stroke','#147e91');shape.setAttribute('stroke-width',Math.max(w,h)\/200);svg.append(shape);}last=out.area;root.querySelector('#copy-area').disabled=false;}}\ncatch(err){result.textContent=err.message;if(root.querySelector('#copy-area'))root.querySelector('#copy-area').disabled=true;}});\nform.addEventListener('reset',()=>{last=null;result.textContent=\"Enter your measurements and calculate.\";let svg=root.querySelector('#area-diagram');if(svg)svg.replaceChildren();let b=root.querySelector('#copy-area');if(b)b.disabled=true;});\nlet copy=root.querySelector('#copy-area');if(copy)copy.addEventListener('click',async()=>{if(last===null)return;try{await navigator.clipboard.writeText(String(last));result.append(document.createTextNode(\" Area copied in m\u00b2.\"));}catch(e){result.append(document.createTextNode(\" Copy area manually: \"+last+' m\u00b2.'));}});\n})();\n(()=>{let r=document.getElementById('lawn-tool');r.querySelector('form').addEventListener('input',()=>{r.querySelector('.result').textContent=\"Enter your measurements and calculate.\";let b=r.querySelector('#copy-area');if(b)b.disabled=true;let s=r.querySelector('#area-diagram');if(s)s.replaceChildren();});})();<\/script>\n","protected":false},"excerpt":{"rendered":"<p>Estimate mowing time from measured area, cutting width, speed, overlap and turning efficiency. Lawn area (m\u00b2)Full cutting width (cm)Actual mowing speed (km\/hour)Overlap between passes (%)Turning and obstacle efficiency, excluding overlap (%)Additional edging, setup and cleanup (minutes) CalculateReset Enter your measurements and calculate. How this calculator works Effective width = full cutting width \u00d7 (1 \u2212 [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"aiper_reading_time":2,"aiper_last_reviewed":"","aiper_reviewer":0,"aiper_related_ids":[],"aiper_layout":"","footnotes":""},"class_list":["post-13423","page","type-page","status-publish","hentry"],"lang":"en","translations":{"en":13423,"es":13426,"fr":13425,"de":13424},"_links":{"self":[{"href":"https:\/\/aiper.com\/blogs\/wp-json\/wp\/v2\/pages\/13423","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/aiper.com\/blogs\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/aiper.com\/blogs\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/aiper.com\/blogs\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/aiper.com\/blogs\/wp-json\/wp\/v2\/comments?post=13423"}],"version-history":[{"count":1,"href":"https:\/\/aiper.com\/blogs\/wp-json\/wp\/v2\/pages\/13423\/revisions"}],"predecessor-version":[{"id":13439,"href":"https:\/\/aiper.com\/blogs\/wp-json\/wp\/v2\/pages\/13423\/revisions\/13439"}],"wp:attachment":[{"href":"https:\/\/aiper.com\/blogs\/wp-json\/wp\/v2\/media?parent=13423"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}