/*              
    SCANTD.C    Convert ASCII times and dates to binary

    by Ray Duncan, February 1988
*/

#include <stdio.h>
#include <dos.h>

union REGS regs;

                                    /* function prototypes */
static void getctry(void);      
int scantime(char *, int *, int *, int *);
int scandate(char *, int *, int *, int *);


                                    /* table of days of the month */

static int dom[] = {   31,          /* January   */
                       28,          /* February  */
                       31,          /* March     */
                       30,          /* April     */
                       31,          /* May       */
                       30,          /* June      */
                       31,          /* July      */
                       31,          /* August    */
                       30,          /* September */
                       31,          /* October   */
                       30,          /* November  */
                       31 };        /* December  */

static char cbuff[34];              /* receives country info */

static int cflag = 0;               /* true if country info */
                                    /* present in cbuff */



/*
    Convert ASCII string into binary hour, minute, and second.
*/

int scantime(char *timestr, int *hour, int *min, int *sec)
{   
    *hour = *min = -1;              /* force hours and minutes 
                                       to be entered */

    *sec = 0;                       /* allow seconds to default
                                       to zero */

                                    /* validate time string */

    if( strspn(timestr,"0123456789:") != strlen(timestr) )

        return(0);                  /* exit if bad characters */

                                    /* convert fields of input 
                                       using ':' as delimiter  */

    sscanf(timestr, "%d:%d:%d", hour, min, sec);

                                    /* check all results against
                                       allowed values and return
                                       flag for overall conversion */

    return( ( ( *hour>=0 ) && ( *hour<24  ) )  &&
            ( ( *min>=0  ) && ( *min<60   ) )  &&
            ( ( *sec>=0  ) && ( *sec<60   ) ) );
}

  
/*
    Convert ASCII string into binary month, day, and year.
*/

int scandate(char *datestr, int *month, int *day, int *year)
{
    char sep1[2],sep2[2];           /* these little arrays receive
                                       date separators from scanf */

    *month = *day = *year = -1;     /* user must enter all fields */

                                    /* now validate date string */

    if( strspn(datestr,"0123456789/-.") != strlen(datestr) )

        return(0);                  /* exit if bad characters */

    getctry();                      /* get country info */


                                    /* convert fields of input 
                                       according to current 
                                       country, using '-', '/',
                                       or '.' as delimiter  */

    switch(cbuff[0])                /* switch on date code */
    {
        case 0:                     /* USA: m d y */
        sscanf(datestr, "%d%1s%d%1s%d", month, sep1, day, sep2, year);
        break;

        case 1:                     /* Europe: d m y */
        sscanf(datestr, "%d%1s%d%1s%d", day, sep1, month, sep2, year);
        break;

        case 2:                     /* Japan: y m d */
        sscanf(datestr, "%d%1s%d%1s%d", year, sep1, month, sep2, day);
        break;
    }

                                    /* allow entry of complete year
                                       and correct it if necessary */

    if( (*year>=1980) && (*year<=1999) ) *year-=1900;

                                    /* set up days of month table */
    if( (*year%4) == 0 )            /* if leap year ...           */
         dom[1] = 29;               /* then February = 29 days    */
    else dom[1] = 28;               /* else February = 28 days    */

                                    /* check all results against 
                                       allowed values and return 
                                       flag for overall conversion */

    return( ( ( *month>0  ) && ( *month<=12 ) )  &&
            ( ( *day>0    ) && ( *day<=dom[*month-1] ) )  &&
            ( ( *year>=80 ) && ( *year<=99  ) ) );
}


/*
    Get MS-DOS internationalization information into
    'cbuff', or provide default information.
*/

static void getctry(void)
{   
    int dosver;

    if(cflag) return;               /* exit if information 
                                       already in buffer */

    memset(cbuff,0,34);             /* initialize buffer */

    regs.x.ax = 0x3000;             /* get MS-DOS version */
    int86(0x21, &regs, &regs);
    dosver = regs.h.al;

    if(dosver >= 2)                 /* if MS-DOS 2.x or 3.x */
    {                               /* get country info */
        (char *) regs.x.dx = cbuff;
        regs.x.ax = 0x3800;
        int86(0x21, &regs, &regs);
    }

    if(dosver <= 2)                 /* if MS-DOS 1.x or 2.x */
    {                               /* force delimiter info */
        cbuff[9]  = '.';            /* decimal separator */
        cbuff[11] = '/';            /* date separator */
        cbuff[13] = ':';            /* time separator */
    }

    cflag = -1;                     /* we've been here before */
}


