Skip to content

Commit db05f4a

Browse files
committed
Add 'day' field to INTERVAL so 1 day interval can be distinguished from
24 hours. This is very helpful for daylight savings time: select '2005-05-03 00:00:00 EST'::timestamp with time zone + '24 hours'; ?column? ---------------------- 2005-05-04 01:00:00-04 select '2005-05-03 00:00:00 EST'::timestamp with time zone + '1 day'; ?column? ---------------------- 2005-05-04 01:00:00-04 Michael Glaesemann
1 parent 826604f commit db05f4a

File tree

12 files changed

+286
-181
lines changed

12 files changed

+286
-181
lines changed

doc/src/sgml/func.sgml

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.267 2005/07/18 22:34:14 tgl Exp $
2+
$PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.268 2005/07/20 16:42:29 momjian Exp $
33
PostgreSQL documentation
44
-->
55

@@ -5144,6 +5144,22 @@ SELECT SUBSTRING('XY1234Z', 'Y*?([0-9]{1,3})');
51445144
<entry><literal>true</literal></entry>
51455145
</row>
51465146

5147+
<row>
5148+
<entry><literal><function>justify_hours</function>(<type>interval</type>)</literal></entry>
5149+
<entry><type>interval</type></entry>
5150+
<entry>Adjust interval so 24-hour time periods are represented as days</entry>
5151+
<entry><literal>justify_hours(interval '24 hours')</literal></entry>
5152+
<entry><literal>1 day</literal></entry>
5153+
</row>
5154+
5155+
<row>
5156+
<entry><literal><function>justify_days</function>(<type>interval</type>)</literal></entry>
5157+
<entry><type>interval</type></entry>
5158+
<entry>Adjust interval so 30-day time periods are represented as months</entry>
5159+
<entry><literal>justify_days(interval '30 days')</literal></entry>
5160+
<entry><literal>1 month</literal></entry>
5161+
</row>
5162+
51475163
<row>
51485164
<entry><literal><function>localtime</function></literal></entry>
51495165
<entry><type>time</type></entry>

src/backend/commands/variable.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
*
1111
* IDENTIFICATION
12-
* $PostgreSQL: pgsql/src/backend/commands/variable.c,v 1.109 2005/06/28 05:08:55 tgl Exp $
12+
* $PostgreSQL: pgsql/src/backend/commands/variable.c,v 1.110 2005/07/20 16:42:30 momjian Exp $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
@@ -292,6 +292,15 @@ assign_timezone(const char *value, bool doit, GucSource source)
292292
pfree(interval);
293293
return NULL;
294294
}
295+
if (interval->day != 0)
296+
{
297+
if (source >= PGC_S_INTERACTIVE)
298+
ereport(ERROR,
299+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
300+
errmsg("invalid interval value for time zone: day not allowed")));
301+
pfree(interval);
302+
return NULL;
303+
}
295304
if (doit)
296305
{
297306
/* Here we change from SQL to Unix sign convention */
@@ -414,6 +423,7 @@ show_timezone(void)
414423
Interval interval;
415424

416425
interval.month = 0;
426+
interval.day = 0;
417427
#ifdef HAVE_INT64_TIMESTAMP
418428
interval.time = -(CTimeZone * USECS_PER_SEC);
419429
#else

src/backend/utils/adt/date.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/utils/adt/date.c,v 1.112 2005/07/12 15:17:44 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/utils/adt/date.c,v 1.113 2005/07/20 16:42:30 momjian Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -1423,6 +1423,7 @@ time_interval(PG_FUNCTION_ARGS)
14231423
result = (Interval *) palloc(sizeof(Interval));
14241424

14251425
result->time = time;
1426+
result->day = 0;
14261427
result->month = 0;
14271428

14281429
PG_RETURN_INTERVAL_P(result);
@@ -1477,8 +1478,9 @@ time_mi_time(PG_FUNCTION_ARGS)
14771478

14781479
result = (Interval *) palloc(sizeof(Interval));
14791480

1480-
result->time = (time1 - time2);
14811481
result->month = 0;
1482+
result->day = 0;
1483+
result->time = time1 - time2;
14821484

14831485
PG_RETURN_INTERVAL_P(result);
14841486
}

