Project: YugabyteDB (App Definition and Development / Database)
File: manipulating-date-time-values.md

title: Functions for manipulating date-time values [YSQL] headerTitle: Functions for manipulating date-time values linkTitle: Manipulating date-time values description: The semantics of the functions manipulating date-time values. [YSQL] menu: v2.18: identifier: manipulating-date-time-values parent: date-time-functions weight: 20 type: docs The datetrunc() built-in function truncates a datetime value to the specified granularity. It has three overloads. Each returns a value whose data type is the same as that of the second argument. The first argument, chosen from a list of legal values, determines how the second argument will be truncated. Here is the interesting part of the output from \\df datetrunc()_: ```output Result data type | Argument data types --+-- interval | text, interval timestamp with time zone | text, timestamp with time zone timestamp without time zone | text, timestamp without time zone ``` Here are the legal values for the first argument, in order of increasing size: ```output microseconds milliseconds second minute hour day week month quarter year decade century millennium ``` If a date value is used for the second argument, then the typecasting rules presented in the in the section are used. However, a date value can be typecast either to a plan timestamp value or to a timestamptz value; so a rule governs the data type of the return value. It can be determined by experiment like this: ```plpgsql set timezone = 'UTC'; with c as ( select date_trunc('year', '2021-07-19'::date) as v) select pg_typeof(v)::text as "type", v::text from c; ``` This is the result: ```output type | v --+ timestamp with time zone | 2021-01-01 00:00:00+00 ``` Of course, you should never rely on implicit typecasting but, rather, should always write the typecast that you intend explicitly. Try this: ```plpgsql with c as ( select date_trunc('year', ('2021-07-19'::date)::timestamp) as v) select pg_typeof(v)::text as "type", v::text from c; ``` This is the result: ```output type | v --+ timestamp without time zone | 2021-01-01 00:00:00 ``` A plain time value cannot be typecast to a plain timestamp value or to a timestamptz value. But it can be typecast to an interval

Try this: ```plpgsql with c as ( select date_trunc('hour', ('13:42:37.123456'::time)::interval) as v) select pg_typeof(v)::text as "type", v::text from c; ``` This is the result: ```output type | v -+- interval | 13:00:00 ``` Notice that when a hybrid interval value is supplied to datetrunc()_, the result might surprise the uninitiated. Try this: ```plpgsql with c as ( -- 5000000 hours is close to 600 years. select make_interval(hours=>5000000) as i) select i, date_trunc('years', i) as "result" from c; ``` This is the result: ```output i | result +- 5000000:00:00 | 00:00:00 ``` The result (truncating a value of close to 600 years to a granularity of one year gets a result of zero) emphasizes the point that hybrid interval values can be dangerous. This is explained in the section . Briefly, these functions manipulate the fields of the internal representation of an interval value by using a rule of thumb to compute and apply increments to the mm and dd fields from, respectively, the dd and ss fields. Nominally, they make interval values easier to comprehend. Here's an example: ```plpgsql \x on with c1 as ( select '2017-05-16 12:00:00'::timestamp as t, make_interval(days=>1000000, secs=>1000000) as i), c2 as ( select t as t, i as i, justify_interval(i) as j from c1) select t ::text as "t", i ::text as "i", (t + i) ::text as "t + i", j ::text as "justify_interval(i)", (t + j) ::text as "t + justify_interval(i)" from c2; \x off ``` This is the result: ```output t | 2017-05-16 12:00:00 i | 1000000 days 277:46:40 t + i | 4755-04-25 01:46:40 justify_interval(i) | 2777 years 9 mons 21 days 13:46:40 t + justify_interval(i) | 4795-03-10 01:46:40 ``` Notice that justifyinterval(i) changed the addition semantics of i. This is dramatically different from justifying, for example, 18 inches to 1 foot 6 inches_ where the two presentation forms have identical distance semantics. The section explains the potential dangers (dramatically changing the semantics of interval arithmetic) that using these functions brings. These three functions are described in the section within the section .