;+
; NAME:
;    day_of_week
;
; PURPOSE:
;    This function determines the weekday for a given date.
;
; CATEGORY:
;    Calendar
;
; CALLING SEQUENCE:
;    result = day_of_week( date_in )
;
; INPUTS:
;    DATE_IN:  The required input date, as a scalar or vector string of format 
;        'yyyymmdd'.
;
; KEYWORD PARAMETERS:
;    ABBREVIATE:  If set, then the abbreviated weekday name is returned, for 
;        instance "Mon" for "Monday".
;    CALENDAR:  The optional name of the calendar to use.  See 
;        convert_time_format.pro for supported values.  The default is 
;        'gregorian'.
;
; USES:
;    convert_time_format.pro
;
; PROCEDURE:
;    This function determines the day of the week by taking mod since of the 
;    days since a reference Monday.
;
; EXAMPLE:
;    ; Determine the day of 1 January 2026 (Thursday).
;    print, day_of_week( '20260101' )
;
; MODIFICATION HISTORY:
;    Written by:  Daithi A. Stone (dastone@runbox.com), 2026-02-21
;-

;***********************************************************************

FUNCTION DAY_OF_WEEK, $
    DATE_IN, $
    CALENDAR=calendar, $
    ABBREVIATE=abbreviate_opt

;***********************************************************************
; Constants and options

; Determine the number of requested dates
n_date = n_elements( date_in )
if n_date eq 0 then stop

; The option to abbreviate day names
abbreviate_opt = keyword_set( abbreviate_opt )

; The names of the days of the week
if abbreviate_opt eq 1 then begin
  day_name = [ 'Mon', 'Tues', 'Wed', 'Thurs', 'Fri', 'Sat', 'Sun' ]
endif else begin
  day_name = [ 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', $
      'Saturday', 'Sunday' ]
endelse

; A reference Monday (2 February 2026)
ref_date = '2026-02-02'

;***********************************************************************
; Determine the weekday(s) for the date(s)

; Put dates in ascending order (needed by convert_time_format.pro)
if n_date gt 0 then begin
  id_sort = sort( date_in )
  date_in = date_in[id_sort]
endif

; Determine the number of days since ref_day
temp = 'days since ' + ref_date + 'T00:00:00'
days_since = convert_time_format( date_in, 'yyyymmdd', temp, calendar=calendar )
days_since = round( days_since )

; Return dates to original order
if n_date gt 0 then begin
  temp = date_in
  date_in[id_sort] = temp
  temp = days_since
  days_since[id_sort] = temp
endif

; Ensure days_since is positive
temp = min( days_since )
if temp lt 0 then begin
  temp = abs( round( floor( temp / 7. ) * 7 ) )
  days_since = days_since + temp
endif

; Determine day of week
index = days_since mod 7
day_out = day_name[index]
if n_date eq 1 then day_out = day_out[0]

;***********************************************************************
; The end

return, day_out
END