src/backend/utils/adt/formatting.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* -----------------------------------------------------------------------
22
* formatting.c
33
*
4-
* $PostgreSQL: pgsql/src/backend/utils/adt/formatting.c,v 1.90 2005/06/24 01:10:11 neilc Exp $
4+
* $PostgreSQL: pgsql/src/backend/utils/adt/formatting.c,v 1.91 2005/07/20 16:42:30 momjian Exp $
55
*
66
*
77
* Portions Copyright (c) 1999-2005, PostgreSQL Global Development Group
@@ -899,7 +899,7 @@ static char *str_tolower(char *buff);
899899
/* static int is_acdc(char *str, int *len); */
900900
static int seq_search(char *name, char **array, int type, int max, int *len);
901901
static void do_to_timestamp(text *date_txt, text *fmt,
902-
struct pg_tm * tm, fsec_t *fsec);
902+
struct pg_tm *tm, fsec_t *fsec);
903903
static char *fill_str(char *str, int c, int max);
904904
static FormatNode *NUM_cache(int len, NUMDesc *Num, char *pars_str, bool *shouldFree);
905905
static char *int_to_roman(int number);
@@ -3028,7 +3028,7 @@ to_date(PG_FUNCTION_ARGS)
30283028
*/
30293029
static void
30303030
do_to_timestamp(text *date_txt, text *fmt,
3031-
struct pg_tm * tm, fsec_t *fsec)
3031+
struct pg_tm *tm, fsec_t *fsec)
30323032
{
30333033
FormatNode *format;
30343034
TmFromChar tmfc;

src/backend/utils/adt/nabstime.c

Lines changed: 17 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
*
1111
*
1212
* IDENTIFICATION
13-
* $PostgreSQL: pgsql/src/backend/utils/adt/nabstime.c,v 1.135 2005/07/12 16:04:56 momjian Exp $
13+
* $PostgreSQL: pgsql/src/backend/utils/adt/nabstime.c,v 1.136 2005/07/20 16:42:30 momjian Exp $
1414
*
1515
*-------------------------------------------------------------------------
1616
*/
@@ -829,36 +829,26 @@ interval_reltime(PG_FUNCTION_ARGS)
829829
Interval *interval = PG_GETARG_INTERVAL_P(0);
830830
RelativeTime time;
831831
int year,
832-
month;
832+
month,
833+
day;
833834

834835
#ifdef HAVE_INT64_TIMESTAMP
835836
int64 span;
836837
#else
837838
double span;
838839
#endif
839840

840-
if (interval->month == 0)
841-
{
842-
year = 0;
843-
month = 0;
844-
}
845-
else if (abs(interval->month) >=12)
846-
{
847-
year = (interval->month / 12);
848-
month = (interval->month % 12);
849-
}
850-
else
851-
{
852-
year = 0;
853-
month = interval->month;
854-
}
841+
year = interval->month / 12;
842+
month = interval->month % 12;
843+
day = interval->day;
855844

856845
#ifdef HAVE_INT64_TIMESTAMP
857-
span = ((INT64CONST(365250000) * year + INT64CONST(30000000) * month) *
858-
INT64CONST(86400)) + interval->time;
846+
span = ((INT64CONST(365250000) * year + INT64CONST(30000000) * month +
847+
INT64CONST(1000000) * day) * INT64CONST(86400)) +
848+
interval->time;
859849
span /= USECS_PER_SEC;
860850
#else
861-
span = (365.25 * year + 30.0 * month) * SECS_PER_DAY + interval->time;
851+
span = (365.25 * year + 30.0 * month + day) * SECS_PER_DAY + interval->time;
862852
#endif
863853

864854
if (span < INT_MIN || span > INT_MAX)
@@ -876,7 +866,8 @@ reltime_interval(PG_FUNCTION_ARGS)
876866
RelativeTime reltime = PG_GETARG_RELATIVETIME(0);
877867
Interval *result;
878868
int year,
879-
month;
869+
month,
870+
day;
880871

881872
result = (Interval *) palloc(sizeof(Interval));
882873

@@ -887,6 +878,7 @@ reltime_interval(PG_FUNCTION_ARGS)
887878
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
888879
errmsg("cannot convert reltime \"invalid\" to interval")));
889880
result->time = 0;
881+
result->day = 0;
890882
result->month = 0;
891883
break;
892884

@@ -896,15 +888,19 @@ reltime_interval(PG_FUNCTION_ARGS)
896888
reltime -= (year * (36525 * 864));
897889
month = (reltime / (30 * SECS_PER_DAY));
898890
reltime -= (month * (30 * SECS_PER_DAY));
891+
day = reltime / SECS_PER_DAY;
892+
reltime -= day * SECS_PER_DAY;
899893

900894
result->time = (reltime * USECS_PER_SEC);
901895
#else
902896
TMODULO(reltime, year, 36525 * 864);
903897
TMODULO(reltime, month, 30 * SECS_PER_DAY);
898+
TMODULO(reltime, day, SECS_PER_DAY);
904899

905900
result->time = reltime;
906901
#endif
907902
result->month = 12 * year + month;
903+
result->day = day;
908904
break;
909905
}
910906

src/backend/utils/adt/selfuncs.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
*
1616
*
1717
* IDENTIFICATION
18-
* $PostgreSQL: pgsql/src/backend/utils/adt/selfuncs.c,v 1.184 2005/07/12 16:04:57 momjian Exp $
18+
* $PostgreSQL: pgsql/src/backend/utils/adt/selfuncs.c,v 1.185 2005/07/20 16:42:30 momjian Exp $
1919
*
2020
*-------------------------------------------------------------------------
2121
*/
@@ -2784,10 +2784,11 @@ convert_timevalue_to_scalar(Datum value, Oid typid)
27842784
* too accurate, but plenty good enough for our purposes.
27852785
*/
27862786
#ifdef HAVE_INT64_TIMESTAMP
2787-
return (interval->time + (interval->month * ((365.25 / 12.0) * 86400000000.0)));
2787+
return interval->time + interval->day * (double)USECS_PER_DAY +
2788+
interval->month * ((365.25 / 12.0) * USECS_PER_DAY);
27882789
#else
2789-
return interval->time +
2790-
interval ->month * (365.25 / 12.0 * 24.0 * 60.0 * 60.0);
2790+
return interval->time + interval->day * SECS_PER_DAY +
2791+
interval->month * ((365.25 / 12.0) * (double)SECS_PER_DAY);
27912792
#endif
27922793
}
27932794
case RELTIMEOID:

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy