📄 interval.c
字号:
* is_nonzero when determining the signs of hour/minute/seconds fields. */ switch (style) { /* compatible with ISO date formats */ case USE_ISO_DATES: if (tm->tm_year != 0) { sprintf(cp, "%d year%s", tm->tm_year, (tm->tm_year != 1) ? "s" : ""); cp += strlen(cp); is_before = (tm->tm_year < 0); is_nonzero = TRUE; } if (tm->tm_mon != 0) { sprintf(cp, "%s%s%d mon%s", is_nonzero ? " " : "", (is_before && tm->tm_mon > 0) ? "+" : "", tm->tm_mon, (tm->tm_mon != 1) ? "s" : ""); cp += strlen(cp); is_before = (tm->tm_mon < 0); is_nonzero = TRUE; } if (tm->tm_mday != 0) { sprintf(cp, "%s%s%d day%s", is_nonzero ? " " : "", (is_before && tm->tm_mday > 0) ? "+" : "", tm->tm_mday, (tm->tm_mday != 1) ? "s" : ""); cp += strlen(cp); is_before = (tm->tm_mday < 0); is_nonzero = TRUE; } if (!is_nonzero || tm->tm_hour != 0 || tm->tm_min != 0 || tm->tm_sec != 0 || fsec != 0) { int minus = tm->tm_hour < 0 || tm->tm_min < 0 || tm->tm_sec < 0 || fsec < 0; sprintf(cp, "%s%s%02d:%02d", (is_nonzero ? " " : ""), (minus ? "-" : (is_before ? "+" : "")), abs(tm->tm_hour), abs(tm->tm_min)); cp += strlen(cp); /* Mark as "non-zero" since the fields are now filled in */ is_nonzero = TRUE; /* fractional seconds? */ if (fsec != 0) {#ifdef HAVE_INT64_TIMESTAMP sprintf(cp, ":%02d", abs(tm->tm_sec)); cp += strlen(cp); sprintf(cp, ".%06d", Abs(fsec));#else fsec += tm->tm_sec; sprintf(cp, ":%012.9f", fabs(fsec));#endif TrimTrailingZeros(cp); cp += strlen(cp); is_nonzero = TRUE; } /* otherwise, integer seconds only? */ else if (tm->tm_sec != 0) { sprintf(cp, ":%02d", abs(tm->tm_sec)); cp += strlen(cp); is_nonzero = TRUE; } } break; case USE_POSTGRES_DATES: default: strcpy(cp, "@ "); cp += strlen(cp); if (tm->tm_year != 0) { int year = tm->tm_year; if (tm->tm_year < 0) year = -year; sprintf(cp, "%d year%s", year, (year != 1) ? "s" : ""); cp += strlen(cp); is_before = (tm->tm_year < 0); is_nonzero = TRUE; } if (tm->tm_mon != 0) { int mon = tm->tm_mon; if (is_before || (!is_nonzero && tm->tm_mon < 0)) mon = -mon; sprintf(cp, "%s%d mon%s", is_nonzero ? " " : "", mon, (mon != 1) ? "s" : ""); cp += strlen(cp); if (!is_nonzero) is_before = (tm->tm_mon < 0); is_nonzero = TRUE; } if (tm->tm_mday != 0) { int day = tm->tm_mday; if (is_before || (!is_nonzero && tm->tm_mday < 0)) day = -day; sprintf(cp, "%s%d day%s", is_nonzero ? " " : "", day, (day != 1) ? "s" : ""); cp += strlen(cp); if (!is_nonzero) is_before = (tm->tm_mday < 0); is_nonzero = TRUE; } if (tm->tm_hour != 0) { int hour = tm->tm_hour; if (is_before || (!is_nonzero && tm->tm_hour < 0)) hour = -hour; sprintf(cp, "%s%d hour%s", is_nonzero ? " " : "", hour, (hour != 1) ? "s" : ""); cp += strlen(cp); if (!is_nonzero) is_before = (tm->tm_hour < 0); is_nonzero = TRUE; } if (tm->tm_min != 0) { int min = tm->tm_min; if (is_before || (!is_nonzero && tm->tm_min < 0)) min = -min; sprintf(cp, "%s%d min%s", is_nonzero ? " " : "", min, (min != 1) ? "s" : ""); cp += strlen(cp); if (!is_nonzero) is_before = (tm->tm_min < 0); is_nonzero = TRUE; } /* fractional seconds? */ if (fsec != 0) {#ifdef HAVE_INT64_TIMESTAMP if (is_before || (!is_nonzero && tm->tm_sec < 0)) tm->tm_sec = -tm->tm_sec; sprintf(cp, "%s%d.%02d secs", is_nonzero ? " " : "", tm->tm_sec, ((int) fsec) / 10000); cp += strlen(cp); if (!is_nonzero) is_before = (fsec < 0);#else fsec_t sec; fsec += tm->tm_sec; sec = fsec; if (is_before || (!is_nonzero && fsec < 0)) sec = -sec; sprintf(cp, "%s%.2f secs", is_nonzero ? " " : "", sec); cp += strlen(cp); if (!is_nonzero) is_before = (fsec < 0);#endif is_nonzero = TRUE; /* otherwise, integer seconds only? */ } else if (tm->tm_sec != 0) { int sec = tm->tm_sec; if (is_before || (!is_nonzero && tm->tm_sec < 0)) sec = -sec; sprintf(cp, "%s%d sec%s", is_nonzero ? " " : "", sec, (sec != 1) ? "s" : ""); cp += strlen(cp); if (!is_nonzero) is_before = (tm->tm_sec < 0); is_nonzero = TRUE; } break; } /* identically zero? then put in a unitless zero... */ if (!is_nonzero) { strcat(cp, "0"); cp += strlen(cp); } if (is_before && (style != USE_ISO_DATES)) { strcat(cp, " ago"); cp += strlen(cp); } return 0;} /* EncodeInterval() *//* interval2tm() * Convert a interval data type to a tm structure. */static intinterval2tm(interval span, struct tm * tm, fsec_t *fsec){#ifdef HAVE_INT64_TIMESTAMP int64 time;#else double time;#endif if (span.month != 0) { tm->tm_year = span.month / MONTHS_PER_YEAR; tm->tm_mon = span.month % MONTHS_PER_YEAR; } else { tm->tm_year = 0; tm->tm_mon = 0; } time = span.time;#ifdef HAVE_INT64_TIMESTAMP tm->tm_mday = time / USECS_PER_DAY; time -= tm->tm_mday * USECS_PER_DAY; tm->tm_hour = time / USECS_PER_HOUR; time -= tm->tm_hour * USECS_PER_HOUR; tm->tm_min = time / USECS_PER_MINUTE; time -= tm->tm_min * USECS_PER_MINUTE; tm->tm_sec = time / USECS_PER_SEC; *fsec = time - (tm->tm_sec * USECS_PER_SEC);#elserecalc: TMODULO(time, tm->tm_mday, (double) SECS_PER_DAY); TMODULO(time, tm->tm_hour, (double) SECS_PER_HOUR); TMODULO(time, tm->tm_min, (double) SECS_PER_MINUTE); TMODULO(time, tm->tm_sec, 1.0); time = TSROUND(time); /* roundoff may need to propagate to higher-order fields */ if (time >= 1.0) { time = ceil(span.time); goto recalc; } *fsec = time;#endif return 0;} /* interval2tm() */static inttm2interval(struct tm * tm, fsec_t fsec, interval * span){ span->month = tm->tm_year * MONTHS_PER_YEAR + tm->tm_mon;#ifdef HAVE_INT64_TIMESTAMP span->time = (((((((tm->tm_mday * INT64CONST(24)) + tm->tm_hour) * INT64CONST(60)) + tm->tm_min) * INT64CONST(60)) + tm->tm_sec) * USECS_PER_SEC) + fsec;#else span->time = (((((tm->tm_mday * (double) HOURS_PER_DAY) + tm->tm_hour) * (double) MINS_PER_HOUR) + tm->tm_min) * (double) SECS_PER_MINUTE) + tm->tm_sec + fsec;#endif return 0;} /* tm2interval() */interval *PGTYPESinterval_new(void){ interval *result; result = (interval *) pgtypes_alloc(sizeof(interval)); /* result can be NULL if we run out of memory */ return result;}voidPGTYPESinterval_free(interval * intvl){ free(intvl);}interval *PGTYPESinterval_from_asc(char *str, char **endptr){ interval *result = NULL; fsec_t fsec; struct tm tt, *tm = &tt; int dtype; int nf; char *field[MAXDATEFIELDS]; int ftype[MAXDATEFIELDS]; char lowstr[MAXDATELEN + MAXDATEFIELDS]; char *realptr; char **ptr = (endptr != NULL) ? endptr : &realptr; tm->tm_year = 0; tm->tm_mon = 0; tm->tm_mday = 0; tm->tm_hour = 0; tm->tm_min = 0; tm->tm_sec = 0; fsec = 0; if (strlen(str) >= sizeof(lowstr)) { errno = PGTYPES_INTVL_BAD_INTERVAL; return NULL; } if (ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf, ptr) != 0 || DecodeInterval(field, ftype, nf, &dtype, tm, &fsec) != 0) { errno = PGTYPES_INTVL_BAD_INTERVAL; return NULL; } result = (interval *) pgtypes_alloc(sizeof(interval)); if (!result) return NULL; if (dtype != DTK_DELTA) { errno = PGTYPES_INTVL_BAD_INTERVAL; free(result); return NULL; } if (tm2interval(tm, fsec, result) != 0) { errno = PGTYPES_INTVL_BAD_INTERVAL; free(result); return NULL; } errno = 0; return result;}char *PGTYPESinterval_to_asc(interval * span){ struct tm tt, *tm = &tt; fsec_t fsec; char buf[MAXDATELEN + 1]; int DateStyle = 0; if (interval2tm(*span, tm, &fsec) != 0) { errno = PGTYPES_INTVL_BAD_INTERVAL; return NULL; } if (EncodeInterval(tm, fsec, DateStyle, buf) != 0) { errno = PGTYPES_INTVL_BAD_INTERVAL; return NULL; } return pgtypes_strdup(buf);}intPGTYPESinterval_copy(interval * intvlsrc, interval * intvldest){ intvldest->time = intvlsrc->time; intvldest->month = intvlsrc->month; return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -