aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/timestamp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/adt/timestamp.c')
-rw-r--r--src/backend/utils/adt/timestamp.c70
1 files changed, 57 insertions, 13 deletions
diff --git a/src/backend/utils/adt/timestamp.c b/src/backend/utils/adt/timestamp.c
index 13dba7cb5c6..7632e1b8961 100644
--- a/src/backend/utils/adt/timestamp.c
+++ b/src/backend/utils/adt/timestamp.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.171 2007/01/05 22:19:42 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.172 2007/02/16 03:39:45 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -3749,32 +3749,57 @@ interval_trunc(PG_FUNCTION_ARGS)
PG_RETURN_INTERVAL_P(result);
}
-/* isoweek2date()
- * Convert ISO week of year number to date.
- * The year field must be specified with the ISO year!
- * karel 2000/08/07
+/* isoweek2j()
+ *
+ * Return the Julian day which corresponds to the first day (Monday) of the given ISO 8601 year and week.
+ * Julian days are used to convert between ISO week dates and Gregorian dates.
*/
-void
-isoweek2date(int woy, int *year, int *mon, int *mday)
+int
+isoweek2j(int year, int week)
{
int day0,
- day4,
- dayn;
+ day4;
- if (!*year)
+ if (!year)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("cannot calculate week number without year information")));
/* fourth day of current year */
- day4 = date2j(*year, 1, 4);
+ day4 = date2j(year, 1, 4);
/* day0 == offset to first day of week (Monday) */
day0 = j2day(day4 - 1);
- dayn = ((woy - 1) * 7) + (day4 - day0);
+ return ((week - 1) * 7) + (day4 - day0);
+}
+
+/* isoweek2date()
+ * Convert ISO week of year number to date.
+ * The year field must be specified with the ISO year!
+ * karel 2000/08/07
+ */
+void
+isoweek2date(int woy, int *year, int *mon, int *mday)
+{
+ j2date(isoweek2j(*year, woy), year, mon, mday);
+}
+
+/* isoweekdate2date()
+ *
+ * Convert an ISO 8601 week date (ISO year, ISO week and day of week) into a Gregorian date.
+ * Populates year, mon, and mday with the correct Gregorian values.
+ * year must be passed in as the ISO year.
+ */
+void
+isoweekdate2date(int isoweek, int isowday, int *year, int *mon, int *mday)
+{
+ int jday;
+
+ jday = isoweek2j(*year, isoweek);
+ jday += isowday - 1;
- j2date(dayn, year, mon, mday);
+ j2date(jday, year, mon, mday);
}
/* date2isoweek()
@@ -3887,6 +3912,17 @@ date2isoyear(int year, int mon, int mday)
}
+/* date2isoyearday()
+ *
+ * Returns the ISO 8601 day-of-year, given a Gregorian year, month and day.
+ * Possible return values are 1 through 371 (364 in non-leap years).
+ */
+int
+date2isoyearday(int year, int mon, int mday)
+{
+ return date2j(year, mon, mday) - isoweek2j(date2isoyear(year, mon, mday), 1) + 1;
+}
+
/* timestamp_part()
* Extract specified field from timestamp.
*/
@@ -4029,6 +4065,10 @@ timestamp_part(PG_FUNCTION_ARGS)
#endif
break;
+ case DTK_ISOYEAR:
+ result = date2isoyear(tm->tm_year, tm->tm_mon, tm->tm_mday);
+ break;
+
case DTK_TZ:
case DTK_TZ_MINUTE:
case DTK_TZ_HOUR:
@@ -4256,6 +4296,10 @@ timestamptz_part(PG_FUNCTION_ARGS)
#endif
break;
+ case DTK_ISOYEAR:
+ result = date2isoyear(tm->tm_year, tm->tm_mon, tm->tm_mday);
+ break;
+
default:
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),