Academic calendar widget
Shows the undergraduate academic events within the next 30 days, ordered by start date. No login is needed.
Request parameters
Section titled “Request parameters”Names follow Python snake_case; Node.js takes a camelCase options object ({ start, end }) and Java takes positional arguments. No login is needed.
| Method | Parameter | Type | Required | Default | Meaning |
|---|---|---|---|---|---|
calendar |
start |
string | Yes | Start date (yyyy-MM-dd) |
|
end |
string | Yes | End date (yyyy-MM-dd) |
||
category_code |
string | No | 0001 |
Category code (0001 undergraduate, 0002 to 0007 graduate) |
|
graduate_calendar |
site_id |
string | Yes | Graduate site name (for example graduate). Passed by the caller, so a new graduate school needs no release |
|
year / month |
integer | Yes | Year / month to fetch |
Response data structure
Section titled “Response data structure”One entry of the list calendar(start, end) returns. Field names are Python snake_case; Node.js uses camelCase (start_date -> startDate) and Java uses getters (getStartDate()). Values only show the shape.
[ { "year": "2026", "month": "3", "category_code": "0001", "category_name": "학부", "title": "2학기 중간고사 성적 입력", "title_en": "Grades input for Fall semester Midterm Examination", "start_date": "2026-03-02", "end_date": "2026-03-08", "extra": {} }]| Field | Meaning |
|---|---|
title / title_en |
Title / English title (school text) |
start_date / end_date |
Start / end date (yyyy-MM-dd for undergraduate; same value for a one-day event) |
year / month |
Year / month the entry belongs to |
category_code / category_name |
Category code / name (0001 is undergraduate) |
extra |
Other school fields (empty for undergraduate events) |
All fields: Academic calendar.
On failure: when the school server fails you get the last cached value or an empty list, without an exception. It looks the same as a period with no events.
Good to know
Section titled “Good to know”- Date formats differ:
yyyy-MM-ddfor undergraduate,MM.ddfor graduate sites. Academic calendar - Opening the widget does not hit the school each time. The same arguments are cached for 24 hours. Failure isolation and cache
- Titles are the school’s own text (Korean). The English title is
title_en/titleEn.
Example code
Section titled “Example code”import java.time.LocalDate;import java.util.List;import kr.suhsaechan.sejongpeia.publicdata.SejongPublicData;import kr.suhsaechan.sejongpeia.publicdata.model.CalendarEvent;
class AcademicCalendarWidget {
static List<CalendarEvent> upcomingAcademicEvents(SejongPublicData publicData, int daysAhead) { LocalDate today = LocalDate.now(); return publicData.calendar(today.toString(), today.plusDays(daysAhead).toString()).stream() .sorted(java.util.Comparator.comparing(CalendarEvent::getStartDate)) .toList(); }}from datetime import date, timedelta
from sejongpeia import SejongPublicData
public_data = SejongPublicData()
def upcoming_academic_events(days_ahead: int = 30) -> list: """Undergraduate events that overlap the next days_ahead days (by start date)""" today = date.today() events = public_data.calendar(today.isoformat(), (today + timedelta(days=days_ahead)).isoformat()) # Dates are yyyy-MM-dd strings from the school, so string order equals date order return sorted(events, key=lambda event: event.start_date)
if __name__ == "__main__": for event in upcoming_academic_events(): period = event.start_date if event.start_date == event.end_date else f"{event.start_date} ~ {event.end_date}" print(f"{period} {event.title}")import { SejongPublicData } from 'pro-sejongpeia';
const publicData = new SejongPublicData();
/** Undergraduate events that overlap the next daysAhead days (by start date) */export async function upcomingAcademicEvents(daysAhead = 30) { const toDateText = (date) => date.toLocaleDateString('sv-SE'); // yyyy-MM-dd (local date) const today = new Date(); const end = new Date(today.getTime() + daysAhead * 24 * 60 * 60 * 1000); const events = await publicData.calendar({ start: toDateText(today), end: toDateText(end) }); // Dates are yyyy-MM-dd strings from the school, so string order equals date order return events.sort((first, second) => first.startDate.localeCompare(second.startDate));}
for (const event of await upcomingAcademicEvents()) { const period = event.startDate === event.endDate ? event.startDate : `${event.startDate} ~ ${event.endDate}`; console.log(`${period} ${event.title}`);}