What is the correct syntax for working with Dates in DB2? - date

I am writing a SQL statement that may be used against a number of database types.
I have never worked with DB2 before, and am unsure of the syntax for working with dates.
The dates are stored as a date type.
Here is a snippet of the statement against a SQL Server database:
SELECT * from tbl1 where YEAR(Start_Time) = YEAR(GetDate() -365)
I thinking that the equivalent in DB2 would be:
SELECT * from tbl1 where YEAR(Start_Time) = YEAR(current_date -365 days)
Unfortunately, I don't have a DB2 environment at my home office (thanks to COVID-19)

Datetime operations and durations
SELECT Start_Time
FROM
(
VALUES
CURRENT TIMESTAMP - 365 DAYS - 1 HOUR - 1 MINUTE - 1 SECOND - 1 MICROSECOND
, CURRENT TIMESTAMP - 365 DAYS
) tbl1 (Start_Time)
WHERE YEAR(Start_Time) = YEAR(CURRENT TIMESTAMP - 365 DAYS);
The result is:
|START_TIME |
|--------------------------|
|2019-04-08-15.17.17.613999|
|2019-04-08-16.18.18.614000|

Related

how can i get the all data from postgresql thats from the current day, between the hours of 00:00:00 and 11:59:59?

very new to the backend as well as all things postgresql, at the moment all ive been able to do is
SELECT * FROM nutrition WHERE timestamp >= (extract(epoch from now())::bigint * 1000) - 86400000 AND timestamp <= (extract(epoch from now())::bigint * 1000) + 86400000
in the frontend using js, im using Date.now() to store the timestamp in the DB.
timestamp is a column in my db thats logging the unix time in bigint format in which the food was logged. I want to get all the data from the current day from the hours beteen 12 AM midnight, and 11:59 PM. thanks.
for example, the last item i logged was last night at 10pm (1663995295337 UNIX time) so the data shouldnt include it.
show timezone returns;
America/Los_Angeles
Solution below --------------------------------------------------------------------
const today = new Date();
const beginningOfDay = today.setUTCHours(7, 0, 0, 0);
const endOfDay = today.setUTCHours(30, 59, 59, 99);
switch (method) {
case "GET":
try {
const text = `
select
*
from
nutrition
where
timestamp
between ${beginningOfDay} and ${endOfDay}`
this was the solution i was looking for, thanks for the help. sorry if i wasnt descriptive enough.
Assuming that by Unix time you mean epoch.
select extract(epoch from now());
extract
-------------------
1664038032.392004
select to_timestamp(1664038032.392004);
to_timestamp
--------------------------------
09/24/2022 09:47:12.392004 PDT
select
*
from
some_table
where
to_timestamp(1664038032.392004)
between
current_date + '00:00:00'::time AND current_date + '23:59:59'::time
UPDATE
Using timestamptz field in Postgres and an ISO datetime string from Javascript in order to properly deal with time zone.
create table tsz_test(id integer, tsz_fld timestamptz);
--In Web frontend today = new Date().toISOString(); "2022-09-24T20:57:05.830Z"
insert into
tsz_test
values (1, '2022-09-24T20:57:05.830Z'), (2, '2022-09-25T08:57:05.830Z');
select * from tsz_test ;
id | tsz_fld
----+----------------------------
1 | 09/24/2022 13:57:05.83 PDT
2 | 09/25/2022 01:57:05.83 PDT
--Borrowing from #a_horse_with_no_name answer
select * from tsz_test where tsz_fld::date = '09/24/2022'::date;
id | tsz_fld
----+----------------------------
1 | 09/24/2022 13:57:05.83 PDT
You can convert your "unix timestamp" to a date, then compare it with "today":
where to_timestamp("timestamp")::date = current_date
This assumes that your column named "timestamp" is not really a timestamp
If the column doesn't actually store seconds (which would be a unix epoch), but milliseconds you need to_timestamp("timestamp"/1000)::date instead (another source of problems that wouldn't exist if you had used a proper timestamptz or at least timestamp data type).

Number of days in a month in DB2

Is there a way to find the number of days in a month in DB2. For example I have a datetime field which I display as Jan-2020, Feb-2020 and so on. Based on this field I need to fetch the number of days for that month. The output should be something like below table,
I'm using the below query
select reportdate, TO_CHAR(reportdate, 'Mon-YYYY') as textmonth from mytable
Expected output
ReportDate textMonth No of Days
1-1-2020 08:00 Jan-2020 31
1-2-2020 09:00 Feb-2020 29
12-03-2020 07:00 Mar-2020 31
Try this:
/*
WITH MYTABLE (reportdate) AS
(
VALUES
TIMESTAMP('2020-01-01 08:00:00')
, TIMESTAMP('2020-02-01 09:00:00')
, TIMESTAMP('2020-03-12 07:00:00')
)
*/
SELECT reportdate, textMonth, DAYS(D + 1 MONTH) - DAYS(D) AS NO_OF_DAYS
FROM
(
SELECT
reportdate, TO_CHAR(reportdate, 'Mon-YYYY') textMonth
, DATE(TO_DATE('01-' || TO_CHAR(reportdate, 'Mon-YYYY'), 'dd-Mon-yyyy')) D
FROM MYTABLE
);
Db2 has the function DAYS_TO_END_OF_MONTH and several others which you could use. Based on your month input, construct the first day of the month. This should be something like 2020-01-01 for Jan-2020 or 2020-02-01 for Feb-2020. Follow the link for several other conversion functions which allow you to transform between formats and to perform date arithmetics.
convert your column to a proper date and try this: day(last_day(date_column))

PostgreSQL difference between two dates and return in hours and minutes

Hello I want to return in my PostgreSQL the difference between two dates:
START: 2016-06-01 00:00:00
END: 2016-06-06 08:35:33
Expected return value: 128:35:33, formatted like format [h]:mm:ss;# in Excel. Hours must be added up if there is more than 24 hours of difference.
Here's my SQL:
SELECT EXTRACT(EPOCH FROM dt_termino::timestamp - dt_inicio::timestamp)/3600 FROM crm.task_interacao WHERE id_task_tarefa = 1
UPDATE!!!
hello now i'm facing another problema I have a table like this:
my table in database like this
start;end
2013-06-01 09:29:33;2016-06-07 14:08:19
2016-06-07 14:22:09;2016-06-07 14:22:43
2016-06-07 14:22:51; null
i need to sum values ....i'm trying as you said (1st awnser).. I cant use function because i'm using inside a php code
SELECT SUM(COALESCE(end::timestamp, now()::timestamp) - start::timestamp) FROM crm.task_interacao WHERE id_task_tarefa = 1
but is returning
1102 days 26:07:54.864879
why 26 hours??? I was supose be te at maximum 24...
no problem now to return (Days HH:MM:SS) and not miliseconds
You can simply subtract timestamps to get interval:
select '2016-06-06 08:35:33'::timestamp- '2016-06-01 00:00:00' result
result
-----------------
5 days 08:35:33
(1 row)
There is no standard function to convert the result to the format you need but you can write one:
create or replace function interval_without_days(interval)
returns interval language sql as $$
select $1- date_part('day', $1)* '1d'::interval+ date_part('day', $1)* '24h'::interval;
$$;
select interval_without_days('2016-06-06 08:35:33'::timestamp- '2016-06-01 00:00:00');
interval_without_days
-----------------------
128:35:33
(1 row)
Question #2. Use the functions date_trunc(text, interval) and justify_hours(interval):
select date_trunc('sec', justify_hours('1102 days 26:07:54.864879'));
date_trunc
--------------------
1103 days 02:07:54
(1 row)

How can I have timestamp displayed in UTC+02 (same timezone) for both the queries below?

My first query is:
SELECT distinct wfc_request_job_id,wfc_request_job_info,
replace(iso_cc,';',' ') as "iso_cc",to_char(wfc_request_start_ts,'yyyy-MM-dd HH:mm:ss') as ts,
sent_message_count,
(link_object_count + poi_object_count + point_address_object_count) as request_object_count
FROM wfc_request_job
where
wfc_request_job_id=173526;
This returns ts as 2015-08-16 03:08:59
Second Query:
SELECT wfc_request_job_id,wfc_request_start_ts,wfc_request_end_ts,replace(iso_cc,';',' ') as "iso_ccs",sent_message_count,wfc_queue_name
FROM wfc_request_job
where
to_char(wfc_request_start_ts,'YYYY-MM-DD') >= to_char(to_date('08/16/2015','MM/DD/YYYY'),'YYYY-MM-DD')
and to_char(wfc_request_start_ts,'YYYY-MM-DD') <= to_char(to_date('08/16/2015','MM/DD/YYYY'),'YYYY-MM-DD')
order by wfc_request_job_id desc
This returns ts of the job id mentioned above as - "2015-08-16 15:58:59.809+02"
How can I make both the queries return ts in UTC+02 - i.e. same timezone
The data type of wfc_request_start_ts is - timestamp with timezone
I changed to queries to have the format HH24:MI:SS however that did not help. Please note that the webapp using these queries will be opened in both Germany and USA.
According to postgresql manual to_char there is TZ (and OF as of v9.4) template patterns for Date/Time formatting.
Therefore in query you need to add it so
postgres=# select to_char(now(),'yyyy-MM-dd HH24:mm:ss TZ');
to_char
------------------------
2015-08-19 12:08:56 CEST
(1 row)
Also, make sure you specify timezone when converting
so instead
to_date('08/16/2015','MM/DD/YYYY')
use
TIMESTAMP WITH TIME ZONE '2015-08-16 00:00:00+02';
in second query.

How can I compare two datetime fields but ignore the year?

I get to dust off my VBScript hat and write some classic ASP to query a SQL Server 2000 database.
Here's the scenario:
I have two datetime fields called fieldA and fieldB.
fieldB will never have a year value that's greater than the year of fieldA
It is possible the that two fields will have the same year.
What I want is all records where fieldA >= fieldB, independent of the year. Just pretend that each field is just a month & day.
How can I get this? My knowledge of T-SQL date/time functions is spotty at best.
You may want to use the built in time functions such as DAY and MONTH. e.g.
SELECT * from table where
MONTH(fieldA) > MONTH(fieldB) OR(
MONTH(fieldA) = MONTH(fieldB) AND DAY(fieldA) >= DAY(fieldB))
Selecting all rows where either the fieldA's month is greater or the months are the same and fieldA's day is greater.
select *
from t
where datepart(month,t.fieldA) >= datepart(month,t.fieldB)
or (datepart(month,t.fieldA) = datepart(month,t.fieldB)
and datepart(day,t.fieldA) >= datepart(day,t.fieldB))
If you care about hours, minutes, seconds, you'll need to extend this to cover the cases, although it may be faster to cast to a suitable string, remove the year and compare.
select *
from t
where substring(convert(varchar,t.fieldA,21),5,20)
>= substring(convert(varchar,t.fieldB,21),5,20)
SELECT *
FROM SOME_TABLE
WHERE MONTH(fieldA) > MONTH(fieldB)
OR ( MONTH(fieldA) = MONTH(fieldB) AND DAY(fieldA) >= DAY(fieldB) )
I would approach this from a Julian date perspective, convert each field into the Julian date (number of days after the first of year), then compare those values.
This may or may not produce desired results with respect to leap years.
If you were worried about hours, minutes, seconds, etc., you could adjust the DateDiff functions to calculate the number of hours (or minutes or seconds) since the beginning of the year.
SELECT *
FROM SOME_Table
WHERE DateDiff(d, '1/01/' + Cast(DatePart(yy, fieldA) AS VarChar(5)), fieldA) >=
DateDiff(d, '1/01/' + Cast(DatePart(yy, fieldB) AS VarChar(5)), fieldB)
Temp table for testing
Create table #t (calDate date)
Declare #curDate date = '2010-01-01'
while #curDate < '2021-01-01'
begin
insert into #t values (#curDate)
Set #curDate = dateadd(dd,1,#curDate)
end
Example of any date greater than or equal to today
Declare #testDate date = getdate()
SELECT *
FROM #t
WHERE datediff(dd,dateadd(yy,1900 - year(#testDate),#testDate),dateadd(yy,1900 - year(calDate),calDate)) >= 0
One more example with any day less than today
Declare #testDate date = getdate()
SELECT *
FROM #t
WHERE datediff(dd,dateadd(yy,1900 - year(#testDate),#testDate),dateadd(yy,1900 - year(calDate),calDate)) < 0