import { addWeeks , startOfWeek , isBefore , getYear } from 'date-fns' ; import { WeekType , Semester , AcadYear , AcadWeek , AcadWeekInfo } from './types' ; param acadYear return { Date } export function getAcadYearStartDate ( acadYear ) { const shortYear = acadYear . split ( '/' ) [ 0 ] ; const targetYear = 2000 + parseInt ( shortYear , 10 ) ; const firstDateOfMonth = new Date ( targetYear , 7 , 1 , 0 , 0 , 0 ) ; const nearestMonday = startOfWeek ( firstDateOfMonth , { weekStartsOn : 1 } ) ; if ( isBefore ( nearestMonday , firstDateOfMonth ) ) { const firstMonday = addWeeks ( nearestMonday , 1 ) ; return firstMonday ; } return nearestMonday ; } const oneWeekDuration = 1000 * 60 * 60 * 24 * 7 ; const sem1 = 'Semester 1' ; const sem2 = 'Semester 2' ; const special1 = 'Special Term I' ; const special2 = 'Special Term II' ; param { Date } date return { Object } export function getAcadYear ( date ) { const shortYear = getYear ( date ) % 100 ; const potentialAcadYear = `${ shortYear }/${ shortYear + 1 }` ; const potentialStartDate = getAcadYearStartDate ( potentialAcadYear ) ; const year = isBefore ( date , potentialStartDate ) ? `${ shortYear - 1 }/${ shortYear }` : potentialAcadYear ; return { year , startDate : getAcadYearStartDate ( year ) , } ; } param { number } acadWeekNumber return { string } example export function getAcadSem ( acadWeekNumber ) { const earliestSupportedWeek = 1 ; const lastWeekOfSem1 = 23 ; const lastWeekOfSem2 = 40 ; const lastWeekOfSpecialSem1 = 46 ; const lastWeekOfSpecialSem2 = 52 ; if ( acadWeekNumber < earliestSupportedWeek ) { console . warn ( `[nusmoderator] Unsupported acadWeekNumber: ${ acadWeekNumber }` ) ; return null ; } if ( acadWeekNumber <= lastWeekOfSem1 ) return sem1 ; if ( acadWeekNumber <= lastWeekOfSem2 ) return sem2 ; if ( acadWeekNumber <= lastWeekOfSpecialSem1 ) return special1 ; if ( acadWeekNumber <= lastWeekOfSpecialSem2 ) return special2 ; console . warn ( `[nusmoderator] Unsupported acadWeekNumber: ${ acadWeekNumber }` ) ; return null ; } param { number } acadWeekNumber return { string } example export function getAcadWeekName ( acadWeekNumber ) { switch ( acadWeekNumber ) { case 7 : return { weekType : 'Recess' , weekNumber : null , } ; case 15 : return { weekType : 'Reading' , weekNumber : null , } ; case 16 : case 17 : return { weekType : 'Examination' , weekNumber : acadWeekNumber - 15 , } ; default : { let weekNumber = acadWeekNumber ; if ( weekNumber >= 8 ) { weekNumber -= 1 ; } if ( acadWeekNumber < 1 || acadWeekNumber > 17 ) { console . warn ( `[nusmoderator] Unsupported acadWeekNumber as parameter: ${ acadWeekNumber }` ) ; return null ; } return { weekType : 'Instructional' , weekNumber , } ; } } } param { Date } date return { Object } export function getAcadWeekInfo ( date ) { const currentAcad = getAcadYear ( date ) ; const acadYear = currentAcad . year ; const acadYearStartDate = getAcadYearStartDate ( acadYear ) ; let acadWeekNumber = Math . ceil ( ( date . getTime ( ) - acadYearStartDate . getTime ( ) + 1 ) / oneWeekDuration ) ; const semester = getAcadSem ( acadWeekNumber ) ! ; let weekType = null ; let weekNumber = null ; switch ( semester ) { case sem2 : acadWeekNumber -= 22 ; case sem1 : if ( acadWeekNumber === 1 ) { weekType = 'Orientation' ; break ; } if ( acadWeekNumber > 18 ) { weekType = 'Vacation' ; weekNumber = acadWeekNumber - 18 ; break ; } acadWeekNumber -= 1 ; const acadWeek = getAcadWeekName ( acadWeekNumber ) ! ; weekType = acadWeek . weekType ; weekNumber = acadWeek . weekNumber ; break ; case special2 : acadWeekNumber -= 6 ; case special1 : acadWeekNumber -= 40 ; weekType = 'Instructional' ; weekNumber = acadWeekNumber ; break ; default : if ( acadWeekNumber === 53 ) { weekType = 'Vacation' ; weekNumber = null ; } break ; } return { year : acadYear , sem : semester , type : weekType as WeekType | null , num : weekNumber , } ; } param { string } year param { number } semester returns { Date } export function getExamWeek ( year , semester ) { const startDate = getAcadYearStartDate ( year ) ; if ( ! startDate ) { console . warn ( `[nusmoderator] Unsupported year: ${ year }` ) ; return null ; } const examWeek = { 1 : 16 , 2 : 38 , 3 : 45 , 4 : 51 , } ; const weeks = examWeek [ semester ] ; if ( ! weeks ) { console . warn ( `[nusmoderator] Unknown semester: ${ semester }` ) ; return null ; } const d = new Date ( startDate . valueOf ( ) ) ; d . setDate ( startDate . getDate ( ) + weeks * 7 ) ; return d ; } export default { getAcadYearStartDate , getAcadYear , getAcadSem , getAcadWeekName , getAcadWeekInfo , getExamWeek , } ;