/***************************************************************************
 *                                                                         *
 *   VBDATIM.C                                                             *
 *                                                                         *
 *   Copyright (c) 1994-1997 Galacticomm, Inc.    All rights reserved.     *
 *                                                                         *
 *   These are routines for converting VB double-precision format dates    *
 *   into either DOS packed integer format dates and times or directly     *
 *   into strings, and for converting DOS format and string format dates   *
 *   and times into VB double-precision format.                            *
 *                                                                         *
 *                                                - Bill Hyatt 8/9/94      *
 *                                                                         *
 ***************************************************************************/

#include "gcomm.h"

#define FILREV "$Revision: 9 $"

#ifdef GCMVC
/* MSVC++ generates spurrious "overflow in floating-point constant         */
/* arithmetic" when referencing VBBDAT; this turns the warning off.        */
#pragma warning(disable:4056)
#endif // GCMVC

static VOID exthms(DOUBLE vbdat,INT *pHour,INT *pMin,LONG *pSec);
static VOID extymd(DOUBLE vbdat,INT *pYear,INT *pMonth,INT *pDay);

INT century;                       /* 19-22 - century ind. for stg funcs    */

static INT daymon[]={0,31,59,90,120,151,181,212,243,273,304,334};
                                   /* # days in prev months for ea. month   */

USHORT                             /*   returns DOS packed int date        */
v2ddat(                            /* convert VB date to DOS packed int dat*/
DOUBLE vbdat)                      /*   VB DOUBLE precision date/time      */
{
     DOUBLE whlprt;

     if (vbdat < DOSBVB || vbdat > DOSMVB) {
          return(0);
     }
     modf(vbdat,&whlprt);
     return(datofc((USHORT)(atoi(spr("%lf",whlprt))-DOSBVB)));
}

USHORT                             /*   returns DOS packed int time        */
v2dtim(                            /* convert VB time to DOS packed int tim*/
DOUBLE vbdat)                      /*   VB DOUBLE precision date/time      */
{
     INT hour,minute;
     LONG sec;

     exthms(vbdat,&hour,&minute,&sec);
     if (hour > 23 || minute > 59 || sec > 59) {
          return(0);
     }
     return(dttime(hour,minute,(INT)sec));
}

const CHAR *                       /*   returns ptr to MM/DD/YY            */
v2sdat(                            /* convert VB date to stg "MM/DD/YY"    */
DOUBLE vbdat)                      /*   VB DOUBLE precision date/time      */
                                   /*   implicit output: century           */
{
     INT year,month,day;
     static CHAR buff[sizeof("MM/DD/YY")];

     if (vbdat < VBBDAT || vbdat > VBMDAT) {
          return("");
     }
     extymd(vbdat,&year,&month,&day);
     century=(year-VBBYR)/100+19;
     sprintf(buff,"%02d/%02d/%02d",month,day,year%100);
     return(buff);
}

const CHAR *                       /*   returns ptr to MM/DD/YYYY          */
v2sdatl(                           /* convert VB date to stg "MM/DD/YYYY"  */
DOUBLE vbdat)                      /*   VB DOUBLE precision date/time      */
{
     INT year,month,day;
     static CHAR buff[sizeof("MM/DD/YYYY")];

     if (vbdat < VBBDAT || vbdat > VBMDAT) {
          return("");
     }
     extymd(vbdat,&year,&month,&day);
     sprintf(buff,"%02d/%02d/%04d",month,day,year);
     return(buff);
}

const CHAR *                       /*   returns ptr to HH:MM:SS            */
v2stim(                            /* convert VB time to stg "HH:MM:SS"    */
DOUBLE vbdat)                      /*   VB DOUBLE-precision date/time      */
{
     INT hour,minute;
     LONG sec;
     static CHAR buff[sizeof("HH:MM:SS")];

     if (vbdat < 0.0) {
          return("");
     }
     exthms(vbdat,&hour,&minute,&sec);
     if (hour > 23 || minute > 59 || sec > 59) {
          return("");
     }
     sprintf(buff,"%02d:%02d:%02d",hour,minute,(INT)sec);
     return(buff);
}

DOUBLE                             /*   returns date/time in VB format     */
d2vdat(                            /* convert DOS date/time to VB format   */
USHORT dosdat,                     /*   DOS packed integer date            */
USHORT dostim)                     /*   DOS packed integer time            */
{
     return((DOUBLE)(DOSBVB+cofdat(dosdat)
                    +dthour(dostim)/24.0
                    +dtmin(dostim)/1440.0
                    +dtsec(dostim)/86400.0));
}

DOUBLE                             /*   returns date/time in VB format     */
s2vdat(                            /* convert string date/time to VB format*/
const CHAR *stgdat,                /*   date string in form "MM/DD/YY[YY]" */
const CHAR *stgtim)                /*   time string in form "HH:MM:SS"     */
{
     INT month,day,year,hour,minute,sec;
     LONG days;
     DOUBLE time;

     if (NULSTR(stgdat)) {
          days=0L;
     }
     else {
          year=month=day=0;
          sscanf(stgdat,"%d/%d/%d",&month,&day,&year);
          if (year < 100) {
               year+=THSCEN;
          }
          else if (year < VBBYR) {
               year=VBBYR;
          }
          else if (year > VBMYR) {
               year=VBMYR;
          }
          if (month > 12) {
               month=12;
          }
          else if (month < 1) {
               month=1;
          }
          days=difYear(VBBYR,year);
          days+=daymon[month-1]+(day-1);
          if (isLeapYear(year) && month > 2) {
               ++days;
          }
     }
     if (NULSTR(stgtim)) {
          time=0.0;
     }
     else {
          hour=minute=sec=0;
          sscanf(stgtim,"%d:%d:%d",&hour,&minute,&sec);
          time=(DOUBLE)(hour/24.0+minute/1440.0+sec/86400.0);
     }
     return((DOUBLE)(VBBDAT+days+time));
}

static VOID
extymd(                            /* extract year,month,day from VB time  */
DOUBLE vbdat,                      /*   VB DOUBLE-precision date/time      */
INT *pYear,                        /*   where to put the year              */
INT *pMonth,                       /*   where to put the month             */
INT *pDay)                         /*   where to put the day               */
{
     DOUBLE whlprt;
     LONG count;

     modf(vbdat,&whlprt);
     count=atol(spr("%lf",whlprt))-(LONG)VBBDAT;
     *pYear=VBBYR;
     *pMonth=1;
     *pDay=1;
     addDaysToDate(count,pYear,pMonth,pDay);
}

static VOID
exthms(                            /* extract hours,min,sec from VB time   */
DOUBLE vbdat,                      /*   VB DOUBLE-precision date/time      */
INT *pHour,                        /*   where to put the hours             */
INT *pMin,                         /*   where to put the minutes           */
LONG *pSec)                        /*   where to put the seconds           */
{
     DOUBLE whlprt,frcprt;

     frcprt=modf(vbdat,&whlprt);
     (VOID)whlprt;                 /* get rid of blasted compiler warning   */
     *pSec=atol(spr("%lf",frcprt*86400.0));
     *pHour=(INT)(*pSec/3600L);
     *pSec-=(LONG)*pHour*3600;
     *pMin=(INT)(*pSec/60);
     *pSec-=(*pMin*60);
}
