harn-stdlib 0.8.16

Embedded Harn standard library source catalog
Documentation
// std/calendar — civil date, timezone, country, and business-calendar helpers.
//
// Import with: import { add_business_days, country_info, start_of_week } from "std/calendar"
/** Return timezone-local calendar fields, including ISO week and quarter. */
pub fn parts(timestamp, timezone: string = "UTC") -> dict {
  return __calendar_parts(timestamp, timezone)
}

/** Return `{year, week}` for the timestamp's ISO week in `timezone`. */
pub fn iso_week(timestamp, timezone: string = "UTC") -> dict {
  let p = parts(timestamp, timezone)
  return {year: p.iso_week_year, week: p.iso_week}
}

/** Return the calendar quarter number, 1-4, in `timezone`. */
pub fn quarter(timestamp, timezone: string = "UTC") -> int {
  return parts(timestamp, timezone).quarter
}

/**
 * Build a timestamp from local civil components.
 *
 * `disambiguation` controls repeated fall-back times: `"earlier"`, `"later"`,
 * or `"reject"`. Spring-forward gaps always reject.
 */
pub fn local_datetime(parts: dict, timezone: string = "UTC", disambiguation: string = "earlier") {
  return __calendar_from_local(parts, timezone, disambiguation)
}

/** Add calendar units in a timezone, preserving local clock fields. */
pub fn add_calendar_units(
  timestamp,
  amount: int,
  unit: string,
  timezone: string = "UTC",
  disambiguation: string = "earlier",
) {
  return __calendar_add(timestamp, amount, unit, timezone, disambiguation)
}

/** Return the start or end timestamp for a civil calendar unit. */
pub fn boundary(timestamp, unit: string, edge: string = "start", timezone: string = "UTC") {
  return __calendar_boundary(timestamp, unit, edge, timezone)
}

/** Return the local start of the day that contains `timestamp`. */
pub fn start_of_day(timestamp, timezone: string = "UTC") {
  return boundary(timestamp, "day", "start", timezone)
}

/** Return the local end of the day that contains `timestamp`. */
pub fn end_of_day(timestamp, timezone: string = "UTC") {
  return boundary(timestamp, "day", "end", timezone)
}

/** Return the Monday-local start of the week that contains `timestamp`. */
pub fn start_of_week(timestamp, timezone: string = "UTC") {
  return boundary(timestamp, "week", "start", timezone)
}

/** Return the Sunday-local end of the week that contains `timestamp`. */
pub fn end_of_week(timestamp, timezone: string = "UTC") {
  return boundary(timestamp, "week", "end", timezone)
}

/** Return the local start of the month that contains `timestamp`. */
pub fn start_of_month(timestamp, timezone: string = "UTC") {
  return boundary(timestamp, "month", "start", timezone)
}

/** Return the local end of the month that contains `timestamp`. */
pub fn end_of_month(timestamp, timezone: string = "UTC") {
  return boundary(timestamp, "month", "end", timezone)
}

/** Return the local start of the quarter that contains `timestamp`. */
pub fn start_of_quarter(timestamp, timezone: string = "UTC") {
  return boundary(timestamp, "quarter", "start", timezone)
}

/** Return the local end of the quarter that contains `timestamp`. */
pub fn end_of_quarter(timestamp, timezone: string = "UTC") {
  return boundary(timestamp, "quarter", "end", timezone)
}

/** Return the local start of the year that contains `timestamp`. */
pub fn start_of_year(timestamp, timezone: string = "UTC") {
  return boundary(timestamp, "year", "start", timezone)
}

/** Return the local end of the year that contains `timestamp`. */
pub fn end_of_year(timestamp, timezone: string = "UTC") {
  return boundary(timestamp, "year", "end", timezone)
}

/** Return local calendar-unit ticks in the half-open range `[start, end)`. */
pub fn date_range(start, end, unit: string = "day", timezone: string = "UTC", options: dict = {}) -> list {
  return __calendar_date_range(start, end, unit, timezone, options)
}

/** Return the next matching weekday. Weekdays are ISO 1-7 or names. */
pub fn next_weekday(timestamp, weekday, timezone: string = "UTC", include_today: bool = false) {
  return __calendar_next_weekday(timestamp, weekday, "next", timezone, include_today)
}

/** Return the previous matching weekday. Weekdays are ISO 1-7 or names. */
pub fn previous_weekday(timestamp, weekday, timezone: string = "UTC", include_today: bool = false) {
  return __calendar_next_weekday(timestamp, weekday, "previous", timezone, include_today)
}

/** Return supported country metadata records. */
pub fn countries() -> list {
  return __calendar_countries()
}

/** Return country metadata for an ISO alpha-2 code, or nil when unsupported. */
pub fn country_info(code: string) {
  return __calendar_country_info(code)
}

/** Return known IANA timezones for a supported country code, or nil. */
pub fn country_timezones(code: string) {
  let info = country_info(code)
  if info == nil {
    return nil
  }
  return info.timezones
}

/**
 * Return the only safe default timezone for a country, or nil when the country
 * is unsupported or has multiple plausible timezones.
 */
pub fn default_timezone_for_country(code: string) {
  let info = country_info(code)
  if info == nil || info.default_timezone_ambiguous {
    return nil
  }
  return info.default_timezone
}

/** Return explicit v1 holiday calendars. */
pub fn supported_holiday_calendars() -> list {
  return __calendar_supported_holiday_calendars()
}

/** Return observed holidays for `calendar` in `year`. */
pub fn holidays(year: int, calendar: string = "US-FEDERAL") -> list {
  return __calendar_holidays(calendar, year)
}

/** Return true when `timestamp` falls on a supported or custom holiday. */
pub fn is_holiday(timestamp, calendar = "US-FEDERAL", timezone = nil) -> bool {
  return __calendar_is_holiday(timestamp, calendar, timezone)
}

/** Return true for Saturday or Sunday in `timezone`. */
pub fn is_weekend(timestamp, timezone: string = "UTC") -> bool {
  let weekday = parts(timestamp, timezone).iso_weekday
  return weekday == 6 || weekday == 7
}

/** Return true when the local date is neither weekend nor holiday. */
pub fn is_business_day(timestamp, calendar = "US-FEDERAL", timezone = nil) -> bool {
  return __calendar_is_business_day(timestamp, calendar, timezone)
}

/** Return the next business day, preserving the local time. */
pub fn next_business_day(
  timestamp,
  calendar = "US-FEDERAL",
  timezone = nil,
  include_today: bool = false,
) {
  return __calendar_next_business_day(timestamp, calendar, timezone, include_today)
}

/** Add signed business days, skipping weekends and holidays. */
pub fn add_business_days(timestamp, days: int, calendar = "US-FEDERAL", timezone = nil) {
  return __calendar_add_business_days(timestamp, days, calendar, timezone)
}

/** Count business days in the half-open local date range `[start, end)`. */
pub fn business_days_between(start, end, calendar = "US-FEDERAL", timezone = nil) -> int {
  return __calendar_business_days_between(start, end, calendar, timezone)
}

/** Return a business-hours envelope for the timestamp. */
pub fn business_window(timestamp, calendar = "US-FEDERAL", options: dict = {}) -> dict {
  return __calendar_business_window(timestamp, calendar, options)
}

/** Return true when the timestamp is inside the configured business window. */
pub fn is_business_time(timestamp, calendar = "US-FEDERAL", options: dict = {}) -> bool {
  return business_window(timestamp, calendar, options).inside
}