/* times.c - Copied from I am not sure where, with minor modifications.
* Illustrates various time and date functions including:
*      time            ftime          ctime       asctime
*      localtime       gmtime         mktime      tzset
*      strftime        strptime
* Also the global variables:
*      daylight        timezone       tzname
* Here are the definitions of standard structures from <time.h>:
struct  tm {                    // see ctime(3) 
        int     tm_sec;         // seconds after the minute [0-60] 
        int     tm_min;         // minutes after the hour [0-59] 
        int     tm_hour;        // hours since midnight [0-23] 
        int     tm_mday;        // day of the month [1-31] 
        int     tm_mon;         // months since January [0-11] 
        int     tm_year;        // years since 1900 
        int     tm_wday;        // days since Sunday [0-6] 
        int     tm_yday;        // days since January 1 [0-365] 
        int     tm_isdst;       // Daylight Savings Time flag 
#ifdef _OSF_SOURCE
        long    tm_gmtoff;
        char    *tm_zone;
#else
        long    __tm_gmtoff;
        char    *__tm_zone;
#endif
* From <sys/timeb.h>:

struct timeb    Structure returned by ftime system call
{
        time_t  time;
        unsigned short millitm;
        short   timezone;
        short   dstflag;
};
*/

#include <time.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/timeb.h>
#include <string.h>

/* These are system defined:
  extern int daylight;
  extern long timezone;
  extern char *tzname[];
*/


/* Given a date value of the form
     Thu Dec 01 16:00:00 1999 
   store the appropriate info in the struct tm tmstruct
   It returns 0 iff the conversion succeeded.
 */
static int str2tm(char * value, struct tm * tmstruct)
{
  char * rc = strptime(value, "%A %b %d %H:%M:%S %Y", 
                tmstruct);
  return (rc == NULL);
}

/* display a struct tm */
static void displaystructtm(const char *title, const struct tm *tmstruct)
{
  printf("%s:\n"
         "\tyear: %d, day: %d, hour: %d, minutes: %d, seconds: %d\n",
         title,
         tmstruct->tm_year,
         tmstruct->tm_yday,
         tmstruct->tm_hour,
         tmstruct->tm_min,
         tmstruct->tm_sec);
}

int main()
{
    char tmpbuf[128], *now, ampm[] = "AM";
    time_t ltime;
    struct timeb tstruct;
    struct tm *today, *gmt, atm, xmas = { 0, 0, 12, 25, 11, 93 };

    /* Set time zone from TZ environment variable. If TZ is not set,
     * the operating system is queried to obtain the default value
     * for the variable.
     */
    tzset();

    /* Get UNIX-style time and display as number and string. */
    time( &ltime );
    printf( "Time in seconds since UTC 1/1/70:\t%ld\n", ltime );
    printf( "UNIX time and date:\t\t\t%s", ctime( &ltime ) );

    /* Display UTC. */
    gmt = gmtime( &ltime );
    now = asctime( gmt );
    printf( "Coordinated universal time:\t\t%s", now );

    /* Converting a Coordinated Universal Time string to a tm structure */
    if ( str2tm( now, &atm ) ) {
      printf("%s is not in a format I understand\n", now);
    } else {
      displaystructtm("The struct tm is:", &atm);
    }

    /* Convert to time structure and adjust for PM if necessary. */
    today = localtime( &ltime );
    if( today->tm_hour > 12 )
    {
      strcpy( ampm, "PM" );
      today->tm_hour -= 12;
    }
    if( today->tm_hour == 0 )  /* Adjust if midnight hour. */
      today->tm_hour = 12;

    /* Note how pointer addition is used to skip the first 11
     * characters and printf is used to trim off terminating
     * characters.
     */
    printf( "12-hour time:\t\t\t\t%.8s %s\n",
       asctime( today ) + 11, ampm );

    /* Print additional time information. */
    ftime( &tstruct );
    printf( "Plus milliseconds:\t\t\t%u\n", tstruct.millitm );
    printf( "Zone difference in minutes from UTC:\t%u\n",
             tstruct.timezone );
    printf( "Again, Zone difference in seconds from UTC:\t%u\n",
             timezone );
    printf( "Time zone name:\t\t\t\t%s\n", tzname[0] );
    printf( "Daylight savings:\t\t\t%s\n",
             tstruct.dstflag ? "YES" : "NO" ); /*may give wrong result*/
    printf( "Again Daylight savings:\t\t\t%s\n",
             daylight ? "YES" : "NO" );
    printf( "More Daylight savings:\t\t\t%s\n",
             today->tm_isdst ? "YES" : "NO" );


    /* Make time for noon on Christmas, 1993. */
    if( mktime( &xmas ) != (time_t)-1 )
      printf( "Christmas\t\t\t\t%s\n", asctime( &xmas ) );

    /* Use time structure to build a customized time string. */
    today = localtime( &ltime );

    /* Use strftime to build a customized time string. */
    strftime( tmpbuf, 128,
         "Today is %A, day %d of %B in the year %Y.\n", today );
    printf( tmpbuf );

    return 0;
}

/* Output when ran on a Digital/Compaq Alpha Unix:

Time in seconds since UTC 1/1/70:	956775070
UNIX time and date:			Wed Apr 26 14:51:10 2000
Coordinated universal time:		Wed Apr 26 18:51:10 2000
The struct tm is::
	year: 100, day: 116, hour: 18, minutes: 51, seconds: 10
12-hour time:				02:51:10 PM
Plus milliseconds:			650
Zone difference in minutes from UTC:	300
Again, Zone difference in seconds from UTC:	18000
Time zone name:				GMT
Daylight savings:			NO
Again Daylight savings:			YES
More Daylight savings:			YES
Christmas				Sat Dec 25 12:00:00 1993

Today is Wednesday, day 26 of April in the year 2000.

*/
