class VirtualDate

Overview

VirtualDate builds on VirtualTime to represent due/omit rules plus higher-level scheduling semantics.

Included Modules

Defined in:

virtualdate.cr

Constant Summary

VERSION = [VERSION_MAJOR, VERSION_MINOR, VERSION_REVISION].join('.')
VERSION_MAJOR = 1
VERSION_MINOR = 2
VERSION_REVISION = 1

Constructors

Instance Method Summary

Constructor Detail

def self.new(ctx : YAML::ParseContext, node : YAML::Nodes::Node) #

[View source]
def self.new(id : String | Nil = "") #

[View source]

Instance Method Detail

def begin : VirtualTime::TimeOrVirtualTime | Nil #

Absolute begin date/time. Item is never "on" before this date.


[View source]
def begin=(begin __arg0 : VirtualTime::TimeOrVirtualTime | Nil) #

Absolute begin date/time. Item is never "on" before this date.


[View source]
def deadline : VirtualTime::TimeOrVirtualTime | Nil #

Hard deadline — vdate MUST finish before this time or fails scheduling


[View source]
def deadline=(deadline : VirtualTime::TimeOrVirtualTime | Nil) #

Hard deadline — vdate MUST finish before this time or fails scheduling


[View source]
def depends_on : Array(VirtualDate) #

Optional dependencies: scheduler will try to place this vdate after all dependencies. (Used only by Scheduler; VirtualDate itself does not enforce this.)


[View source]
def depends_on=(depends_on : Array(VirtualDate)) #

Optional dependencies: scheduler will try to place this vdate after all dependencies. (Used only by Scheduler; VirtualDate itself does not enforce this.)


[View source]
def depends_on_ids : Array(String) #

Serialized form


[View source]
def depends_on_ids=(depends_on_ids : Array(String)) #

Serialized form


[View source]
def due : Array(VirtualTime) #

List of VirtualTimes on which the vdate is "on"/due/active.


[View source]
def due=(due : Array(VirtualTime)) #

List of VirtualTimes on which the vdate is "on"/due/active.


[View source]
def due_on?(time : VirtualTime::TimeOrVirtualTime = Time.local, times = @due) #

[View source]
def due_on_any_date?(time : VirtualTime::TimeOrVirtualTime = Time.local, times = @due) #

[View source]
def due_on_any_time?(time : VirtualTime::TimeOrVirtualTime = Time.local, times = @due) #

[View source]
def duration : Time::Span #

[View source]
def duration=(duration : Time::Span) #

[View source]
def end : VirtualTime::TimeOrVirtualTime | Nil #

Absolute end date/time. Item is never "on" after this date.


[View source]
def end=(end __arg0 : VirtualTime::TimeOrVirtualTime | Nil) #

Absolute end date/time. Item is never "on" after this date.


[View source]
def fixed : Bool #

If true, Scheduler treats this vdate as non-movable due to conflicts (still movable by omit-rescheduling rules if you keep shift != false).


[View source]
def fixed=(fixed : Bool) #

If true, Scheduler treats this vdate as non-movable due to conflicts (still movable by omit-rescheduling rules if you keep shift != false).


[View source]
def flags : Set(String) #

Flags/categories (e.g. meeting, task, or passive/active/unimportant, or color-coded, or anything). Used by Scheduler for parallelism.


[View source]
def flags=(flags : Set(String)) #

Flags/categories (e.g. meeting, task, or passive/active/unimportant, or color-coded, or anything). Used by Scheduler for parallelism.


[View source]
def id : String #

Identifier (important for dependencies)


[View source]
def id=(id : String) #

Identifier (important for dependencies)


[View source]
def matches_any_date?(time : VirtualTime::TimeOrVirtualTime, times : Array(VirtualTime), default) #

[View source]
def matches_any_time?(time : VirtualTime::TimeOrVirtualTime, times : Array(VirtualTime), default) #

[View source]
def max_shift : Time::Span | Nil #

Max amount of total time by which vdate can be shifted before it's considered unschedulable (false)


[View source]
def max_shift=(max_shift : Time::Span | Nil) #

Max amount of total time by which vdate can be shifted before it's considered unschedulable (false)


[View source]
def max_shifts : Int32 #

Max amount of shift attempts, before it's considered unschedulable (false)


[View source]
def max_shifts=(max_shifts : Int32) #

Max amount of shift attempts, before it's considered unschedulable (false)


[View source]
def omit : Array(VirtualTime) #

List of VirtualTimes on which the vdate should be "omitted".


[View source]
def omit=(omit : Array(VirtualTime)) #

