Overview
The Bell class (src/utils/bell.ts) is the core utility for managing school schedules, calculating periods, and determining school day information. It processes schedule data and provides methods for time-based calculations.
Constructor
new Bell(date: Date, schedules?: ScheduleCollection[], scheduleMode?: string)
The date to get schedule information for
Custom list of schedules (defaults to schedules from schedules.json)
Specific schedule mode to use (e.g., “Normal”, “Half Periods”). Defaults to first available mode.
Example:
import Bell from '@/utils/bell';
// Get schedule for today
const bell = new Bell(new Date());
// Get schedule for a specific date
const futureDate = new Date('2026-12-25');
const christmasBell = new Bell(futureDate);
// Use a specific schedule mode
const halfDayBell = new Bell(new Date(), undefined, 'Half Periods');
Instance Properties
The date this Bell instance represents
Whether there is school on this date
Schedule type name (e.g., “Standard Schedule”, “Late Arrival”, “No School”, “No School (Weekend)”)
All available schedule modes for this date
Date patterns this schedule applies to
Current schedule mode name (e.g., “Normal”, “Half Periods”). Undefined if no school.
schedule
SingleDaySchedule | undefined
The processed single-day schedule with period times and names. Undefined if no school.
Current period information (name, start, end times, or before/after school). Undefined if no school.
Date of the next school day after this date
Whether currently in a class period (not before school, after school, or no school)
Instance Methods
getRange()
Returns a human-readable time range for the current period or entire day.
Returns: Time range string (e.g., “8:00 – 9:20”) or empty string if no school
Example:
const bell = new Bell(new Date());
console.log(bell.getRange()); // "8:00 – 3:15"
getPeriodName()
Returns the formatted name of the current period.
Returns: Period name (e.g., “Period 1”, “Passing”) or empty string if not in school
Example:
const bell = new Bell(new Date());
console.log(bell.getPeriodName()); // "Period 3"
getSecondsUntilNextTarget()
Calculates seconds until the next significant time (end of current period or start of next school day).
getSecondsUntilNextTarget(): number
Returns: Number of seconds until next bell or school day start
Example:
const bell = new Bell(new Date());
const seconds = bell.getSecondsUntilNextTarget();
const minutes = Math.floor(seconds / 60);
console.log(`${minutes} minutes until next bell`);
Static Methods
getScheduleType()
Finds the schedule collection that matches the given date.
static getScheduleType(date: Date, schedules?: ScheduleCollection[]): ScheduleCollection
Example:
const scheduleType = Bell.getScheduleType(new Date());
console.log(scheduleType.name); // "Standard Schedule"
getSchedule()
Selects a specific schedule mode from available modes.
static getSchedule(scheduleModes: Schedule[], scheduleMode: string): Schedule | null
Returns: The matching schedule or the first schedule if mode not found, null if no modes available
getPeriod()
Determines which period is active at the given date/time.
static getPeriod(schedule: SingleDaySchedule, date: Date): Period
Returns: Period object indicating current class, passing period, or before/after school
Example:
const schedule = {
name: "Normal",
start: ["8:00", "9:30"],
end: ["9:20", "10:50"],
periods: ["1", "2"]
};
const now = new Date('2026-03-02 09:00');
const period = Bell.getPeriod(schedule, now);
console.log(period); // { name: "1", start: "8:00", end: "9:20" }
isSingleDaySchedule()
Type guard checking if a schedule is single-day.
static isSingleDaySchedule(schedule: Schedule): schedule is SingleDaySchedule
isMultiDaySchedule()
Type guard checking if a schedule is multi-day (like Finals).
static isMultiDaySchedule(schedule: Schedule): schedule is MultiDaySchedule
isBetweenTime()
Tests whether a date falls within a time range.
static isBetweenTime(date: Date, start: string, end: string): boolean
Parameters:
date: Date object including the time to test
start: 24-hour start time string (inclusive), e.g., “8:00”
end: 24-hour end time string (exclusive), e.g., “9:20”
Example:
const testTime = new Date('2026-03-02 08:30');
const inPeriod = Bell.isBetweenTime(testTime, "8:00", "9:20");
console.log(inPeriod); // true
processMultiDay()
Converts a multi-day schedule to a single-day schedule for a specific date.
static processMultiDay(schedule: Schedule, date: Date, dates: string[]): SingleDaySchedule
Formats a period name for display.
static formatPeriodName(name: string): string
Example:
Bell.formatPeriodName("1"); // "Period 1"
Bell.formatPeriodName("!Passing"); // "Passing"
convertMilitaryTime()
Converts 24-hour time to 12-hour format.
static convertMilitaryTime(time: string): string
Example:
Bell.convertMilitaryTime("8:00"); // "8:00"
Bell.convertMilitaryTime("13:30"); // "1:30"
Bell.convertMilitaryTime("0:00"); // "12:00"
getSuffix()
Returns AM/PM suffix for a 24-hour time.
static getSuffix(time: string): string
Example:
Bell.getSuffix("8:00"); // "AM"
Bell.getSuffix("13:30"); // "PM"
timeToNumber()
Converts time string to minutes since midnight for comparisons.
static timeToNumber(time: string): number
Example:
Bell.timeToNumber("8:00"); // 480
Bell.timeToNumber("13:30"); // 810
getNextSchoolDay()
Finds the next school day after the given date.
static getNextSchoolDay(date: Date, schedules?: ScheduleCollection[]): Date
Type Guard
isBellOnSchoolDay()
Type guard function that narrows Bell to have all required properties when it’s a school day.
function isBellOnSchoolDay(bell: Bell): bell is Required<Bell>
Example:
import Bell, { isBellOnSchoolDay } from '@/utils/bell';
const bell = new Bell(new Date());
if (isBellOnSchoolDay(bell)) {
// TypeScript knows these properties are defined
console.log(bell.mode);
console.log(bell.schedule);
console.log(bell.period);
}
Complete Usage Example
import Bell, { isBellOnSchoolDay } from '@/utils/bell';
import { useScheduleStore } from '@/stores/schedules';
import { dateToSeconds } from '@/utils/util';
export default {
setup() {
const scheduleStore = useScheduleStore();
// Create Bell instance with custom schedules
const bell = new Bell(
new Date(),
scheduleStore.schedules,
scheduleStore.scheduleMode
);
// Check if school day
if (isBellOnSchoolDay(bell)) {
console.log(`Schedule: ${bell.type}`);
console.log(`Mode: ${bell.mode}`);
console.log(`Current period: ${bell.getPeriodName()}`);
console.log(`Time range: ${bell.getRange()}`);
// Calculate countdown
if (bell.inSchool) {
const secondsLeft = bell.getSecondsUntilNextTarget();
console.log(`${Math.floor(secondsLeft / 60)} minutes until bell`);
}
} else {
console.log('No school today!');
console.log(`Next school day: ${bell.nextSchoolDay.toLocaleDateString()}`);
}
return { bell };
}
};
Integration with Stores
The Bell class is primarily used through the clock store:
// src/stores/clock.ts
import { defineStore } from 'pinia';
import { computed } from 'vue';
import Bell from '@/utils/bell';
import useScheduleStore from '@/stores/schedules';
export default defineStore('clock', () => {
const scheduleStore = useScheduleStore();
const date = ref(new Date());
const bell = computed((): Bell => {
return new Bell(date.value, scheduleStore.schedules, scheduleStore.scheduleMode);
});
return { bell };
});
Common Patterns
Display Current Period
const bell = new Bell(new Date());
if (isBellOnSchoolDay(bell)) {
if (bell.period.beforeSchool) {
console.log('Before school');
} else if (bell.period.afterSchool) {
console.log('After school');
} else {
console.log(`${bell.getPeriodName()}: ${bell.getRange()}`);
}
}
Countdown Timer
const bell = new Bell(new Date());
const seconds = bell.getSecondsUntilNextTarget();
const hours = Math.floor(seconds / 3600);
const minutes = Math.floor((seconds % 3600) / 60);
if (bell.inSchool) {
console.log(`Period ends in ${minutes} minutes`);
} else {
console.log(`School starts in ${hours}h ${minutes}m`);
}
Check Specific Date
const testDate = new Date('2026-12-25');
const bell = new Bell(testDate);
if (bell.isSchoolDay) {
console.log(`School on Christmas: ${bell.type}`);
} else {
console.log('No school on Christmas');
}