Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Examples  

date.c

Go to the documentation of this file.
00001 /*! \file date.c
00002     This file contains various functions used to manupulate dates.
00003  */
00004 
00005 #include "date.h"
00006 
00007 
00008 /*! \brief Current line in the time zones definitions file.
00009  */
00010 
00011 int             date_line_num;
00012 
00013 /*! \brief This structure contains the date 'timezone', 'daylight', 'time shift'.
00014  */
00015 
00016 struct tz_tab   tzs;
00017 
00018 /*! \brief Parser's entry point (created by flex).
00019  */
00020 
00021 int             dateyylex();
00022 
00023 /*! \brief Parser's input stream (used by dateyylex()).
00024  */
00025 
00026 extern FILE     *dateyyin;
00027 
00028 
00029 /*! \brief This array should contain "MET" and "MET DST" for TZ=MET.
00030  */
00031 
00032 extern char *tzname[2];
00033 
00034 /*! \brief The external time_t variable altzone  contains  the  difference, in seconds, between Coordinated Universal
00035            Time and the alternate time zone.
00036  */
00037 extern time_t timezone;
00038 
00039 /*! \brief The external variable daylight indicates whether time should  reflect  daylight  savings  time.  Both timezone and
00040            altzone default to 0 (UTC). The external  variable  daylight is  non-zero if an alternate time zone exists.
00041  */
00042 extern int daylight;
00043 
00044 /*! \brief The function date2timestamp() lookups the structure 'tzs' to find the correct timezone configuration for the 
00045            current date actually processed. This variable points to the current time zone configuration that aplies to
00046            the currently scaned date.
00047  */
00048 struct timezones *current_tz;
00049 
00050 /*! \brief Set the local time zone to GTM (which is equivalent to UTC).
00051     \return The function returns 0 if success, 1 otherwise.
00052  */
00053 
00054 int set_local_TZ_to_GMT()
00055 {
00056   static char current_tz[TZSET_MAX_SIZE];
00057 
00058 
00059   strcpy (current_tz, "TZ=GMT +0");
00060 
00061   if (putenv(current_tz) != 0) { return 1; }
00062   tzset();
00063   return 0;
00064 }
00065 
00066 /*! \brief Load time zones definitions.
00067     \param filename Pointer to a NULL terminated string of characters that contains the name on the file that contains the
00068            time zones definitions. If 'filename' is NULL, then the function looks for the environmanr variable 
00069            "TIMEZONES_DEFINITION".
00070     \return If the operation succed, the function returns TIME_ZONES_LOAD_OK. Otherwise, the function may return:
00071 <UL>
00072   <li>TIME_ZONES_NO_FILE: No file name specified (ie; 'filename' is NULL, and TIMEZONES_DEFINITION is not set).
00073   <li>TIME_ZONES_CAN_NOT_OPEN_FILE: Can not open definition file.
00074   <li>TIME_ZONES_NO_DEF_FOUND: Definition file is empty.
00075   <li>TIME_ZONES_DEF_OVERFLOW: Too many timezones definitions.
00076   <li>TIME_ZONES_NO_MEM: Running out of memory.
00077   <li>TIME_ZONES_TIMEZONE_OVERFLOW: the timezone flag is too long.
00078   <li>TIME_ZONES_DAYLIGHT_OVERFLOW: the daylight flag is too long.
00079   <li>TIME_ZONES_PARSE_ERROR: parser error - check config file.
00080 </UL>
00081 
00082  */
00083 
00084 int load_timezones (char *filename)
00085 {
00086   char *fname;
00087   int  parser_status;
00088 
00089 
00090   if (filename == NULL)
00091   {
00092     fname = getenv("TIMEZONES_DEFINITION");
00093     if (fname == NULL) { return TIME_ZONES_NO_FILE; }
00094   }
00095   else (fname = filename);
00096 
00097   dateyyin = fopen (fname, "r");
00098   if (dateyyin == NULL) { return TIME_ZONES_CAN_NOT_OPEN_FILE; }
00099   
00100   parser_status = dateyylex();
00101 
00102   if (parser_status != 0) { return parser_status; }
00103 
00104   if (tzs.entry_number == 0) { return TIME_ZONES_NO_DEF_FOUND; }
00105 
00106   return TIME_ZONES_LOAD_OK;
00107 }
00108 
00109 /*! \example test_load_tz.c
00110     This file shows how to use the function load_timezones().
00111  */
00112 
00113 
00114 /*! \brief Compare 2 timezone structures.
00115     \param tz1 Pointer to the first timezone to compare.
00116     \param tz2 Pointer to the second timezone to compare.
00117     \return The function returns 1 if the two structure are identical, otherwise the function returns 0.
00118  */
00119 
00120 int tzcmp (struct timezones *tz1, struct timezones *tz2)
00121 {
00122   if (strcmp (tz1->timezone, tz2->timezone) != 0) { return 0; }
00123   if (strcmp (tz1->daylight, tz2->daylight) != 0) { return 0; }
00124 
00125   return 1;
00126 }
00127 
00128 /*! \brief Find a time zone data structure in the time zone configuration file.
00129     \param tzz Pointer to a time zone data structure. This structure must have the fields 'timezone' and 'daylight'
00130            correctly initialized (NULL terminated string of characters).
00131     \return If the function found a configuration that matches the time zone defined by 'tzz', it returns 1. Otherwise,
00132             the function returns 0. Please note that the structure 'tzz' will contain the correct value for the field
00133             'shift'.
00134  */
00135 
00136 int tzfound (struct timezones *tzz)
00137 {
00138   int i;
00139 
00140   current_tz = NULL;
00141   for (i=0; i<tzs.entry_number; i++)
00142   {
00143     if (tzcmp (&((tzs.tz)[i]), tzz) == 1)
00144     {
00145       current_tz = &((tzs.tz)[i]);
00146       tzz->shift = (tzs.tz)[i].shift;
00147       return 1;
00148     }
00149   }
00150 
00151   return 0;
00152 }
00153 
00154 /*! \example test_load_tz.c
00155     This file shows how to use the function tzfound().
00156  */
00157 
00158 /*! \brief Contains the names of the 7 days of the week.
00159  */
00160 
00161 extern char *days[7];
00162 
00163 /*! \brief Contains the names of the 12 months of the year.
00164  */
00165 
00166 extern char *months[12];
00167 
00168 /*! \brief Returns the index of the day (starting at 0, so the returned value is between 0 and 6). The first day (index 0)
00169            is 'Sunday'.
00170     \param day Pointer to a string of characters that contains the day of the week.
00171     \return The function returns the index of the day (starting at 0, so the returned value is between 0 and 6). If an
00172             error occurs, the function returns -1.
00173  */
00174 
00175 int get_day (char *day)
00176 {
00177   int  i;
00178 
00179   for (i=0; i<7; i++)
00180   { if (strcmp(day, days[i]) == 0) { return i; } }
00181 
00182   return -1;
00183 }
00184 
00185 /*! \brief Returns the index of the month (starting at 0, so the returned value is between 0 and 11). The first month
00186            (index 0) is 'january'.
00187     \param month Pointer to a string of characters that contains the month of the year.
00188     \returns The function returns the index of the month (starting at 0, so the returned value is between 0 and 11).
00189              If an error occurs, the function returns -1.
00190  */ 
00191 
00192 int get_month (char *month)
00193 {
00194   int  i;
00195 
00196   for (i=0; i<12; i++)
00197   { if (strcmp(month, months[i]) == 0) { return i; } }
00198 
00199   return -1;
00200 }
00201 
00202 /*! \brief Returns a zero terminated string of characters that represents the time zones configuration.
00203     \return If the function succed, it returns a non NULL pointer. Otherwise, it returns NULL.
00204     \warning The returned pointer has been allocated within the function, make sure to free it (using free()).
00205  */
00206 
00207 char* print_tz_conf()
00208 {
00209   int    n, size, i;
00210   char   *res;
00211 
00212   n = tzs.entry_number;
00213 
00214   size = n * (TIMEZONE_SIZE + DAYLIGHT_SIZE + TTREF_MAX_TIMESTAMP_SIZE + 50);
00215   res  = (char*)malloc((size+1)*sizeof(char));
00216   if (res == NULL) { return NULL; }
00217 
00218   *res = 0;
00219 
00220   for (i=0; i<n-1; i++)
00221   {
00222     strcat (res, "(");
00223     strcat (res, (tzs.tz)[i].timezone);
00224     strcat (res, ", ");
00225     strcat (res, (tzs.tz)[i].daylight);
00226     strcat (res, ", ");
00227     sprintf (res+strlen(res), "%d) - ", (tzs.tz)[i].shift);
00228   } 
00229 
00230   strcat (res, "(");
00231   strcat (res, (tzs.tz)[i].timezone);
00232   strcat (res, ", ");
00233   strcat (res, (tzs.tz)[i].daylight);
00234   strcat (res, ", ");
00235   sprintf (res+strlen(res), "%d)", (tzs.tz)[i].shift);
00236 
00237   return res;
00238 }
00239 
00240 
00241 
00242 /*! \brief Calculate the timestamp of a ticket (The number of seconds since the first of January 1970).
00243     \param date Pointer to a string of characters that contains the date as it is read from the TSM's log. the date looks
00244            something like ' Tue Aug 28 01:02:24 MET DST 2001'.
00245     \param timestamp Pointer to a string that will receive the timestamp.
00246     \param nbcar Size of the memory location pointed by 'timestamp'.
00247     \param shift This value represents the number of seconds between the current date and the UTC date. If the value of
00248            shift is AUTOMATIC_TIME_SHIFT_COMPUTATION, then the function will use the time zones configuration file
00249            to find out the correct time shift.
00250     \return The function returns a pointer to 'timestamp'. If an error occurs, the function returns NULL. This can mean that
00251             the program is running out of memory, or that the date is not well formated (not "MET" "DST" ...).
00252     \warning <UL>
00253                <li>The first thing to do when using all this function of this library is to call set_local_TZ_to_GMT().
00254                    Otherwise, timestamps will depend on the system's local time zone configuration.
00255                <li>You MUST call the function load_timezones() before using this function !!!! If you do not do that you may
00256                    produce a segmentation fault. 
00257                <li>The input date 'date' will be modified. If you need to used it after, then make a copy!.
00258              </UL>
00259 
00260  */
00261 
00262 char* date2timestamp (char* date, char* timestamp, int nbcar, int shift)
00263 {
00264   struct fields    f;
00265   struct fields    t;
00266   int              nb_fields;
00267   struct tm        tt;
00268   int              seconds;            /* 0    -  59   */
00269   int              minutes;            /* 0    -  59   */
00270   int              hours;              /* 0    -  23   */
00271   int              day_of_the_month;   /* 1    -  31   */ 
00272   int              month;              /* 0    -  11   */
00273   int              year;               /* year - 1900  */
00274   int              day_of_the_week;    /* 0    -  6    */
00275   int              day_of_the_year;    /* 0    -  365  */
00276   int              decalage;           /* any number - see doc */ 
00277   int              year_tag;           /* the position of the year depends on the number of field */
00278   char             tstamp[200];
00279   char*            timep;
00280   time_t           v;
00281   struct timezones tzz;
00282 
00283   #ifdef DEBUG
00284   int i;
00285   #endif
00286 
00287   if (nbcar <= 0) { return NULL; }
00288 
00289   /***********************************************************/
00290   /* Split the date                                          */
00291   /* You can have 6 or 7 fields exactly.                     */
00292   /***********************************************************/
00293 
00294 
00295   nb_fields = s_split(date, " ", &f);
00296 
00297   #ifdef DEBUG
00298   fprintf (stdout, "\n\ndate2timestamp() nb_fields = %d\n", nb_fields); fflush(stdout);
00299   #endif
00300 
00301   if ((nb_fields != 7) && (nb_fields != 6))
00302   {
00303     free_fields (&f);
00304     timestamp[0] = 0;
00305     return NULL;
00306   }
00307 
00308   /***********************************************************/
00309   /* Find the correct timezone and daylight                  */
00310   /* So you get the time shift.                              */
00311   /***********************************************************/
00312 
00313   year_tag = YEAR;
00314 
00315   if (nb_fields == 7)
00316   {
00317     if (strlen(f.tabs[TAG1]) >= TIMEZONE_SIZE)
00318     {
00319       free_fields (&f);
00320       timestamp[0] = 0;
00321       return NULL;
00322     }
00323 
00324     if (strlen(f.tabs[TAG2]) >= DAYLIGHT_SIZE)
00325     {
00326       free_fields (&f);
00327       timestamp[0] = 0;
00328       return NULL;
00329     }
00330 
00331     strcpy (tzz.timezone, f.tabs[TAG1]);
00332     strcpy (tzz.daylight, f.tabs[TAG2]);
00333   }
00334 
00335   if (nb_fields == 6)
00336   {
00337     if (strlen(f.tabs[TAG1]) >= TIMEZONE_SIZE)
00338     {
00339       free_fields (&f);
00340       timestamp[0] = 0;
00341       return NULL;
00342     }
00343 
00344     strcpy (tzz.timezone, f.tabs[TAG1]);
00345     (tzz.daylight)[0] = 0;
00346 
00347     /* One field missing => the year tag is one tag before !!!!!! */
00348 
00349     year_tag = YEAR - 1;
00350   }
00351 
00352   #ifdef DEBUG
00353   fprintf (stdout, "\n\ndate2timestamp(): tzz done\n"); fflush(stdout);
00354   #endif
00355 
00356   /***********************************************************/
00357   /* lookup timezone configuration                           */
00358   /***********************************************************/
00359 
00360   current_tz = NULL;
00361 
00362   if (tzfound(&tzz) == 0)
00363   {
00364     free_fields (&f);
00365     timestamp[0] = 0;
00366     return NULL;
00367   }
00368 
00369   #ifdef DEBUG
00370   fprintf (stdout, "\n\ndate2timestamp(): tzfound() passed\n"); fflush(stdout);
00371   #endif
00372 
00373   /***********************************************************/
00374   /* Time zone configuration found - set global variable     */
00375   /* current_tz                                              */
00376   /***********************************************************/
00377 
00378   /* set into tzfound() ... */
00379 
00380   /***********************************************************/
00381   /* Set time shift according to timezone configuration      */
00382   /***********************************************************/
00383 
00384   if (shift == AUTOMATIC_TIME_SHIFT_COMPUTATION) { shift = tzz.shift; }
00385 
00386   /***********************************************************/
00387   /* Split the clock time                                    */
00388   /***********************************************************/
00389 
00390   timep = (char*)malloc((strlen(f.tabs[CLOCK])+1)*sizeof(char));
00391   if (timep == NULL)
00392   {
00393     free_fields (&f);
00394     timestamp[0] = 0;
00395     return NULL;
00396   }
00397 
00398   strcpy (timep, f.tabs[CLOCK]);
00399 
00400   nb_fields = s_split(timep, ":", &t);
00401   if (nb_fields != 3)
00402   {
00403     free_fields (&t);
00404     free_fields (&f);
00405     free (timep);
00406     timestamp[0] = 0;
00407     return NULL;
00408   }
00409 
00410   free (timep);
00411 
00412   #ifdef DEBUG
00413   fprintf (stdout, "\nDate:");
00414   for (i=0; i<f.number_of_fields; i++)
00415   { fprintf (stdout, "\n -> %s", f.tabs[i]); }
00416   fprintf (stdout, "\n"); fflush(stdout);
00417   #endif
00418  
00419   #ifdef DEBUG
00420   fprintf (stdout, "\nHour:");
00421   for (i=0; i<t.number_of_fields; i++)
00422   { fprintf (stdout, "\n -> %s", t.tabs[i]); }
00423   fprintf (stdout, "\n"); fflush(stdout);
00424   #endif
00425  
00426   /***********************************************************/
00427   /* Compute UTC timestamp                                   */
00428   /***********************************************************/
00429 
00430   seconds            = atoi(t.tabs[SECONDS]);
00431   minutes            = atoi(t.tabs[MINUTES]);
00432   hours              = atoi(t.tabs[HOUR]);
00433   day_of_the_month   = atoi(f.tabs[DAY_OF_THE_MONTH]);
00434   month              = get_month(f.tabs[MONTH]);
00435   year               = atoi(f.tabs[year_tag]) - 1900;
00436   day_of_the_week    = get_day(f.tabs[DAY_OF_THE_WEEK]);
00437   day_of_the_year    = 0;
00438 
00439   decalage           = 0; 
00440 
00441   tt.tm_sec   = seconds;
00442   tt.tm_min   = minutes;
00443   tt.tm_hour  = hours;
00444   tt.tm_mday  = day_of_the_month;
00445   tt.tm_mon   = month;
00446   tt.tm_year  = year;
00447   tt.tm_wday  = day_of_the_week;
00448   tt.tm_yday  = day_of_the_year;  /* unused */
00449   tt.tm_isdst = decalage;
00450 
00451   #ifdef DEBUG
00452   fprintf (stdout, "\nsec:               %d", seconds);
00453   fprintf (stdout, "\nmin:               %d", minutes);
00454   fprintf (stdout, "\nhour:              %d", hours);
00455   fprintf (stdout, "\nday_of_the_month:  %d", day_of_the_month);
00456   fprintf (stdout, "\nmonth:             %d", month);
00457   fprintf (stdout, "\nyear:              %d", year);
00458   fprintf (stdout, "\nday_of_the_week:   %d", day_of_the_week);
00459   fprintf (stdout, "\nday_of_the_year:   %d", day_of_the_year);
00460   fprintf (stdout, "\n");
00461   #endif
00462 
00463   v = mktime(&tt);
00464 
00465   /***********************************************************/
00466   /* Add time shift                                          */
00467   /***********************************************************/
00468 
00469   sprintf (tstamp, "%lu", (unsigned long int)v + shift);
00470 
00471   /***********************************************************/
00472   /* Copy the result into output buffer and then clean all   */
00473   /***********************************************************/
00474 
00475   if (nbcar-1 < strlen(tstamp))
00476   { 
00477     free_fields (&t);
00478     free_fields (&f);
00479     timestamp[0] = 0;
00480     return NULL;
00481   }
00482 
00483   strcpy (timestamp, tstamp);
00484 
00485   free_fields (&f);
00486   free_fields (&t);
00487   return timestamp;
00488 }
00489 
00490 /*! \example test_date2timestamp.c
00491     This file shows how to use the function 'test_date2timestamp()'.
00492  */
00493 
00494 /*! \brief Return the current date as Apache's standard.
00495     \return The function returns a pointer to a string of characters that contains the current date.
00496     \warning The returned pointer points to a static string of characters. Therefore you do NOT have to free it (do NOT free
00497              it!).
00498  */
00499 
00500 char* dater()
00501 {
00502   static char  strtime[MAX_TIMER_SIZE];
00503   time_t       tt;
00504 
00505   tt = time(NULL);
00506   strftime (strtime, 256, "%Y-%m-%d %k:%M:%S", localtime(&tt));
00507 
00508   return strtime;
00509 }
00510 
00511 /*! \example test_date2timestamp.c
00512     This file shows how to use the date functions.
00513  */
00514 
00515 
00516 /*! \brief Current line number being parsed by the time zones reference parsed.
00517  */
00518 int                ttref_line_num = 0;
00519 
00520 /*! \brief Data structure that contains all the couples (date, timestamp) used as reference.
00521  */ 
00522 struct ttref_tab   ttrefs;
00523 
00524 /*! \brief Lexical parser build by the flex utility (for parsing the timestamps references configuration file).
00525  */
00526 extern int ttreflex();
00527 
00528 /*! \brief Pointer to the stream descriptor used by the timestamps references parser.
00529  */
00530 extern FILE* ttrefin;
00531 
00532 
00533 /*! \brief Check the time zone configuration data against well known couple (date, timestamps).
00534     \param config_file Pointer to a zero terminated string of characters that represents the name of the timestamps
00535            reference configuration file. This file is a list of couple (date, timestamps).
00536     \param auto_conf Timezone autoconfiguration flag. This value can be:
00537            <UL>
00538               <li>TZ_AUTOCONF_ON: Auto configuration mode requested.
00539               <li>TZ_AUTOCONF_OFF: Auto configuration mode not requested.
00540            </UL>
00541     \return If the time zone configuration is OK, then the function returns TTREF_OK. Otherwise the function may return
00542             one of the following codes:
00543             <UL>
00544               <li>TTREF_TOO_MANY_REF; Too many references in the timestamps reference config file.
00545               <li>TTREF_NO_MEM: Not enough memory.
00546               <li>TTREF_SYNTAX_ERROR: Syntax error found in the timestamps reference config file.
00547               <li>TTREF_DATE_TOO_LONG: Date too long in the timestamps reference config file.
00548               <li>TTREF_REF_TOO_LONG: timestamp too long in the timestamps reference config file.
00549               <li>TTREF_CAN_NOT_OPEN_CONF_FILE Can not open the timestamps reference config file.
00550               <li>TTREF_INVALID_DATE: Invalid date format in the timestamps reference config file.
00551               <li>TTREF_KO: Invalid time zone configuration - check the time zone configuration file!
00552             </UL>
00553     \warning You must call load_timezones() before you can call this function!.
00554  */
00555 
00556 int test_tz_conf (char* config_file, int auto_conf)
00557 {
00558   int    cr;
00559   int    i;
00560   char   *pt;
00561   char   tt[TTREF_MAX_TIMESTAMP_SIZE];
00562   char   ref_date[TTREF_MAX_DATE_SIZE];
00563 
00564   time_t ref, conf;
00565   int    err, correction;
00566 
00567   /***********************************************************/
00568   /* Make sure we have not already loaded it !               */
00569   /***********************************************************/
00570 
00571   if (ttrefs.entry_number == 0)
00572   {
00573 
00574     /***********************************************************/
00575     /* Open the timestamps references parser's input file      */
00576     /***********************************************************/
00577 
00578     ttrefin = fopen(config_file, "r");
00579     if (ttrefin == NULL) { return TTREF_CAN_NOT_OPEN_CONF_FILE; }
00580 
00581     /***********************************************************/
00582     /* Load timestamps references                              */ 
00583     /***********************************************************/
00584 
00585     cr = ttreflex();
00586     if (cr != 0) { fclose (ttrefin); return cr; }
00587 
00588     fclose (ttrefin); 
00589   }
00590 
00591   /***********************************************************/
00592   /* Now compute known timestamps                            */
00593   /***********************************************************/
00594 
00595   for (i=0; i<ttrefs.entry_number; i++)
00596   {
00597     strcpy (ref_date, ((ttrefs.ttref)[i]).date);
00598 
00599     pt = date2timestamp(ref_date, tt, TTREF_MAX_TIMESTAMP_SIZE, AUTOMATIC_TIME_SHIFT_COMPUTATION);
00600     if (pt == NULL) { return TTREF_INVALID_DATE; }
00601 
00602     #ifdef DEBUG
00603     fprintf (stdout, "\n-> %s", current_tz->timezone);
00604     fprintf (stdout, "\n-> %s", current_tz->daylight);
00605     fprintf (stdout, "\n-> %d", current_tz->shift);
00606     fprintf (stdout, "\n");
00607     fflush (stdout);
00608     #endif
00609 
00610     if (strcmp(tt, ((ttrefs.ttref)[i]).timestamp) != 0)
00611     {
00612       if (auto_conf == TZ_AUTOCONF_OFF) { return TTREF_KO; }
00613 
00614       /*******************************************************/
00615       /* Time zone auto configuration mode activated ...     */
00616       /* Compute the correct time shift according to the     */
00617       /* couples (date, timestamp) considered as references. */
00618       /*******************************************************/
00619 
00620       ref         = string2time_t(((ttrefs.ttref)[i]).timestamp, &err);
00621       conf        = string2time_t(tt, &err);
00622       correction  = (int)((unsigned int)ref - (unsigned int)conf);
00623 
00624       current_tz->shift += correction;    
00625     }
00626   }
00627 
00628   return TTREF_OK; 
00629 }
00630 
00631 /*! \example test_load_ttref.c
00632     This file shows how to use test_tz_conf().
00633  */
00634 
00635 /*! \brief Return the number of seconds since 00:00:00 UTC, January 1, 1970.
00636     \return The function returns the number of seconds since 00:00:00 UTC, January 1, 1970.
00637  */
00638 
00639 time_t get_utc_timestamp ()
00640 {
00641   time_t tt;
00642 
00643   /***********************************************************/
00644   /* Get the number of seconds since 00:00:00 UTC, January   */
00645   /* 1, 1970                                                 */
00646   /***********************************************************/
00647 
00648   tt = time(NULL);
00649   return tt;
00650 }
00651 
00652 /*! \example test_get_utc_timestamp.c
00653     This file shows how to use the function get_utc_timestamp ().
00654  */
00655 
00656 /*! \brief Format a TSM date (ex: &quot;Tue Sep 17 11:48:39 MET 2002&quot;) from a given timestamp.
00657     \param timestamp Number of seconds since 00:00:00 UTC, January 1, 1970 (as returned by the POSIX
00658            function time()).
00659     \param debug Debug flag (0: no debug, otherwize debug output).
00660     \return Upon successful completion, the function returns a pointer to a string of characters that
00661             represents the date associated with the given timestamp. This date respects the TSM's format.
00662             If an error occured, the function returns the value NULL.
00663     \warning The returned pointer points to a static memory area (declared whithin the function). Therefore
00664              you do not have to free it!
00665  */
00666 
00667 char *get_tsm_date (time_t timestamp, int debug)
00668 {
00669   static char  date[MAX_TSM_DATE_SIZE];
00670   static char  current_tz[TZSET_MAX_SIZE];
00671   static char  original_tz[TZSET_MAX_SIZE];
00672   char         buffer[TZSET_MAX_SIZE];
00673   char         *s;
00674   struct tm    *dd;
00675 
00676   
00677 
00678   if (debug)
00679   {
00680     s = getenv("TZ");
00681 
00682     fprintf (stdout, "\n------------------------");
00683     fprintf (stdout, "\nInitial timezone setting:\n");
00684     fflush (stdout);
00685 
00686     if (s != NULL) { fprintf (stdout, "\n       - TZ:         %s", s); fflush (stdout);}
00687     else           { fprintf (stdout, "\n       - TZ:         NULL pointer (getenv(\"TZ\"))"); fflush (stdout); }
00688 
00689     s = tzname[0];
00690     if (s != NULL) { fprintf (stdout, "\n       - tzname[0]:  %s", s); fflush (stdout);}
00691     else           { fprintf (stdout, "\n       - tzname[0]:  NULL pointer"); fflush (stdout); }
00692 
00693     s = tzname[1];
00694     if (s != NULL) { fprintf (stdout, "\n       - tzname[1]:  %s", s); fflush (stdout);}
00695     else           { fprintf (stdout, "\n       - tzname[1]:  NULL pointer"); fflush (stdout); }
00696 
00697     fprintf (stdout, "\n");
00698     fflush (stdout);
00699   }
00700 
00701   /* -------------------------------------------- */
00702   /* Save current timezone setting                */
00703   /* WARNING!! See "man putenv"                   */
00704   /* -------------------------------------------- */
00705 
00706   s = getenv("TZ");
00707   if (s == NULL) { return NULL; }
00708   strcpy (buffer, "TZ=");
00709   if (strlen(s) >= TZSET_MAX_SIZE-3) { return NULL; } 
00710   strcat (buffer, s);
00711   strcpy (original_tz, buffer);
00712 
00713   /* -------------------------------------------- */
00714   /* Now set current timezone to MET              */
00715   /* -------------------------------------------- */
00716 
00717   strcpy (current_tz, "TZ=MET");
00718   if (putenv(current_tz) != 0) { return NULL; }
00719   tzset();
00720 
00721   if (debug)
00722   {
00723     s = getenv("TZ");
00724 
00725     fprintf (stdout, "\nSetting process timezone to MET:\n");
00726     fflush (stdout);
00727 
00728     if (s != NULL) { fprintf (stdout, "\n       - TZ:         %s", s); fflush (stdout);}
00729     else           { fprintf (stdout, "\n       - TZ:         NULL pointer (getenv(\"TZ\"))"); fflush (stdout); }
00730 
00731     s = tzname[0];
00732     if (s != NULL) { fprintf (stdout, "\n       - tzname[0]:  %s", s); fflush (stdout);}
00733     else           { fprintf (stdout, "\n       - tzname[0]:  NULL pointer"); fflush (stdout); }
00734 
00735     s = tzname[1];
00736     if (s != NULL) { fprintf (stdout, "\n       - tzname[1]:  %s", s); fflush (stdout);}
00737     else           { fprintf (stdout, "\n       - tzname[1]:  NULL pointer"); fflush (stdout); }
00738 
00739     fprintf (stdout, "\n");
00740     fflush (stdout);
00741   }
00742 
00743   /* -------------------------------------------- */
00744   /* Format TSM's date                            */
00745   /* -------------------------------------------- */
00746 
00747   if (strcmp(tzname[0], "MET")     != 0) { return NULL; }
00748   if (strcmp(tzname[1], "MET DST") != 0) { return NULL; }
00749 
00750   dd = localtime(&timestamp);
00751 
00752   sprintf (date, "%s %s %02d %02d:%02d:%02d %s %d",
00753                  days[dd->tm_wday],
00754                  months[dd->tm_mon],
00755                  dd->tm_mday,
00756                  dd->tm_hour,
00757                  dd->tm_min,
00758                  dd->tm_sec,
00759                  (dd->tm_isdst ? "MET": "MET DST"),
00760                  1900 + dd->tm_year);
00761 
00762   /* -------------------------------------------- */
00763   /* Restore original timezone setting            */
00764   /* -------------------------------------------- */
00765 
00766   if (putenv(original_tz) != 0) { return NULL; } 
00767   tzset();
00768 
00769   if (debug)
00770   {
00771     s = getenv("TZ");
00772 
00773     fprintf (stdout, "\nRestore initial process timezone:\n");
00774     fflush (stdout);
00775 
00776     if (s != NULL) { fprintf (stdout, "\n       - TZ:         %s", s); fflush (stdout);}
00777     else           { fprintf (stdout, "\n       - TZ:         NULL pointer (getenv(\"TZ\"))"); fflush (stdout); }
00778 
00779     s = tzname[0];
00780     if (s != NULL) { fprintf (stdout, "\n       - tzname[0]:  %s", s); fflush (stdout);}
00781     else           { fprintf (stdout, "\n       - tzname[0]:  NULL pointer"); fflush (stdout); }
00782 
00783     s = tzname[1];
00784     if (s != NULL) { fprintf (stdout, "\n       - tzname[1]:  %s", s); fflush (stdout);}
00785     else           { fprintf (stdout, "\n       - tzname[1]:  NULL pointer"); fflush (stdout); }
00786 
00787     fprintf (stdout, "\n");
00788     fflush (stdout);
00789   }
00790 
00791 
00792   return date;
00793 }
00794 
00795 /*! \example test_get_tsm_date.c
00796     This example shows how to use the function get_tsm_date().
00797  */
00798 
00799 
00800 
00801 
00802 
00803 
00804 
00805 
00806 

Generated on Thu Apr 3 16:23:42 2003 for Common_C_libraries by doxygen1.3-rc1