• Main Page
  • Related Pages
  • Data Structures
  • Files
  • File List
  • Globals

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, const DateTime * dt)
00105 {
00106     datetime_copy(&ts->dt[0], dt);
00107     ts->count = 1;
00108 }
00109 
00110 void G_set_timestamp_range(struct TimeStamp *ts,
00111                            const DateTime * dt1, const DateTime * dt2)
00112 {
00113     datetime_copy(&ts->dt[0], dt1);
00114     datetime_copy(&ts->dt[1], dt2);
00115     ts->count = 2;
00116 }
00117 
00118 int G__read_timestamp(FILE * fd, struct TimeStamp *ts)
00119 {
00120     char buf[1024];
00121     char comment[2];
00122 
00123     while (fgets(buf, sizeof(buf), fd)) {
00124         if (sscanf(buf, "%1s", comment) != 1 || *comment == '#')
00125             continue;
00126         return (G_scan_timestamp(ts, buf) > 0 ? 0 : -1);
00127     }
00128     return -2;                  /* nothing in the file */
00129 }
00130 
00131 
00145 int G__write_timestamp(FILE * fd, const struct TimeStamp *ts)
00146 {
00147     char buf[1024];
00148 
00149     if (G_format_timestamp(ts, buf) < 0)
00150         return -1;
00151     fprintf(fd, "%s\n", buf);
00152     return 0;
00153 }
00154 
00155 
00171 int G_format_timestamp(const struct TimeStamp *ts, char *buf)
00172 {
00173     char temp1[128], temp2[128];
00174 
00175     *buf = 0;
00176     if (ts->count > 0) {
00177         if (datetime_format(&ts->dt[0], temp1) != 0)
00178             return -1;
00179     }
00180     if (ts->count > 1) {
00181         if (datetime_format(&ts->dt[1], temp2) != 0)
00182             return -1;
00183     }
00184     if (ts->count == 1)
00185         strcpy(buf, temp1);
00186     else if (ts->count == 2)
00187         sprintf(buf, "%s / %s", temp1, temp2);
00188 
00189     return 1;
00190 }
00191 
00192 
00207 int G_scan_timestamp(struct TimeStamp *ts, const char *buf)
00208 {
00209     char temp[1024], *t;
00210     const char *slash;
00211     DateTime dt1, dt2;
00212 
00213     G_init_timestamp(ts);
00214     for (slash = buf; *slash; slash++)
00215         if (*slash == '/')
00216             break;
00217     if (*slash) {
00218         t = temp;
00219         while (buf != slash)
00220             *t++ = *buf++;
00221         *t = 0;
00222         buf++;
00223         if (datetime_scan(&dt1, temp) != 0 || datetime_scan(&dt2, buf) != 0)
00224             return -1;
00225         G_set_timestamp_range(ts, &dt1, &dt2);
00226     }
00227     else {
00228         if (datetime_scan(&dt2, buf) != 0)
00229             return -1;
00230         G_set_timestamp(ts, &dt2);
00231     }
00232     return 1;
00233 }
00234 
00235 
00252 int G_get_timestamps(const struct TimeStamp *ts,
00253                      DateTime * dt1, DateTime * dt2, int *count)
00254 {
00255     *count = 0;
00256     if (ts->count > 0) {
00257         datetime_copy(dt1, &ts->dt[0]);
00258         *count = 1;
00259     }
00260     if (ts->count > 1) {
00261         datetime_copy(dt2, &ts->dt[1]);
00262         *count = 2;
00263     }
00264 
00265     return 0;
00266 }
00267 
00268 
00269 /* write timestamp file
00270  * 1 ok
00271  * -1 error - can't create timestamp file
00272  * -2 error - invalid datetime in ts
00273  */
00274 static int write_timestamp(const char *maptype, const char *dir,
00275                            const char *name, const struct TimeStamp *ts)
00276 {
00277     FILE *fd;
00278     int stat;
00279 
00280     fd = G_fopen_new_misc(dir, "timestamp", name);
00281     if (fd == NULL) {
00282         G_warning(_("Can't create timestamp file for %s map %s in mapset %s"),
00283                   maptype, name, G_mapset());
00284         return -1;
00285     }
00286 
00287     stat = G__write_timestamp(fd, ts);
00288     fclose(fd);
00289     if (stat == 0)
00290         return 1;
00291     G_warning(_("Invalid timestamp specified for %s map %s in mapset %s"),
00292               maptype, name, G_mapset());
00293     return -2;
00294 }
00295 
00296 /* read timestamp file
00297  * 0 no timestamp file
00298  * 1 ok
00299  * -1 error - can't open timestamp file
00300  * -2 error - invalid datetime values in timestamp file
00301  */
00302 static int read_timestamp(const char *maptype, const char *dir,
00303                           const char *name, const char *mapset,
00304                           struct TimeStamp *ts)
00305 {
00306     FILE *fd;
00307     int stat;
00308 
00309     if (!G_find_file2_misc(dir, "timestamp", name, mapset))
00310         return 0;
00311     fd = G_fopen_old_misc(dir, "timestamp", name, mapset);
00312     if (fd == NULL) {
00313         G_warning(_("Can't open timestamp file for %s map %s in mapset %s"),
00314                   maptype, name, mapset);
00315         return -1;
00316     }
00317 
00318     stat = G__read_timestamp(fd, ts);
00319     fclose(fd);
00320     if (stat == 0)
00321         return 1;
00322     G_warning(_("Invalid timestamp file for %s map %s in mapset %s"),
00323               maptype, name, mapset);
00324     return -2;
00325 }
00326 
00327 #define RAST_MISC "cell_misc"
00328 #define VECT_MISC "dig_misc"
00329 #define GRID3     "grid3"
00330 
00331 
00344 int G_read_raster_timestamp(const char *name, const char *mapset,
00345                             struct TimeStamp *ts)
00346 {
00347     return read_timestamp("raster", RAST_MISC, name, mapset, ts);
00348 }
00349 
00350 
00363 int G_remove_raster_timestamp(const char *name)
00364 {
00365     return G_remove_misc(RAST_MISC, "timestamp", name);
00366 }
00367 
00368 
00369 
00382 int G_read_vector_timestamp(const char *name, const char *mapset,
00383                             struct TimeStamp *ts)
00384 {
00385     return read_timestamp("vector", VECT_MISC, name, mapset, ts);
00386 }
00387 
00388 
00389 
00404 int G_remove_vector_timestamp(const char *name)
00405 {
00406     return G_remove_misc(VECT_MISC, "timestamp", name);
00407 }
00408 
00409 
00421 int G_read_grid3_timestamp(const char *name, const char *mapset,
00422                            struct TimeStamp *ts)
00423 {
00424     return read_timestamp("grid3", GRID3, name, mapset, ts);
00425 }
00426 
00427 
00440 int G_remove_grid3_timestamp(const char *name)
00441 {
00442     return G_remove_misc(GRID3, "timestamp", name);
00443 }
00444 
00445 
00446 
00459 int G_write_raster_timestamp(const char *name, const struct TimeStamp *ts)
00460 {
00461     return write_timestamp("raster", RAST_MISC, name, ts);
00462 }
00463 
00464 
00465 
00478 int G_write_vector_timestamp(const char *name, const struct TimeStamp *ts)
00479 {
00480     return write_timestamp("vector", VECT_MISC, name, ts);
00481 }
00482 
00483 
00496 int G_write_grid3_timestamp(const char *name, const struct TimeStamp *ts)
00497 {
00498     return write_timestamp("grid3", GRID3, name, ts);
00499 }

Generated on Thu Dec 9 2010 20:46:05 for GRASS Programmer's Manual by  doxygen 1.7.2