List of VirtualTimes on which the vdate should be "omitted".


[View source]
def omit_on?(time : VirtualTime::TimeOrVirtualTime = Time.local, times = @omit) #

[View source]
def omit_on_dates?(time : VirtualTime::TimeOrVirtualTime = Time.local, times = @omit) #

[View source]
def omit_on_times?(time : VirtualTime::TimeOrVirtualTime = Time.local, times = @omit) #

[View source]
def on : Nil | Bool | Time::Span #

Fixed override of #on? for this vdate. If set, takes precedence over begin/end/due/omit. Same union as #shift.


[View source]
def on=(on : Nil | Bool | Time::Span) #

Fixed override of #on? for this vdate. If set, takes precedence over begin/end/due/omit. Same union as #shift.


[View source]
def on?(time : Time, *, max_shift = @max_shift, max_shifts = @max_shifts) : Bool #

Checks if the vdate is effectively scheduled at time. Returns:

  • true if it is on at time directly, OR due at some base time that resolves (via shifting) to exactly time
  • false if would be on, but can't be scheduled to a slot Returns Time::Span if it's shifted by some amount Returns nil if not applicable / not scheduled

(For omit-driven shifting (Time::Span), we can search candidate base times by shifting back in the opposide direction. This is deterministic, bounded by max_shifts/max_shift.)


[View source]
def parallel : Int32 #

Max number of overlapping vdates that share at least one common flag with this vdate. Example: flags={meeting}, parallel=2 means up to 2 meetings can overlap.


[View source]
def parallel=(parallel : Int32) #

Max number of overlapping vdates that share at least one common flag with this vdate. Example: flags={meeting}, parallel=2 means up to 2 meetings can overlap.


[View source]
def priority : Int32 #

Higher wins conflict resolution when Scheduler must choose.


[View source]
def priority=(priority : Int32) #

Higher wins conflict resolution when Scheduler must choose.


[View source]
def resolve(time : VirtualTime::TimeOrVirtualTime = Time.local, *, max_shift = @max_shift, max_shifts = @max_shifts, hint = time.is_a?(Time) ? time : Time.local) : Time | Bool | Nil #

Resolves the asked VirtualTime to an effective scheduled Time.

Returns:

  • Time : resolved scheduled time
  • true : scheduled "as asked" (same as returning time, but preserved for symmetry)
  • nil : not scheduled
  • false : due but unschedulable

Notes:

  • For Time input, returned Time preserves the timezone/location of the input time.
  • For VirtualTime input, uses hint for materialization as in legacy #on?.

[View source]
def resolve_dependencies!(index : Hash(String, VirtualDate)) #

[View source]
def shift : Nil | Bool | Time::Span #

Decision about an vdate to make if it falls on an omitted date/time.

Allowed values are:

  • nil: treat the vdate as non-applicable/not-scheduled on the specified date/time
  • false: treat the vdate as not due due to falling on an omitted date/time, after a reschedule was not attempted or was not able to find another spot
  • true: treat the vdate as due regardless of falling on an omitted date/time
  • Time::Span: shift the scheduled date/time by specified time span. Can be negative or positive.

[View source]
def shift=(shift : Nil | Bool | Time::Span) #

Decision about an vdate to make if it falls on an omitted date/time.

Allowed values are:

  • nil: treat the vdate as non-applicable/not-scheduled on the specified date/time
  • false: treat the vdate as not due due to falling on an omitted date/time, after a reschedule was not attempted or was not able to find another spot
  • true: treat the vdate as due regardless of falling on an omitted date/time
  • Time::Span: shift the scheduled date/time by specified time span. Can be negative or positive.

[View source]
def stagger : Time::Span | Nil #

Optional staggered parallel scheduling


[View source]
def stagger=(stagger : Time::Span | Nil) #

Optional staggered parallel scheduling


[View source]
def strict_on?(time : VirtualTime::TimeOrVirtualTime = Time.local, *, max_shift = @max_shift, max_shifts = @max_shifts, hint = time.is_a?(Time) ? time : Time.local) : Nil | Bool | Time::Span #

Checks whether the vdate is "on" on the specified date/time.

Return values: nil - vdate is not "on" / not due / not scheduled true - vdate is "on" (due and not omitted) false - vdate is due but omitted and no reschedule requested or possible Time::Span - the span to add to asked date to reach earliest/closest time when vdate is "on"

IMPORTANT: If the vdate is rescheduled away from the asked time, #strict_on? returns a Time::Span, but querying #strict_on? at the rescheduled time will not necessarily return true. Use #resolve or #on? to return a true falue for shifted dates/times.


[View source]