/* @(#)ast_tratime.c	19.1 (ES0-DMD) 02/25/03 13:53:54 */
/*===========================================================================
  Copyright (C) 1995 European Southern Observatory (ESO)
 
  This program is free software; you can redistribute it and/or 
  modify it under the terms of the GNU General Public License as 
  published by the Free Software Foundation; either version 2 of 
  the License, or (at your option) any later version.
 
  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
 
  You should have received a copy of the GNU General Public 
  License along with this program; if not, write to the Free 
  Software Foundation, Inc., 675 Massachusetss Ave, Cambridge, 
  MA 02139, USA.
 
  Corresponding concerning ESO-MIDAS should be addressed as follows:
	Internet e-mail: midas@eso.org
	Postal address: European Southern Observatory
			Data Management Division 
			Karl-Schwarzschild-Strasse 2
			D 85748 Garching bei Muenchen 
			GERMANY
===========================================================================*/

/*++++++++
.MODULE    tratime.c
.AUTHOR    Francois Ochsenbein [ESO]
.LANGUAGE  C
.CATEGORY  Conversion from character to date structure.
.COMMENTS
\begin{TeX} 
	The time structure is defined in <time.h> (system) as integers
	 \begin{itemize} 
	 \item int tm\_year number
	 \item int tm\_mon number [0-11] \item int tm\_mday [1-31]
	 \item int tm\_yday [0-355]      \item int tm\_wday [0-6] (Sunday = 0)
	 \item int tm\_hour [0-23]	\item int tm\_min [0-59]
	 \item int tm\_sec  [0-59] 	\item int tm\_isdst
	 \end{itemize} 
\end{TeX}

.VERSION   1.0	04-Mar-1987: Creation
.VERSION   1.1	21-Oct-1988: Cosmetic modifications
.VERSION   1.2	17-Feb-1989: Added tr_at
.VERSION   1.3	13-Jul-1989: Corrected bug in tr_atm when string is empty
				(returned status set to zero)
------------------------------*/
 
#include <osdefos.h>
#include <atype.h>
#include <trtime.h>	
#include <tra.h>	
#define FINISH	goto FIN

RSTATIC char month_list[] = {"\0Jan\01Feb\02Mar\03Apr\04May\05Jun\06Jul\07Aug\
\010Sep\011Oct\012Nov\013Dec\01Fev\03Avr\04Mai\05Jui\07Aou\011Okt\013Dez"};

/*===========================================================================*/
int tr_atm(str, len, T)
/*++++++
.PURPOSE Converts a string to a date/time; input can be 
	YYYY MM DD hh mm ss, or MMM DD YYYY hh mm ss,
	with month alphabetic or numeric.
.RETURNS -1 if error (error logged) / Number of Items present, from 1 (only 
	year) to 6 (year + month + day + hours + min + sec)
.REMARKS An empty string gives the current date/time
--------*/
	char	*str;	/* IN: String to scan	*/
	int	len;	/* IN: Length of string to scan	*/
	struct tm *T;	/* OUT: the date structure	*/
{
	char 	*p, *pe, err_flag;
	int	k, i;
	int	l;
	long	value;

  p = str, pe = p + len;
  err_flag = 0;		/* No error */

  p += oscspan(p, pe-p, _SPACE_|_PUNCT_, main_ascii);	/* Skip blanks */
  
  if (p == pe)	/* Empty String: Get Current Date / Time */
  {
  	tr_tT(oshtime(), T);
	k = 0;
  	FINISH;
  }

  
  /* Initialize the structure to zero	*/
  oscfill((char *)T, sizeof(struct tm), 0);
  T->tm_mon = -1;		    /* ... but with a bad month		*/
  
  for (k=0;  p < pe; p += l + oscspan(p+l, pe-p, _SPACE_|_PUNCT_, main_ascii))
  {	if (k >= 6)		break;	/* We have all items!		*/
	if (isdigit(*p))		/* A number comes now ...	*/
	{	l = oscspan(p, pe-p, _DIGIT_, main_ascii);
		i = atoi((char *)p);	/* ... get it ...		*/
		switch(k)
		{ case 1:		/* Month number or day number	*/
			if (T->tm_mon < 0)	T->tm_mon  = i-1;
			else			T->tm_mday = i;
			break;
		  case 0: 		/* Year or Day			*/
		  	if (i <= 31)	T->tm_mday = i;
		  	else		T->tm_year = i;
		  case 2:		/* Year or Day			*/
		  	if (T->tm_mday == 0)	T->tm_mday = i;
		  	else			T->tm_year = i;
		  	break;
		  case 3:		/* Hours	*/
		  	T->tm_hour = i;	break;
		  case 4:		/* Hours	*/
		  	T->tm_min = i;	break;
		  case 5:		/* Hours	*/
		  	T->tm_sec = i;	break;
		}
		k++; continue;
	}
	if (isalpha(*p))		/* A text comes now ...		*/
	{	l = oscspan(p, pe-p, _ALPHA_, main_ascii);
		if (k >= 2)		continue;	/* Useless...	*/
		for (i=1; i < sizeof(month_list); i += 4)
			if (osccomp(&month_list[i], p, 3) == 0)	break;
		if (i >= sizeof(month_list))		/* Not Found...	*/
		{	if (k > 0)	k++;
			continue;
		}
		T->tm_mon = month_list[i-1];
		k++; continue;
	}
	break;				/* Control  character ??	*/
  }
  p += oscspan(p, pe-p, _SPACE_, main_ascii);	/* Strip trailing	*/
  err_flag = tr_tm(T);				/* Add missing info	*/
  if (p != pe)	err_flag = 1;
  if (k == 0)	err_flag = 1;

  FIN:
  return(err_flag ? -1 : k);
}  

/*===========================================================================*/
int tr_at(str, len, t)
/*++++++
.PURPOSE Converts a string to a date/time; input can be 
	YYYY MM DD hh mm ss, or MMM DD YYYY hh mm ss,
	with month alphabetic or numeric.
.RETURNS Length of the scanned text / -1 if error (error logged)
.REMARKS An empty string (value 0 returned) gives the current date/time
--------*/
	char	*str;	/* IN: String to scan	*/
	int	len;	/* IN: Length of string to scan	*/
	long	*t;	/* OUT: the date (seconds since 1970)	*/
{
	struct 	tm T;
	int	status;
	
  *t = 0x80000000;
  if (len > 0)	status = tr_atm(str, len, &T);
  else		status = 0;

  if(status == 0)	*t = oshtime();
  else	if (status > 0)
  {	if (T.tm_year < 100)	T.tm_year += 1900;
  	if (tr_Tt(&T, t) < 0)	status = -1;
  }
  
  return(status);
}
