PageSourceSearch

https://vali-tempo-docs.netlify.app/assets/js/e54ed230.a1e9c0e6.js

js vali-tempo-docs.netlify.app collected 2026-10-03 11:34:56 UTC 16,788 bytes, 1 lines download raw bytes

1"use strict";(globalThis.webpackChunkvali_tempo_docs=globalThis.webpackChunkvali_tempo_docs||[]).push([[927],{8725(e,n,r){r.r(n),r.d(n,{assets:()=>t,contentTitle:()=>i,default:()=>o,frontMatter:()=>s,metadata:()=>c,toc:()=>a});const c=JSON.parse('{"id":"vali-schedule/overview","title":"Vali-Schedule Overview","description":"Vali-Schedule provides cron-style and recurrence scheduling for .NET \u2014 compute next and previous occurrences for daily, weekly, monthly, and custom patterns.","source":"@site/docs/vali-schedule/overview.md","sourceDirName":"vali-schedule","slug":"/vali-schedule/overview","permalink":"/docs/vali-schedule/overview","draft":false,"unlisted":false,"editUrl":"https://github.com/UBF21/Vali-Tempo/tree/main/docs/vali-schedule/overview.md","tags":[],"version":"current","frontMatter":{"id":"overview","title":"Vali-Schedule Overview","sidebar_label":"Overview","description":"Vali-Schedule provides cron-style and recurrence scheduling for .NET \u2014 compute next and previous occurrences for daily, weekly, monthly, and custom patterns.","keywords":["Vali-Schedule","scheduling","recurrence","cron",".NET","NuGet","C#","next occurrence"]},"sidebar":"docsSidebar","previous":{"title":"Changelog","permalink":"/docs/vali-age/changelog"},"next":{"title":"Examples","permalink":"/docs/vali-schedule/examples"}}');var d=r(4848),l=r(8453);const s={id:"overview",title:"Vali-Schedule Overview",sidebar_label:"Overview",description:"Vali-Schedule provides cron-style and recurrence scheduling for .NET \u2014 compute next and previous occurrences for daily, weekly, monthly, and custom patterns.",keywords:["Vali-Schedule","scheduling","recurrence","cron",".NET","NuGet","C#","next occurrence"]},i="Vali-Schedule",t={},a=[{value:"Installation",id:"installation",level:2},{value:"Registration",id:"registration",level:2},{value:"Enums",id:"enums",level:2},{value:"RecurrenceType",id:"recurrencetype",level:3},{value:"RecurrenceEnd",id:"recurrenceend",level:3},{value:"IValiSchedule \u2014 Fluent Builder API",id:"ivalischedule--fluent-builder-api",level:2},{value:"Every",id:"every",level:3},{value:"On",id:"on",level:3},{value:"At",id:"at",level:3},{value:"StartingFrom",id:"startingfrom",level:3},{value:"EndsAfter",id:"endsafter",level:3},{value:"EndsOn",id:"endson",level:3},{value:"OnDayOfMonth",id:"ondayofmonth",level:3},{value:"WithCustomPredicate",id:"withcustompredicate",level:3},{value:"Build",id:"build",level:3},{value:"Query Methods",id:"query-methods",level:2},{value:"NextOccurrence",id:"nextoccurrence",level:3},{value:"PreviousOccurrence",id:"previousoccurrence",level:3},{value:"OccursOn",id:"occurson",level:3},{value:"Occurrences",id:"occurrences",level:3},{value:"OccurrencesInRange",id:"occurrencesinrange",level:3},{value:"Complete Examples",id:"complete-examples",level:2},{value:"Weekly standup",id:"weekly-standup",level:3},{value:"Monthly payroll run",id:"monthly-payroll-run",level:3},{value:"Yearly reminder with end condition",id:"yearly-reminder-with-end-condition",level:3}];function h(e){const n={admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,l.R)(),...e.components};return(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(n.header,{children:(0,d.jsx)(n.h1,{id:"vali-schedule",children:"Vali-Schedule"})}),"\n",(0,d.jsxs)(n.p,{children:[(0,d.jsx)(n.code,{children:"IValiSchedule"})," is a fluent builder for recurring schedules. It supports daily, weekly, monthly, and yearly recurrence patterns with start date, end conditions, and custom predicates."]}),"\n",(0,d.jsx)(n.h2,{id:"installation",children:"Installation"}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{className:"language-bash",children:"dotnet add package Vali-Schedule\n"})}),"\n",(0,d.jsx)(n.h2,{id:"registration",children:"Registration"}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{className:"language-csharp",children:"builder.Services.AddValiSchedule();\n// or via the meta-package:\nbuilder.Services.AddValiTempo();\n"})}),"\n",(0,d.jsx)(n.admonition,{title:"Thread safety",type:"warning",children:(0,d.jsxs)(n.p,{children:[(0,d.jsx)(n.code,{children:"IValiSchedule"})," is ",(0,d.jsx)(n.strong,{children:"not thread-safe"})," and should ",(0,d.jsx)(n.strong,{children:"not"})," be registered as a singleton. Register it as ",(0,d.jsx)(n.strong,{children:"scoped"})," or ",(0,d.jsx)(n.strong,{children:"transient"}),", or create new instances as needed. The builder pattern is stateful between calls."]})}),"\n",(0,d.jsx)(n.h2,{id:"enums",children:"Enums"}),"\n",(0,d.jsx)(n.h3,{id:"recurrencetype",children:"RecurrenceType"}),"\n",(0,d.jsx)(n.p,{children:"Defines how often the schedule repeats:"}),"\n",(0,d.jsxs)(n.table,{children:[(0,d.jsx)(n.thead,{children:(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.th,{children:"Value"}),(0,d.jsx)(n.th,{children:"Description"})]})}),(0,d.jsxs)(n.tbody,{children:[(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"Daily"})}),(0,d.jsx)(n.td,{children:"Repeats every N days"})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"Weekly"})}),(0,d.jsx)(n.td,{children:"Repeats every N weeks on specified days"})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"Monthly"})}),(0,d.jsx)(n.td,{children:"Repeats every N months on a specified day"})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"Yearly"})}),(0,d.jsx)(n.td,{children:"Repeats every N years on a specified month and day"})]})]})]}),"\n",(0,d.jsx)(n.h3,{id:"recurrenceend",children:"RecurrenceEnd"}),"\n",(0,d.jsx)(n.p,{children:"Defines when the schedule stops:"}),"\n",(0,d.jsxs)(n.table,{children:[(0,d.jsx)(n.thead,{children:(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.th,{children:"Value"}),(0,d.jsx)(n.th,{children:"Description"})]})}),(0,d.jsxs)(n.tbody,{children:[(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"Never"})}),(0,d.jsx)(n.td,{children:"The schedule repeats indefinitely"})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"AfterOccurrences"})}),(0,d.jsx)(n.td,{children:"Stops after a fixed number of occurrences"})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"OnDate"})}),(0,d.jsx)(n.td,{children:"Stops on or after a specific end date"})]})]})]}
1),"\n",(0,d.jsx)(n.h2,{id:"ivalischedule--fluent-builder-api",children:"IValiSchedule \u2014 Fluent Builder API"}),"\n",(0,d.jsx)(n.h3,{id:"every",children:"Every"}),"\n",(0,d.jsx)(n.p,{children:"Set the interval and recurrence type:"}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{className:"language-csharp",children:"schedule.Every(1, RecurrenceType.Daily)    // every day\nschedule.Every(2, RecurrenceType.Weekly)   // every 2 weeks\nschedule.Every(1, RecurrenceType.Monthly)  // every month\nschedule.Every(1, RecurrenceType.Yearly)   // every year\n"})}),"\n",(0,d.jsxs)(n.p,{children:[(0,d.jsx)(n.strong,{children:"Signature:"})," ",(0,d.jsx)(n.code,{children:"IValiSchedule Every(int interval, RecurrenceType type)"})]}),"\n",(0,d.jsx)(n.h3,{id:"on",children:"On"}),"\n",(0,d.jsx)(n.p,{children:"For weekly schedules: specify which days of the week to include:"}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{className:"language-csharp",children:"schedule.Every(1, RecurrenceType.Weekly)\n        .On(DayOfWeek.Monday, DayOfWeek.Wednesday, DayOfWeek.Friday)\n"})}),"\n",(0,d.jsxs)(n.p,{children:[(0,d.jsx)(n.strong,{children:"Signature:"})," ",(0,d.jsx)(n.code,{children:"IValiSchedule On(params DayOfWeek[] days)"})]}),"\n",(0,d.jsx)(n.h3,{id:"at",children:"At"}),"\n",(0,d.jsx)(n.p,{children:"Set the time of day for occurrences:"}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{className:"language-csharp",children:"schedule.Every(1, RecurrenceType.Daily)\n        .At(9, 0) // 9:00 AM\n"})}),"\n",(0,d.jsxs)(n.p,{children:[(0,d.jsx)(n.strong,{children:"Signature:"})," ",(0,d.jsx)(n.code,{children:"IValiSchedule At(int hour, int minute = 0, int second = 0)"})]}),"\n",(0,d.jsx)(n.h3,{id:"startingfrom",children:"StartingFrom"}),"\n",(0,d.jsxs)(n.p,{children:["Set the start date (default is ",(0,d.jsx)(n.code,{children:"DateTime.Today"}),"):"]}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{className:"language-csharp",children:"schedule.Every(1, RecurrenceType.Weekly)\n        .StartingFrom(new DateTime(2025, 4, 1))\n"})}),"\n",(0,d.jsxs)(n.p,{children:[(0,d.jsx)(n.strong,{children:"Signature:"})," ",(0,d.jsx)(n.code,{children:"IValiSchedule StartingFrom(DateTime startDate)"})]}),"\n",(0,d.jsx)(n.h3,{id:"endsafter",children:"EndsAfter"}),"\n",(0,d.jsx)(n.p,{children:"Stop the schedule after a fixed number of occurrences:"}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{className:"language-csharp",children:"schedule.Every(1, RecurrenceType.Daily)\n        .EndsAfter(10) // 10 occurrences then stop\n"})}),"\n",(0,d.jsxs)(n.p,{children:[(0,d.jsx)(n.strong,{children:"Signature:"})," ",(0,d.jsx)(n.code,{children:"IValiSchedule EndsAfter(int occurrences)"})]}),"\n",(0,d.jsx)(n.h3,{id:"endson",children:"EndsOn"}),"\n",(0,d.jsx)(n.p,{children:"Stop the schedule on or after a specific date:"}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{className:"language-csharp",children:"schedule.Every(1, RecurrenceType.Monthly)\n        .EndsOn(new DateTime(2026, 12, 31))\n"})}),"\n",(0,d.jsxs)(n.p,{children:[(0,d.jsx)(n.strong,{children:"Signature:"})," ",(0,d.jsx)(n.code,{children:"IValiSchedule EndsOn(DateTime endDate)"})]}),"\n",(0,d.jsx)(n.h3,{id:"ondayofmonth",children:"OnDayOfMonth"}),"\n",(0,d.jsx)(n.p,{children:"For monthly schedules: specify which day of the month:"}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{className:"language-csharp",children:"schedule.Every(1, RecurrenceType.Monthly)\n        .OnDayOfMonth(15) // 15th of every month\n"})}),"\n",(0,d.jsxs)(n.p,{children:[(0,d.jsx)(n.strong,{children:"Signature:"})," ",(0,d.jsx)(n.code,{children:"IValiSchedule OnDayOfMonth(int day)"})]}),"\n",(0,d.jsx)(n.h3,{id:"withcustompredicate",children:"WithCustomPredicate"}),"\n",(0,d.jsxs)(n.p,{children:["Add a custom filter \u2014 only occurrences where the predicate returns ",(0,d.jsx)(n.code,{children:"true"})," are included:"]}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{className:"language-csharp",children:"schedule.Every(1, RecurrenceType.Daily)\n        .WithCustomPredicate(date => date.DayOfWeek != DayOfWeek.Friday)\n// Skips Fridays\n"})}),"\n",(0,d.jsxs)(n.p,{children:[(0,d.jsx)(n.strong,{children:"Signature:"})," ",(0,d.jsx)(n.code,{children:"IValiSchedule WithCustomPredicate(Func<DateTime, bool> predicate)"})]}),"\n",(0,d.jsx)(n.h3,{id:"build",children:"Build"}),"\n",(0,d.jsxs)(n.p,{children:["Finalize the builder and return a read-only ",(0,d.jsx)(n.code,{children:"Schedule"})," object:"]}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{className:"language-csharp",children:"var sched = schedule\n    .Every(1, RecurrenceType.Weekly)\n    .On(DayOfWeek.Monday)\n    .At(9, 0)\n    .StartingFrom(new DateTime(2025, 1, 6))\n    .Build();\n"})}),"\n",(0,d.jsxs)(n.p,{children:[(0,d.jsx)(n.strong,{children:"Signature:"})," ",(0,d.jsx)(n.code,{children:"Schedule Build()"})]}),"\n",(0,d.jsx)(n.h2,{id:"query-methods",children:"Query Methods"}),"\n",(0,d.jsxs)(n.p,{children:["Once you have a ",(0,d.jsx)(n.code,{children:"Schedule"}),", use these methods to query occurrences:"]}),"\n",(0,d.jsx)(n.h3,{id:"nextoccurrence",children:"NextOccurrence"}),"\n",(0,d.jsx)(n.p,{children:"Return the next occurrence after a given date:"}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{className:"language-csharp",children:"DateTime? next = sched.NextOccurrence(DateTime.Now);\n// \u2192 null if schedule has ended\n"})}),"\n",(0,d.jsxs)(n.p,{children:[(0,d.jsx)(n.strong,{children:"Signature:"})," ",(0,d.jsx)(n.code,{children:"DateTime? NextOccurrence(DateTime after)"})]}),"\n",(0,d.jsx)(n.h3,{id:"previousoccurrence",children:"PreviousOccurrence"}),"\n",(0,d.jsx)(n.p,{children:"Return the most recent occurrence before a given date:"}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{className:"language-csharp",children:"DateTime? prev = sched.PreviousOccurrence(DateTime.Now);\n"})}),"\n",(0,d.jsxs)(n.p,{children:[(0,d.jsx)(n.strong,{children:"Signature:"})," ",(0,d.jsx)(n.code,{children:"DateTime? PreviousOccurrence(DateTime before)"})]}),"\n",(0,d.jsx)(n.h3,{id:"occurson",children:"OccursOn"}),"\n",(0,d.jsxs)(n.p,{children:["Return ",(0,d.jsx)(n.code,{children:"true"})," if the schedule has an occurrence on the given date (ignoring time):"]}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{className:"language-csharp",children:"bool occurs = sched.OccursOn(new DateTime(2025, 4, 7));\n"})}),"\n",(0,d.jsxs)(n.p,{children:[(0,d.jsx)(n.strong,{children:"Signature:"})," ",(0,d.jsx)(n.code,{children:"bool OccursOn(DateTime date)"})]}),"\n",(0,d.jsx)(n.h3,{id:"occurrences",children:"Occurrences"}),"\n",(0,d.jsx)(n.p,{children:"Enumerate the next N occurrences from a given date:"}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{className:"language-csharp",children:'IEnumerable<DateTime> next5 = sched.Occurrences(5, DateTime.Now);\n\nforeach (var occ in next5)\n    Console.WriteLine(occ.ToString("g"));\n'})}),"\n",(0,d.jsxs)(n.p,{children:[(0,d.jsx)(n.strong,{children:"Signature:"})," ",(0,d.jsx)(n.code,{children:"IEnumerable<DateTime> Occurrences(int count, DateTime from)"})]}),"\n",(0,d.jsx)(n.h3,{id:"occurrencesinrange",children:"OccurrencesInRange"}),"\n",(0,d.jsx)(n.p,{children:"Enumerate all occurrences within a date range:"}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{className:"language-csharp",children:"var range = new DateRange(new DateTime(2025, 4, 1), new DateTime(2025, 6, 30));\nIEnumerable<DateTime> q2Meetings = sched.OccurrencesInRange(range);\n"})}),"\n",(0,d.jsxs)(n.p,{children:[(0,d.jsx)(n.strong,{children:"Signature:"})," ",(0,d.jsx)(n.code,{children:"IEnumerable<DateTime> OccurrencesInRange(DateRange range)"})]}),"\n",(0,d.jsx)(n.h2,{id:"complete-examples",children:"Complete Examples"}),"\n",(0,d.jsx)(n.h3,{id:"weekly-standup",children:"Weekly standup"}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{className:"language-csharp",children:'public class StandupScheduler(IValiSchedule schedule)\n{\n    public Schedule BuildStandup(DateTime startDate)\n    {\n        return schedule\n            .Every(1, RecurrenceType.Weekly)\n            .On(DayOfWeek.Monday, DayOfWeek.Tuesday, DayOfWeek.Wednesday,\n                DayOfWeek.Thursday, DayOfWeek.Friday)\n            .At(9, 30)\n            .StartingFrom(startDate)\n            .Build();\n    }\n\n    public void PrintNextStandups(Schedule sched, int count = 5)\n    {\n        Console.WriteLine($"Next {count} standups:");\n        foreach (var occ in sched.Occurrences(count, DateTime.Now))\n            Console.WriteLine($"  {occ:ddd, MMM dd HH:mm}");\n    }\n}\n'})}),"\n",(0,d.jsx)(n.h3,{id:"monthly-payroll-run",children:"Monthly payroll run"}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{className:"language-csharp",children:"public class PayrollScheduler(IValiSchedule schedule)\n{\n    public Schedule BuildPayroll(int dayOfMonth = 25)\n    {\n        return schedule\n            .Every(1, RecurrenceType.Monthly)\n            .OnDayOfMonth(dayOfMonth)\n            .At(8, 0)\n            .StartingFrom(new DateTime(2025, 1, 1))\n            // Skip months where the 25th falls on weekend\n            .WithCustomPredicate(d =>\n                d.DayOfWeek != DayOfWeek.Saturday &&\n                d.DayOfWeek != DayOfWeek.Sunday)\n            .Build();\n    }\n}\n"})}),"\n",(0,d.jsx)(n.h3,{id:"yearly-reminder-with-end-condition",children:"Yearly reminder with end condition"}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{className:"language-csharp",children:'var reminder = schedule\n    .Every(1, RecurrenceType.Yearly)\n    .At(10, 0)\n    .StartingFrom(new DateTime(2025, 3, 23))\n    .EndsAfter(5) // 5 years only\n    .Build();\n\nDateTime? nextReminder = reminder.NextOccurrence(DateTime.Now);\nConsole.WriteLine($"Next annual reminder: {nextReminder:MMM dd, yyyy}");\n'})})]})}function o(e={}){const{wrapper:n}={...(0,l.R)(),...e.components};return n?(0,d.jsx)(n,{...e,children:(0,d.jsx)(h,{...e})}):h(e)}},8453(e,n,r){r.d(n,{R:()=>s,x:()=>i});var c=r(6540);const d={}
1,l=c.createContext(d);function s(e){const n=c.useContext(l);return c.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(d):e.components||d:s(e.components),c.createElement(l.Provider,{value:n},e.children)}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.