As we were talking on Discord, it'd be nice if there was some function to easily format a date to the proper localization. (month-day-year vs day-month-year, for example)
Well, now there is!
Well, now there is!
Code: (Select All)
PRINT UniDate$("mm/dd/yyyy", DATE$)
PRINT UniDate$("w, MM dd, YYYY", DATE$)
PRINT UniDate$("W, MM DD, YYYY", DATE$)
PRINT UniDate$("dd/mm/yyyy", DATE$)
PRINT UniDate$("W, E D, YYYY", DATE$)
PRINT UniDate$("mm-dd-yy", DATE$)
FUNCTION UniDate$ (format$, userdate$)
'some basic documentation for formatting:
'dates sent via userdate$ should be in the standardized QB64 DATE$ format -- MM/DD/YYYY
'To customize your return date format, use the following syntax
'w = short weekday names. (Mon, Tue, Wed, Thu, Fri, Sat, Sun)
'W = long weekday names. (Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday)
'E = Extended month names. (January, February, March....)
'M = long month names. (Jan, Feb, Mar...)
'm = short month names. (01, 02, 03...)
'D = long day names. (01st, 02nd, 03rd...)
'd = short day names. (01, 02, 03...)
'Y or y (case insensitive) = year. Number of Yy present determines the number of digits we return.
' YY = 2-digit year
' YYYY = 4 digit year
' Y with any additional number of y's = 4 digit year by default, so a typo of YYYYY is the same as YYYY.
'Any other character is simply considered part of the desired output and faithfully carried over into the proper spot.
' For example, "mm/dd/yyyy" gives us "02/10/2023" for Feb 10th, 2023.
' Second example, "dd.mm.yyyy" gives us "10.02.2023" for the same date.
' Third example, "dd EE YYYY" gives us "02 February 2023" for that same date.
'Note: Extra digits of most of these codes are simply ignored for error proofing purposes, with only the initial code being accepted.
' For example "mM YYYY" is actually processed as a simple "m YYYY". The process won't mix short, long, or extended results.
' Also for example, "m YY" is the *exact* same as "mm YY".
' Feel free to use extra digits as you desire to help you keep track of positional spacing in your format string.
' Even though "M D, yyyy" may process the same as "MMM DDDD, YYYY", the second may work better for you if you're trying to track
' position of formatted objects. (The output would be "Feb 10th, 2023", and those extra characters help hold that
' positioning for us easily.)
'And, I think that's it. Enjoy, guys!
temp$ = userdate$
IF temp$ = "" THEN temp$ = DATE$
m$ = LEFT$(temp$, 2)
d$ = MID$(temp$, 4, 2)
y$ = RIGHT$(temp$, 4)
temp$ = format$
DO
firstchar$ = LEFT$(temp$, 1)
SELECT CASE firstchar$
CASE "E" 'extended month
temp$ = MID$(temp$, 2)
IF NOT MonthSet THEN
MonthSet = -1
SELECT CASE VAL(m$)
CASE 1: out$ = out$ + "January"
CASE 2: out$ = out$ + "February"
CASE 3: out$ = out$ + "March"
CASE 4: out$ = out$ + "April"
CASE 5: out$ = out$ + "May"
CASE 6: out$ = out$ + "June"
CASE 7: out$ = out$ + "July"
CASE 8: out$ = out$ + "August"
CASE 9: out$ = out$ + "September"
CASE 10: out$ = out$ + "October"
CASE 11: out$ = out$ + "November"
CASE 12: out$ = out$ + "December"
END SELECT
END IF
CASE "M" 'long month
temp$ = MID$(temp$, 2)
IF NOT MonthSet THEN
MonthSet = -1
SELECT CASE VAL(m$)
CASE 1: out$ = out$ + "Jan"
CASE 2: out$ = out$ + "Feb"
CASE 3: out$ = out$ + "Mar"
CASE 4: out$ = out$ + "Apr"
CASE 5: out$ = out$ + "May"
CASE 6: out$ = out$ + "Jun"
CASE 7: out$ = out$ + "Jul"
CASE 8: out$ = out$ + "Aug"
CASE 9: out$ = out$ + "Sep"
CASE 10: out$ = out$ + "Oct"
CASE 11: out$ = out$ + "Nov"
CASE 12: out$ = out$ + "Dec"
END SELECT
END IF
CASE "m" 'short month
temp$ = MID$(temp$, 2)
IF NOT MonthSet THEN
MonthSet = -1
SELECT CASE VAL(m$)
CASE 1: out$ = out$ + "01"
CASE 2: out$ = out$ + "02"
CASE 3: out$ = out$ + "03"
CASE 4: out$ = out$ + "04"
CASE 5: out$ = out$ + "05"
CASE 6: out$ = out$ + "06"
CASE 7: out$ = out$ + "07"
CASE 8: out$ = out$ + "08"
CASE 9: out$ = out$ + "09"
CASE 10: out$ = out$ + "10"
CASE 11: out$ = out$ + "11"
CASE 12: out$ = out$ + "12"
END SELECT
END IF
CASE "D" 'long day
temp$ = MID$(temp$, 2)
IF NOT DaySet THEN
DaySet = -1
out$ = out$ + RIGHT$("00" + _TRIM$(d$), 2)
SELECT CASE VAL(d$)
CASE 1, 11, 21, 31: out$ = out$ + "st"
CASE 2, 22: out$ = out$ + "nd"
CASE 3, 23: out$ = out$ + "rd"
CASE ELSE: out$ = out$ + "th"
END SELECT
END IF
CASE "d" 'short day
temp$ = MID$(temp$, 2)
IF NOT DaySet THEN
DaySet = -1
out$ = out$ + RIGHT$("00" + _TRIM$(d$), 2)
END IF
CASE "W" 'long weekday
temp$ = MID$(temp$, 2)
IF NOT WeekdaySet THEN
GOSUB getday
SELECT CASE result
CASE 0: Day$ = "Saturday"
CASE 1: Day$ = "Sunday"
CASE 2: Day$ = "Monday"
CASE 3: Day$ = "Tuesday"
CASE 4: Day$ = "Wednesday"
CASE 5: Day$ = "Thursday"
CASE 6: Day$ = "Friday"
END SELECT
out$ = out$ + Day$
END IF
CASE "w" 'short weekday
temp$ = MID$(temp$, 2)
IF NOT WeekdaySet THEN
GOSUB getday
SELECT CASE result
CASE 0: Day$ = "Sat"
CASE 1: Day$ = "Sun"
CASE 2: Day$ = "Mon"
CASE 3: Day$ = "Tue"
CASE 4: Day$ = "Wed"
CASE 5: Day$ = "Thr"
CASE 6: Day$ = "Fri"
END SELECT
out$ = out$ + Day$
END IF
CASE "Y", "y" 'year
IF NOT YearSet THEN
YearSet = -1
IF LEFT$(UCASE$(temp$), 4) = "YYYY" THEN
temp$ = MID$(temp$, 5)
out$ = out$ + y$
ELSEIF LEFT$(UCASE$(temp$), 2) = "YY" THEN
temp$ = MID$(temp$, 3)
out$ = out$ + RIGHT$(y$, 2)
ELSE
temp$ = MID$(temp$, 2)
out$ = out$ + y$
END IF
ELSE
temp$ = MID$(temp$, 2)
END IF
CASE ELSE 'seperator
temp$ = MID$(temp$, 2)
out$ = out$ + firstchar$
END SELECT
LOOP UNTIL temp$ = ""
UniDate$ = out$
EXIT FUNCTION
getday:
WeekdaySet = -1
'From Zeller's congruence: https://en.wikipedia.org/wiki/Zeller%27s_congruence
mm = VAL(m$): dd = VAL(d$): yyyy = VAL(y$)
IF mm < 3 THEN mm = mm + 12: yyyy = yyyy - 1
century = yyyy MOD 100
zerocentury = yyyy \ 100
result = (dd + INT(13 * (mm + 1) / 5) + century + INT(century / 4) + INT(zerocentury / 4) + 5 * zerocentury) MOD 7
RETURN
END FUNCTION