timestamp.c

Go to the documentation of this file.
00001 /*
00002  *
00003  * provides DateTime functions for timestamp management:
00004  *
00005  * Authors: Michael Shapiro & Bill Brown, CERL
00006  *          grid3 functions by Michael Pelizzari, LMCO
00007  *
00008  * G_init_timestamp()
00009  * G_set_timestamp()
00010  * G_set_timestamp_range()
00011  * G_format_timestamp()
00012  * G_scan_timestamp()
00013  * G_get_timestamps()
00014  * G_read_raster_timestamp()
00015  * G_remove_raster_timestamp()
00016  * G_read_vector_timestamp()
00017  * G_remove_vector_timestamp()
00018  * G_read_grid3_timestamp()
00019  * G_remove_grid3_timestamp()
00020  * G_write_raster_timestamp()
00021  * G_write_vector_timestamp()
00022  * G_write_grid3_timestamp()
00023  *
00024  * COPYRIGHT:    (C) 2000 by the GRASS Development Team
00025  *
00026  *               This program is free software under the GNU General Public
00027  *               License (>=v2). Read the file COPYING that comes with GRASS
00028  *               for details.
00029  *
00030  *
00031  * The timestamp values must use the format as described in the GRASS
00032  * datetime library. The source tree for this library should have a
00033  * description of the format. For convience, the formats as of Feb, 1996
00034  * are reproduced here:
00035  *
00036  * There are two types of datetime values: absolute and relative. Absolute
00037  * values specify exact dates and/or times. Relative values specify a span
00038  * of time. Some examples will help clarify:
00039  *
00040  * Absolute
00041  *
00042  * The general format for absolute values is:
00043  *
00044  * day month year [bc] hour:minute:seconds timezone
00045  *
00046  * day is 1-31
00047  * month is jan,feb,...,dec
00048  * year is 4 digit year
00049  * [bc] if present, indicates dates is BC
00050  * hour is 0-23 (24 hour clock)
00051  * mintue is 0-59
00052  * second is 0-59.9999 (fractions of second allowed)
00053  * timezone is +hhmm or -hhmm (eg, -0600)
00054  *
00055  * parts can be missing
00056  *
00057  * 1994 [bc]
00058  * Jan 1994 [bc]
00059  * 15 jan 1000 [bc]
00060  * 15 jan 1994 [bc] 10 [+0000]
00061  * 15 jan 1994 [bc] 10:00 [+0100]
00062  * 15 jan 1994 [bc] 10:00:23.34 [-0500]
00063  *
00064  * Relative
00065  *
00066  * There are two types of relative datetime values, year- month and day-second.
00067  *
00068  * The formats are:
00069  *
00070  * [-] # years # months
00071  * [-] # days # hours # minutes # seconds
00072  *
00073  * The words years, months, days, hours, minutes, seconds are literal words,
00074  * and the # are the numeric values.
00075  *
00076  * Examples:
00077  *
00078  * 2 years
00079  * 5 months
00080  * 2 years 5 months
00081  * 100 days
00082  * 15 hours 25 minutes 35.34 seconds
00083  * 100 days 25 minutes
00084  * 1000 hours 35.34 seconds
00085  *
00086  * The following are illegal because it mixes year-month and day-second
00087  * (because the number of days in a month or in a year vary):
00088  *
00089  * 3 months 15 days
00090  * 3 years 10 days
00091  *
00092  *
00093  */
00094 
00095 #include <string.h>
00096 #include <grass/gis.h>
00097 #include <grass/glocale.h>
00098 
00099 void G_init_timestamp (struct TimeStamp *ts)
00100 {
00101     ts->count = 0;
00102 }
00103 
00104 void G_set_timestamp (struct TimeStamp *ts, DateTime *dt)
00105 {
00106     datetime_copy (&ts->dt[0],dt);
00107     ts->count = 1;
00108 }
00109 
00110 void G_set_timestamp_range (
00111     struct TimeStamp *ts,
00112     DateTime *dt1,DateTime *dt2)
00113 {
00114     datetime_copy (&ts->dt[0], dt1);
00115     datetime_copy (&ts->dt[1], dt2);
00116     ts->count = 2;
00117 }
00118 
00119 int G__read_timestamp (FILE *fd, struct TimeStamp *ts)
00120 {
00121     char buf[1024];
00122     char comment[2];
00123 
00124     while (fgets(buf, sizeof(buf), fd))
00125     {
00126         if (sscanf (buf, "%1s", comment) != 1 || *comment == '#')
00127             continue;
00128         return (G_scan_timestamp (ts, buf) > 0 ? 0 : -1);
00129     }
00130     return -2; /* nothing in the file */
00131 }
00132 
00133 
00147 int G__write_timestamp ( FILE *fd, struct TimeStamp *ts)
00148 {
00149     char buf[1024];
00150 
00151     if (G_format_timestamp (ts, buf) < 0)
00152         return -1;
00153     fprintf (fd, "%s\n", buf);
00154     return 0;
00155 }
00156 
00157 
00173 int G_format_timestamp (
00174     struct TimeStamp *ts,
00175     char *buf)
00176 {
00177     char temp1[128], temp2[128];
00178     *buf = 0;
00179     if (ts->count > 0)
00180     {
00181         if (datetime_format (&ts->dt[0],temp1) != 0)
00182             return -1;
00183     }
00184     if (ts->count > 1)
00185     {
00186         if (datetime_format (&ts->dt[1],temp2) != 0)
00187             return -1;
00188     }
00189     if (ts->count == 1)
00190         strcpy (buf, temp1);
00191     else if (ts->count == 2)
00192         sprintf (buf, "%s / %s", temp1, temp2);
00193 
00194     return 1;
00195 }
00196 
00197 
00212 int G_scan_timestamp (
00213     struct TimeStamp *ts,
00214     char *buf)
00215 {
00216     char temp[1024], *t;
00217     char *slash;
00218     DateTime dt1, dt2;
00219 
00220     G_init_timestamp(ts);
00221     for (slash = buf; *slash; slash++)
00222         if (*slash == '/')
00223             break;
00224     if (*slash)
00225     {
00226         t = temp;
00227         while (buf != slash)
00228             *t++ = *buf++;
00229         *t = 0;
00230         buf++;
00231         if (datetime_scan(&dt1,temp) != 0 || datetime_scan(&dt2,buf) != 0)
00232                 return -1;
00233         G_set_timestamp_range (ts, &dt1, &dt2);
00234     }
00235     else
00236     {
00237         if(datetime_scan (&dt2, buf) != 0 )
00238             return -1;
00239         G_set_timestamp (ts, &dt2);
00240     }
00241     return 1;
00242 }
00243 
00244 
00261 int G_get_timestamps (
00262     struct TimeStamp *ts,
00263     DateTime *dt1,DateTime *dt2,
00264     int *count)
00265 {
00266     *count = 0;
00267     if (ts->count > 0)
00268     {
00269         datetime_copy (dt1, &ts->dt[0]);
00270         *count = 1;
00271     }
00272     if (ts->count > 1)
00273     {
00274         datetime_copy (dt2, &ts->dt[1]);
00275         *count = 2;
00276     }
00277 
00278     return 0;
00279 }
00280 
00281 
00282 /* write timestamp file
00283  * 1 ok
00284  * -1 error - can't create timestamp file
00285  * -2 error - invalid datetime in ts
00286  */
00287 static int write_timestamp (
00288     char *maptype,char *mapname,char *element,char *filename,
00289     struct TimeStamp *ts)
00290 {
00291     FILE *fd;
00292     int stat;
00293 
00294     fd = G_fopen_new (element, filename);
00295     if (fd == NULL)
00296     {
00297         G_warning (
00298                 _("Can't create timestamp file for %s map %s in mapset %s"),
00299                 maptype, mapname, G_mapset());
00300         return -1;
00301     }
00302 
00303     stat = G__write_timestamp (fd, ts);
00304     fclose (fd);
00305     if (stat == 0)
00306         return 1;
00307     G_warning (
00308             _("Invalid timestamp specified for %s map %s in mapset %s"),
00309             maptype, mapname, G_mapset());
00310     return -2;
00311 }
00312 
00313 /* read timestamp file
00314  * 0 no timestamp file
00315  * 1 ok
00316  * -1 error - can't open timestamp file
00317  * -2 error - invalid datetime values in timestamp file
00318  */
00319 static int read_timestamp (
00320     char *maptype,char *mapname,char *mapset,
00321     char *element,char *filename,
00322     struct TimeStamp *ts)
00323 {
00324     FILE *fd;
00325     int stat;
00326 
00327     if (!G_find_file2 (element, filename, mapset))
00328         return 0;
00329     fd = G_fopen_old (element, filename, mapset);
00330     if (fd == NULL)
00331     {
00332         G_warning (
00333                 _("Can't open timestamp file for %s map %s in mapset %s"),
00334                 maptype, mapname, mapset);
00335         return -1;
00336     }
00337 
00338     stat = G__read_timestamp (fd, ts);
00339     fclose (fd);
00340     if (stat == 0)
00341         return 1;
00342     G_warning (
00343             _("Invalid timestamp file for %s map %s in mapset %s"),
00344             maptype, mapname, mapset);
00345     return -2;
00346 }
00347 
00348 #define RAST_MISC "cell_misc"
00349 #define VECT_MISC "dig_misc"
00350 #define GRID3     "grid3"
00351 
00352 
00365 int G_read_raster_timestamp (
00366     char *name,char *mapset,
00367     struct TimeStamp *ts)
00368 {
00369     char element[128];
00370 
00371     sprintf (element, "%s/%s", RAST_MISC, name);
00372     return read_timestamp ("raster", name, mapset, element, "timestamp", ts);
00373 }
00374 
00375 
00388 int G_remove_raster_timestamp (char *name)
00389 {
00390     char element[128];
00391 
00392     sprintf (element, "%s/%s", RAST_MISC, name);
00393     return G_remove(element, "timestamp");
00394 }
00395 
00396 
00397 
00410 int G_read_vector_timestamp (
00411     char *name,char *mapset,
00412     struct TimeStamp *ts)
00413 {
00414     char element[128];
00415 
00416     sprintf (element, "%s/%s", VECT_MISC, name);
00417     return read_timestamp ("vector", name, mapset, element, "timestamp", ts);
00418 }
00419 
00420 
00421 
00436 int G_remove_vector_timestamp (char *name)
00437 {
00438     char element[128];
00439 
00440     sprintf (element, "%s/%s", VECT_MISC, name);
00441     return G_remove(element, "timestamp");
00442 }
00443 
00444 
00456 int G_read_grid3_timestamp (
00457     char *name,char *mapset,
00458     struct TimeStamp *ts)
00459 {
00460     char element[128];
00461 
00462     sprintf (element, "%s/%s", GRID3, name);
00463     return read_timestamp ("grid3", name, mapset, element, "timestamp", ts);
00464 }
00465 
00466 
00479 int G_remove_grid3_timestamp (char *name)
00480 {
00481     char element[128];
00482 
00483     sprintf (element, "%s/%s", GRID3, name);
00484     return G_remove(element, "timestamp");
00485 }
00486 
00487 
00488 
00501 int G_write_raster_timestamp (
00502     char *name,
00503     struct TimeStamp *ts)
00504 {
00505     char element[128];
00506 
00507     sprintf (element, "%s/%s", RAST_MISC, name);
00508     return write_timestamp ("raster", name, element, "timestamp", ts);
00509 }
00510 
00511 
00512 
00525 int G_write_vector_timestamp (
00526     char *name,
00527     struct TimeStamp *ts)
00528 {
00529     char element[128];
00530 
00531     sprintf (element, "%s/%s", VECT_MISC, name);
00532     return write_timestamp ("vector", name, element, "timestamp", ts);
00533 }
00534 
00535 
00548 int G_write_grid3_timestamp (
00549     char *name,
00550     struct TimeStamp *ts)
00551 {
00552     char element[128];
00553 
00554     sprintf (element, "%s/%s", GRID3, name);
00555     return write_timestamp ("grid3", name, element, "timestamp", ts);
00556 }

Generated on Wed Dec 19 14:59:06 2007 for GRASS by  doxygen 1.5.4