Module: Pikuri::Thunderbird::DateHelpers

Defined in:
lib/pikuri/thunderbird/date_helpers.rb

Overview

Shared presentation helpers turning backend records into the compact, LLM-facing text the tools emit. Kept out of Gloda/Calendar so those stay pure data accessors (raw Times + tz strings), and out of the tool classes so mail/calendar render dates identically.

Constant Summary collapse

DATE_ONLY =

Returns a bare YYYY-MM-DD with no time component.

Returns:

  • (Regexp)

    a bare YYYY-MM-DD with no time component.

/\A\d{4}-\d{2}-\d{2}\z/

Class Method Summary collapse

Class Method Details

.parse_after(str) ⇒ Time?

Inclusive lower bound for a date range. A bare date means the start of that day (local midnight) — the natural "on or after this date".

Parameters:

  • str (String, nil)

Returns:

  • (Time, nil)

Raises:

  • (ArgumentError)

    on an unparseable non-blank string.



61
# File 'lib/pikuri/thunderbird/date_helpers.rb', line 61

def self.parse_after(str) = parse_time(str)

.parse_before(str) ⇒ Time?

Inclusive upper bound. A bare date means the end of that day (23:59:59 local), so "on or before 2026-07-15" includes everything that happens ON the 15th — and a same-day after=before=<date> window spans the whole day, not the single midnight instant. An explicit datetime (with a time component) is used verbatim.

Parameters:

  • str (String, nil)

Returns:

  • (Time, nil)

Raises:

  • (ArgumentError)

    on an unparseable non-blank string.



72
73
74
75
76
77
# File 'lib/pikuri/thunderbird/date_helpers.rb', line 72

def self.parse_before(str)
  t = parse_time(str)
  return nil if t.nil?

  str.to_s.strip.match?(DATE_ONLY) ? t + 86_399 : t
end

.parse_time(str) ⇒ Time?

Parse a user/LLM-supplied date or datetime string to a Time. Use parse_after/parse_before for range bounds — they give a bare date the right inclusive edge.

Parameters:

  • str (String, nil)

Returns:

  • (Time, nil)

    nil when str is blank.

Raises:

  • (ArgumentError)

    on an unparseable non-blank string.



86
87
88
89
90
# File 'lib/pikuri/thunderbird/date_helpers.rb', line 86

def self.parse_time(str)
  return nil if str.nil? || str.to_s.strip.empty?

  Time.parse(str.to_s)
end

.short_datetime(time) ⇒ String

Returns "YYYY-MM-DD HH:MM" (local), or "?".

Parameters:

  • time (Time, nil)

Returns:

  • (String)

    "YYYY-MM-DD HH:MM" (local), or "?".



30
31
32
# File 'lib/pikuri/thunderbird/date_helpers.rb', line 30

def self.short_datetime(time)
  time ? time.getlocal.strftime('%Y-%m-%d %H:%M') : '?'
end

.when_label(event) ⇒ String

Human "when" for a calendar event. All-day events render as a date (or date range, honoring the iCal exclusive DTEND); timed events render in the machine's local zone with the event's own tzid appended — a correct-in-the-common-case heuristic (TB host zone == user zone == dominant event zone), with the tzid shown so a cross-zone event is legible.

Parameters:

  • event (Hash)

    a Calendar record (+:start+, :end, :all_day, :start_tz).

Returns:

  • (String)


22
23
24
25
26
# File 'lib/pikuri/thunderbird/date_helpers.rb', line 22

def self.when_label(event)
  return '(no date)' unless event[:start]

  event[:all_day] ? all_day_label(event) : timed_label(event)
end