$CPU 8086 ' make compatible with XT systems $LIB ALL OFF ' turn off all PowerBASIC libraries $ERROR ALL OFF ' turn off all PowerBASIC error checking $OPTIMIZE SIZE ' optimize for smaller code $COMPILE UNIT ' compile to a UNIT (.PBU) '$COMPILE EXE ' compile to a UNIT (.PBU) DEFINT A-Z ' Required for all numeric functions, forces PB to not ' include floating point in UNIT (makes it smaller) '/*------------------------------------------------------------------*/ $CODE SEG "MLIB6" '/*------------------------------------------------------------------*/ DECLARE FUNCTION WORD(BYVAL X AS STRING,XN AS INTEGER) AS STRING DECLARE FUNCTION WORDS(BYVAL X AS STRING) AS INTEGER '/*------------------------------------------------------------------*/ ' DT2JUL("19960201") ' Date to Julian. ' Converts a date string to a seven digit julian number. ' Returned number is double precision. '/*------------------------------------------------------------------*/ '/*--- Converts Date to 7 digit Julian number ---*/ FUNCTION DT2JUL(BYVAL XD AS STRING) PUBLIC AS DOUBLE IF VAL(LEFT$(XD,2)) > 12 THEN J!= VAL(MID$(XD,5,2)) :'/*MONTH K!= VAL(MID$(XD,7,2)) :'/*DAY I!= VAL(MID$(XD,1,4)) :'/*YEAR ELSE J!= VAL(MID$(XD,1,2)) :'/*MONTH K!= VAL(MID$(XD,4,2)) :'/*DAY I!= VAL(MID$(XD,7,4)) :'/*YEAR END IF IF J!> 2 THEN M8!= J!- 3 Y8!= I! ELSE M8!= J!+ 9 Y8!= I!- 1 END IF C8!=INT(Y8!/100) D8!=Y8!-100*C8! N#=INT(146097*C8!/4)+K!+INT(1461*D8!/4)+1721119+INT((153*M8!+2)/5) FUNCTION = N# END FUNCTION '/*------------------------------------------------------------------*/ FUNCTION JUL2DT(BYVAL N AS DOUBLE) PUBLIC AS STRING M8!= N-1721119 I! = INT((4*M8!-1)/146097) M8! = 4*M8!-1-146097*I! K! = INT(M8!/4) M8! = INT((4*K!+3)/1461) K! = 4*K!+3-1461*M8! K! = INT((K!+4)/4) J! = INT((5*K!-3)/153) K! = 5*K!-3-153*J! K! = INT((K!+5)/5) I! = 100*I!+M8! IF J! < 10 THEN J! = J! + 3 ELSE J! = J! - 9 I! = I! + 1 END IF J$ = RIGHT$(STR$(J!),LEN(STR$(J!))-1) IF J! < 10 THEN J$ = "0" + J$ K$ = RIGHT$(STR$(K!),LEN(STR$(K!))-1) IF K! < 10 THEN K$ = "0" + K$ I$ = RIGHT$(STR$(I!),LEN(STR$(I!))-1) IF I! < 10 THEN I$ = "0" + I$ '/* FUNCTION = J$ + "-" + K$ + "-" + I$ FUNCTION = I$ + J$ + K$ END FUNCTION '/*------------------------------------------------------------------*/ FUNCTION DAYOFYR(BYVAL X AS STRING) PUBLIC AS INTEGER I$ = MID$(X,1,4) J$ = MID$(X,5,2) K$ = MID$(X,7,2) I = VAL(I$) J = VAL(J$) K = VAL(K$) N = INT(3055*(J+2)/100)-91 L = 0 IF I = 4*INT(I/4) THEN L = 1 IF I = 100*INT(I/100) THEN L = 0 IF I = 400*INT(I/400) THEN L = 1 IF J > 2 THEN N = N - 2 + L N = N + K DAYOFYR = N END FUNCTION '/*------------------------------------------------------------------*/ FUNCTION WEEKDAY(BYVAL X AS STRING) PUBLIC AS STRING I$ = MID$(X,1,4) J$ = MID$(X,5,2) K$ = MID$(X,7,2) I = VAL(I$) J = VAL(J$) K = VAL(K$) IF J > 2 THEN M8 = J - 2 Y8 = I ELSE M8 = J + 10 Y8 = I - 1 END IF C8 = INT(Y8/100) D8 = Y8-100*C8 N=INT((13*M8-1)/5)+K+D8+INT(D8/4)+INT(C8/4)-C8-C8+77 N=N-7*INT(N/7) IF N = 0 THEN WEEKDAY = "Sunday" IF N = 1 THEN WEEKDAY = "Monday" IF N = 2 THEN WEEKDAY = "Tuesday" IF N = 3 THEN WEEKDAY = "Wednesday" IF N = 4 THEN WEEKDAY = "Thursday" IF N = 5 THEN WEEKDAY = "Friday" IF N = 6 THEN WEEKDAY = "Saturday" END FUNCTION '/*------------------------------------------------------------------*/ ' DSPLIT DATE$, MONTH, DAY, YEAR ' Date Split. ' Splits DATE$ placing MM into MONTH, DD into Day and ' YYYY into YEAR. ' DATE$ MUST be in either MM-DD-YYY or YYYYMMDD format. ' If DATE$ = "" (NULL) then the current system date is used. ' EXAMPLE: DSPLIT DATE$, M, D, Y ' Where DATE$ = "05-17-1996" returns: ' M = 5 ' D = 17 ' Y = 1996 '/*------------------------------------------------------------------*/ SUB DSPLIT(BYVAL InDate AS STRING, Month AS INTEGER, Day AS INTEGER, Year AS INTEGER) PUBLIC '/* --- If Null String use current date ---*/ IF LEN(InDate) = 0 THEN InDate = DATE$ END IF '/* --- Ordered Date? If so, Change it to DATE$ Format ---*/ T$ = LEFT$(InDate,2) T = VAL(T$) IF T > 12 THEN InDate = MID$(InDate,5,2) + "-" + MID$(InDate,7,2) + "-" + LEFT$(InDate,4) END IF '/* --- Split Out Date Components ---*/ Month = VAL(MID$(InDate,1,2)) Day = VAL(MID$(InDate,4,2)) Year = VAL(MID$(InDate,7)) END SUB '/*----------------------------------------------------------------*/ ' DAYS2DT(NUMBER#) ' Returns the date from 7 digit (DOUBLE) julian day NUMBER#. ' EXAMPLE: DAYS2DT(2450323) = "MM-DD-YYYY" '/*----------------------------------------------------------------*/ ' DT2DAYS(DATE$) ' Returns the number of days represented by DATE$ in the ' a seven digit format (DOUBLE). ' DATE$ may be formated as "MM-DD-YYYY" or "YYYYMMDD". ' EXAMPLE: DT2DAYS("19960827) = 2450323 ' DT2DAYS("08-27-1996) = 2450323 '/*----------------------------------------------------------------*/ FUNCTION DT2DAYS(InDate AS STRING) PUBLIC AS DOUBLE DSPLIT InDate, Month, Day, Year T$ = MKDATE(Month, Day, Year) Temp# = DT2JUL(T$) FUNCTION = Temp# END FUNCTION '/*------------------------------------------------------------------*/ FUNCTION DAYS2DT(BYVAL NumDays AS DOUBLE) PUBLIC AS STRING T$ = JUL2DT(NumDays) T$ = MID$(T$,5,2)+"-"+MID$(T$,7,2)+"-"+MID$(T$,1,4) FUNCTION = T$ END FUNCTION '/*------------------------------------------------------------------*/ '/* Days - Return the number of days between two dates. If the first date '/* comes after the second date, a negative value is returned. '/* Date1 = starting date '/* Date2 = ending date FUNCTION NDAYS(BYVAL Date1 AS STRING, BYVAL Date2 AS STRING) PUBLIC AS INTEGER FUNCTION = DT2DAYS(DATE1) - DT2DAYS(DATE2) END FUNCTION '/*------------------------------------------------------------------*/ ' DMATH(DATE$,NBR) ' Date Math. ' Adds specified NBR of days to DATE$. To subtract, use ' a negative number. ' The date is retured as YYYYMMDD. ' EXAMPLE: DMATH("19961019",2) = "19961021" ' EXAMPLE: DMATH("19961019",-2) = "19961017" ' Performs '/*------------------------------------------------------------------*/ '/* DMATH - Add the specified number of days the specified date. '/* To subtract days, use a negative value. FUNCTION DMATH(BYVAL InDate AS STRING, BYVAL NumberOfDays AS INTEGER) PUBLIC AS STRING T$ = DAYS2DT(DT2DAYS(InDate) + NumberOfDays) IF VAL(LEFT$(InDate,2)) > 12 THEN T$ = MID$(T$,7,4)+MID$(T$,1,2)+MID$(T$,4,2) FUNCTION = T$ END FUNCTION '/*------------------------------------------------------------------*/ FUNCTION MKDATE(BYVAL Month AS INTEGER, BYVAL Day AS INTEGER, BYVAL Year AS INTEGER) PUBLIC AS STRING DIM Temp AS STRING Temp = RIGHT$(STR$(Month), 2) + "-" + _ RIGHT$(STR$(Day), 2) + "-" + _ RIGHT$(STR$(Year), 4) REPLACE " " WITH "0" IN Temp FUNCTION = Temp END FUNCTION '/*------------------------------------------------------------------*/ ' DATE(OPT) ' Returns the computer date in the format determined by OPT. ' OPT: A (Absolute) returns a seven digit number. ' B (Back to Date from Absoulte); returns YYYYMMDD ' D (Days); returns the number of days including the ' current day for far in this year in the format 'ddd' ' with no leading zeros or blanks. ' E (European); returns the date in the format dd/mm/yy. ' F (Full); returns date as Dweek Month DD, YYYY ' I returns date as DD MONTH YYYY. ' J returns date as MONTH DD, YYYY. ' K returns date as MMM DD, YYYY. ' L returns date as DDMMMYYYY. ' M (Month); returns the full English name of the current ' month in mixed case with the first letter a capital. ' N (Normal); explicitly returns the date as dd Mmm yyyy. ' O (Ordered); returns the date in the format 'YY/MM/DD' ' suitable for sorting. ' S (Standard); returns the date in the format 'YYYYMMDD' ' again suitable for sorting. ' U (USA); returns the date in the format 'mm/dd/yy'. ' W (Weekday); returns the English name for the day of the ' week in mixed case with the first letter a capital. ' Other Formats: YYYY MM DD ' YYYY-MM-DD ' YYYY/MM/DD ' MM DD YYYY ' MM-DD-YYYY (Power BASIC format) ' MM/DD/YYYY ' ' EXAMPLES: DATE('A') = '2450323' ' DATE('D') = '239' ' DATE('E') = '27/08/96' ' DATE('F') = 'Tuesday August 27,1996' ' DATE('I') = '27 August 1996 ' DATE('J') = 'August 27, 1996 ' DATE('K') = 'Aug 27, 1996 ' DATE('L') = '27Aug1996 ' DATE('M') = 'August' ' DATE('N') = '27 Aug 1989' ' DATE('O') = '89/08/27' ' DATE('S') = '19890827' ' DATE('U') = '08/27/89' ' DATE('W') = 'Saturday' ' DATE('YYYY MM DD') = '1996 08 27' ' DATE('YYYY-MM-DD') = '1996-08-27' ' DATE('YYYY/MM/DD') = '1996/08/27' ' DATE('MM DD YYYY') = '08 27 1996' ' DATE('MM-DD-YYYY') = '08-27-1996' ' DATE('MM/DD/YYYY') = '08/27/1996' '/*------------------------------------------------------------------*/ FUNCTION DATE(BYVAL OPT AS STRING) PUBLIC AS STRING OPT = UCASE$(OPT) D$ = DATE$ DATE = XFORMAT(OPT,D$) END FUNCTION '/*------------------------------------------------------------------*/ ' DFORMAT("19960422", OPT$) ' Date Format. ' Works the same as DATE via the OPT$ string only you supply ' the date with one or two additional options: ' # - Returns the number of days in year/month. ' V - Returns "1" if date is valid, "0" if data is NOT valid. ' Has a separate option to convert a yymmdd format to yyyymmdd ' format for year 2000 conversions. ' EXAMPLE: DFORMAT("11-02-96","Y2K M-D-Y 90 YYYY-MM-DD") = "1996-11-02" ' | | | | | ' | | | | +--- Final format ' | | | +--- Years prior will be 20 ' | | +--- Format of date string ' | +--- Y2K Option switch ' +--- Date to be converted ' ' EXAMPLE: DFORMAT("110296","Y2K MDY 90 YYYY-MM-DD") = "1996-11-02" ' EXAMPLE: DFORMAT("960211","Y2K YMD 90 YYYY-MM-DD") = "1996-11-02" ' EXAMPLE: DFORMAT("96-02-11","Y2K Y-M-D 90 YYYY-MM-DD") = "1996-11-02" ' EXAMPLE: DFORMAT("199702","#") = "28" ' EXAMPLE: DFORMAT("19920201","#") = "29" ' EXAMPLE: DFORMAT("19970201","V") = "1" ' DFORMAT("19970229","V") = "0" ' DFORMAT("19920229","V") = "1" '/*------------------------------------------------------------------*/ FUNCTION DFORMAT(BYVAL X AS STRING, BYVAL OPT AS STRING) PUBLIC AS STRING OPT = UCASE$(OPT) IF OPT = "#" THEN X = X + "00" D$ = MID$(X,5,2) + "-" + MID$(X,7,2) + "-" + MID$(X,1,4) IF OPT = "B" THEN D$ = X IF WORD(OPT,1) = "Y2K" THEN FMT$ = WORD(OPT,2) YB = VAL(WORD(OPT,3)) D$ = Y2K(X,FMT$,YB) IF WORDS(OPT) > 3 THEN OPT4$ = WORD(OPT,4) ELSE OPT4$ = "" IF OPT4$ <> "" THEN OPT = OPT4$ ELSE OPT = "MM-DD-YYY" END IF DFORMAT = XFORMAT(OPT,D$) END FUNCTION '/*------------------------------------------------------------------*/ FUNCTION VDATE(BYVAL DATECHECK$) PUBLIC AS INTEGER ' Returns 1 if Valid Date, 0 if not ' No modifications are made to DateCheck$ ' This function is aware of leap years ' Requires DateCheck$ to be in "YYYYMMDD" (Year,Month,Day) Format ' Requires FUNCTION DaysInMonth VD = 0 IF LEN(DATECHECK$) <> 8 THEN EXIT FUNCTION 'CHECK FULL DATE IF VAL(LEFT$(DATECHECK$,4)) > 999 AND _ 'IF VALID YEAR VAL(LEFT$(DATECHECK$,4)) < 10000 THEN IF VAL(MID$(DATECHECK$,5,2)) > 0 AND _ 'IF VALID MONTH VAL(MID$(DATECHECK$,5,2)) < 13 THEN IF VAL(RIGHT$(DATECHECK$,2)) > 0 AND _ 'IF VALID DAY VAL(RIGHT$(DATECHECK$,2)) <= _ 'FOR THE ABOVE DAYSINMONTH(VAL(LEFT$(DATECHECK$,4)), _ 'MONTH & YEAR VAL(MID$(DATECHECK$,5,2))) THEN VD = 1 END IF END IF END IF FUNCTION = VD END FUNCTION '/*------------------------------------------------------------------*/ ' DAYSINMONTH(YEAR,MONTH) ' Returns the number of days in a month. ' EXAMPLE: DAYSINMONTH(1997,02) = 28 ' DAYSINMONTH(1992,02) = 29 ' DAYSINMONTH(1997,01) = 31 ' DAYSINMONTH(1997,04) = 30 '/*------------------------------------------------------------------*/ FUNCTION DAYSINMONTH(BYVAL Year AS INTEGER, BYVAL Month AS INTEGER) PUBLIC AS INTEGER ' Returns the number of Days in the Month ' No modifications are made to Year or Month ' Year info must be in full ie. 1993 NOT 93 ' This function is aware of leap years ' Example PRINT DaysInMonth(1993,2) prints to the screen 28 ' Example PRINT DaysInMonth(1992,2) prints to the screen 29 ' 1992 was a Leap Year DM = 0 ' IF Year < 1000 THEN EXIT FUNCTION SELECT CASE Month CASE 2 IF (Year / 4) - FIX(Year / 4) = 0 THEN 'Leap Year DM = 29 ELSE 'Non-Leap Year DM = 28 END IF CASE 4, 6, 9, 11 DM = 30 CASE ELSE DM = 31 END SELECT FUNCTION = DM END FUNCTION '/*------------------------------------------------------------------*/ FUNCTION Y2K(BYVAL X AS STRING, BYVAL OPT AS STRING, BYVAL YB AS INTEGER) AS STRING IF OPT = "YMD" THEN YS = 1 MS = 3 DS = 5 END IF IF OPT = "Y-M-D" THEN YS = 1 MS = 4 DS = 7 END IF IF OPT = "MDY" THEN YS = 5 MS = 1 DS = 3 END IF IF OPT = "M-D-Y" THEN YS = 7 MS = 1 DS = 4 END IF Y = VAL(MID$(X,YS,2)) M = VAL(MID$(X,MS,2)) D = VAL(MID$(X,DS,2)) IF Y < YB THEN Y = Y + 2000 ELSE Y = Y + 1900 T$ = MKDATE(M,D,Y) FUNCTION = T$ END FUNCTION '/*------------------------------------------------------------------*/ FUNCTION XFORMAT(BYVAL OPT AS STRING, BYVAL D AS STRING) PUBLIC AS STRING OPT = UCASE$(OPT) DT$ = D M$ = MID$(DT$,1,2) D$ = MID$(DT$,4,2) Y$ = MID$(DT$,7,4) DA$ = Y$ + M$ + D$ '/* --- Absolute Day Number? ---*/ IF OPT = "A" THEN T# = DT2JUL(DA$) XRET$ = STR$(T#) END IF '/* --- Return to Date? ---*/ IF OPT = "B" THEN T# = VAL(DT$) XRET$ = JUL2DT(T#) END IF '/* --- Day of the Year ---*/ IF OPT = "D" THEN T = DAYOFYR(DA$) XRET$ = STR$(T) XRET$ = RIGHT$(XRET$,LEN(XRET$)-1) END IF '/* --- # Days in Month ---*/ IF OPT = "#" THEN XRET$ = LTRIM$(STR$(DAYSINMONTH(VAL(Y$),VAL(M$)))) END IF '/* --- Valid Date ---*/ IF OPT = "V" THEN XRET$ = LTRIM$(STR$(VDATE(Y$+M$+D))) END IF '/* --- Month Name ---*/ S = INSTR(1,"FMNIJKL",OPT) IF S > 0 THEN IF M$ = "01" THEN XRET$ = "January" IF M$ = "02" THEN XRET$ = "February" IF M$ = "03" THEN XRET$ = "March" IF M$ = "04" THEN XRET$ = "April" IF M$ = "05" THEN XRET$ = "May" IF M$ = "06" THEN XRET$ = "June" IF M$ = "07" THEN XRET$ = "July" IF M$ = "08" THEN XRET$ = "August" IF M$ = "09" THEN XRET$ = "September" IF M$ = "10" THEN XRET$ = "October" IF M$ = "11" THEN XRET$ = "November" IF M$ = "12" THEN XRET$ = "December" END IF '/* --- Special Formats ---*/ IF OPT = "YYYY MM DD" THEN XRET$ = Y$ + " " + M$ + " " + D$ IF OPT = "YYYY" THEN XRET$ = Y$ IF OPT = "MM" THEN XRET$ = M$ IF OPT = "DD" THEN XRET$ = D$ IF OPT = "YYYY-MM-DD" THEN XRET$ = Y$ + "-" + M$ + "-" + D$ IF OPT = "YYYY/MM/DD" THEN XRET$ = Y$ + "-" + M$ + "-" + D$ IF OPT = "MM DD YYYY" THEN XRET$ = M$ + " " + D$ + " " + Y$ IF OPT = "MM-DD-YYYY" THEN XRET$ = M$ + "-" + D$ + "-" + Y$ IF OPT = "MM/DD/YYYY" THEN XRET$ = M$ + "/" + D$ + "/" + Y$ IF OPT = "F" THEN XRET$ = WEEKDAY(DA$) + " " + XRET$ + " " + D$ + "," + Y$ IF OPT = "I" THEN XRET$ = D$ + " " + XRET$ + " " + Y$ IF OPT = "J" THEN XRET$ = XRET$ + " " + D$ + "," + Y$ IF OPT = "K" THEN XRET$ = LEFT$(XRET$,3) + " " + D$ + "," + Y$ IF OPT = "L" THEN XRET$ = D$ + LEFT$(XRET$,3) + Y$ IF OPT = "E" THEN XRET$ = D$ + "/" + M$ + "/" + Y$ IF OPT = "O" THEN XRET$ = RIGHT$(Y$,2) + "/" + M$ + "/" + D$ IF OPT = "U" THEN XRET$ = M$ + "/" + D$ + "/" + RIGHT$(Y$,2) IF OPT = "S" THEN XRET$ = DA$ IF OPT = "N" THEN XRET$ = D$ + " " + LEFT$(XRET$,3) + " " + Y$ IF OPT = "W" THEN XRET$ = WEEKDAY(DA$) XFORMAT = XRET$ END FUNCTION '/*------------------------------------------------------------------*/ ' $INCLUDE "C:\CODE\MLIB\MLIB.INC" ' CLS ' PRINT "199701 = " DFORMAT("199701","#") ' PRINT "199202 = " DFORMAT("199202","#") ' INPUT Z ' PRINT "1B970201 = " DFORMAT("1B970201","V") ' PRINT "19970133 = " DFORMAT("19970133","V") ' PRINT "19970229 = " DFORMAT("19970229","V") ' INPUT Z ' PRINT "Y2K 11-02-96" ' PRINT DFORMAT("961102","Y2K YMD 90 YYYY-MM-DD") ' PRINT NDAYS("19960501","19960520") ' PRINT DATE$" + 2 = "DMATH("19960520",2) ' PRINT DATE$" - 2 = "DMATH("19960520",-2) ' PRINT "19961019 + 2 = "DMATH("19961019",2) ' PRINT "19961019 - 2 = "DMATH("19961019",-2) ' PRINT DATE("A");" ABSOLUTE DAY NUMBER A" ' PRINT DFORMAT("19960827","A") ' PRINT DFORMAT("19960827","A") ' PRINT DFORMAT("2450323","B") ' PRINT DATE("D");" IS THE DAY OF THE YEAR D" ' PRINT DATE("E");" IS THE EUROPEAN DATE E" ' PRINT DATE("F");" IS THE FULL DATE F" ' PRINT DATE("I");" IS THE DD MONTH YYYY I" ' PRINT DATE("J");" IS THE Month DD, YYYY J" ' PRINT DATE("K");" IS THE Mmm DD, YYYY K" ' PRINT DATE("L");" IS THE LDS FORMAT L" ' PRINT DATE("M");" IS THE MONTH M" ' PRINT DATE("N");" IS THE NORMAL DATE N" ' PRINT DATE("O");" IS THE Ordered DATE O" ' PRINT DATE("S");" IS THE Standard DATE S" ' PRINT DATE("U");" IS THE Standard DATE U" ' PRINT DATE("W");" IS THE Weekday W" ' INPUT Z ' PRINT DATE("YYYY MM DD");" YYYY MM DD" ' PRINT DATE("YYYY-MM-DD");" YYYY-MM-DD" ' PRINT DATE("YYYY/MM/DD");" YYYY/MM/DD" ' PRINT DATE("MM DD YYYY");" MM DD YYYY" ' PRINT DATE("MM-DD-YYYY");" MM-DD-YYYY" ' PRINT DATE("MM/DD/YYYY");" MM/DD/YYYY" ' PRINT DFORMAT("19961019","L") ' PRINT DFORMAT("19961019","W") ' INPUT Z