GRASS Programmer's Manual
6.4.2(2012)
|
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 }