Different Time Stamps in Redshift - amazon-redshift

Please help me know difference in following SQL statements in Amazon Redshift: -
extract(epoch from
trunc(convert_timezone('Asia/Calcutta', getDate())
- 27)
)::bigint * 1000000
vs
trunc(convert_timezone('Asia/Calcutta',getDate())
-27)
- INTERVAL '05:30' HOUR TO MINUTE
Please help me with relevant online documents which explain in detail.

Step 1: GETDATE will return TIMESTAMP in UTC, irrespective of where Server is located.
Step 2: convert_timezone converted UTC timestamp into IST.
Step 3: -27 took converted timestamp to 27 days ago.
Step 4: trunc() removed time from timestamp, thus making it date without time in IST.
Step 5: extract converted IST date into epoch seconds.
Step 6: Interval uses datepart and quantity, where abbreviations and plurals of datepart are optional

Related

Db2: How to convert Unix / epoch time to timestamp?

I have a BIGINT value which represents a UNIX timestamp (epoch). How can I convert it to the built-in TIMESTAMP type?
As example, I want to turn 1611140400 into the related date and time. TIMESTAMP_FORMAT does not work.
You can use datetime arithmetics in Db2 and Db2 on Cloud. For Db2 on Cloud (which is running in UTC):
VALUES (TIMESTAMP('1970-01-01') + 1611140400 seconds)
Epoch is seconds since January 1st, 1970 GMT / UTC. Thus, adding your number as seconds to that date will give:
2021-01-20 11:00:00.0
If you are running in a different timezone, you need to take care of it, e.g.:
VALUES (TIMESTAMP(‘1970-01-01-00.00.00.000000’) + 1611140400 seconds + current timezone)

Nifi - How to add or subtract months from date?

I want to get two fields: Begin date and End date of last month. For example, 14-04-2020 should give me the Begin date as 01-03-2020 and End_date as 31-03-2020. I have read the Nifi Expression language docs but all it can do with a date format is add or subtract in milliseconds. This is not helpful for my use case as the number of days in a month is not fixed and conversion to milliseconds won't help.
Is there a way to achieve my use case somehow using Nifi Expression language?
#AdarshKumar
NiFI Expression Language for this Use Case would be very clunky and unreliable for different timezones, months with <> 30 days, and leap years.
Please reference this post below which goes into detail for how to get "last month":
How to insert previous month of data into database Nifi?
In the Case of NiFi you kind of have to play with the dates to get the outcome
if you have the dates you easily convert a date and then just hard set a day to get the 1st day of the month with a hard coded day
${now():toNumber():format('yyyy-MM-01')}
to get the last day of the month you can either use the script or play with the calc using epoch time.
so to get the last day of the previous month you can just use the date and convert the day into epoch time and subtract it from the epoch date to get last day of previous month
example
${now():toNumber():format('yyyy-MM-dd'):toDate('yyyy-MM-dd', 'GMT'):toNumber():minus(${now():toNumber():format('dd'):toNumber():multiply(86400):multiply(1000)}):format('yyyy-MM-dd')}
in this example above we convert the date to epoch format it to convert again, conversion happens to remove default timestamp and then we use the same formula to get just the day as a number to multiply it with 86400 seconds in a day and multiply that by 1000 for the epoch number to subtract from the date which is then formatted back into a date.
Raw Date: Thursday, August 26, 2021 11:20:31 AM
formatted: Thursday, August 26, 2021 12:00:00 AM
epoch of formatted date: 1629936000000
Subtract Epoch: 2246400000 (86400 seconds * 26 days * 1000)
result: 2021-07-31
alteratively you could first add a month and the work back to get the current day of the given month
this example is just to give you an idea of ways you can use built in date functions with epoch time to calculate the correct date, removing the issues with months that end on specific numbers.
I try UpdateAttribute to minus month
test${now():toNumber():format('yyyyMM'):minus(1)}01

postgres time conversion hh:mm:ss.us to hh:mm

Using PostgreSQL database for my attendance application.
I have a table with IN and out times (hh:mm:ss.us format).
When I subtract the times (OUT -IN) to calculate the working hours, results are not as expected due to precision.
If IN Time is "22:12:56.09"
& OUT TIme is "22:14:06.06" the difference considering only HH:mm should be 00:02 but it actually shows "00:01:09.97" which becomes "00:01" in excel using only HH:mm.
I am trying to do the time conversion from hh:mm:ss.us to hh:mm (time format) so that I can subtract the time and get the desired output.
I have done similar things in SQL Server but I did not find any function in PostgreSQL. Please advise.
First you need to truncate the seconds. Then subtract to get desired result
select
to_char(
(
to_char('22:14:06.06' :: time, 'HH24:MI'):: time -
to_char('22:12:56.09' :: time, 'HH24:MI'):: time
),
'HH24:MI'
)
Result: 00:02
General Solution:
select
to_char(
(
to_char(out, 'HH24:MI'):: time - to_char(in, 'HH24:MI'):: time
),
'HH24:MI'
)
Here the purpose of to_char() is to format result to hours:minutes and not to include seconds.
Postgres includes seconds in interval by default.
You can use the date_trunc function with timestamp.
It would work something like this:
select date_trunc('minute', out) - date_trunc('minute', in)
This would set a minute level precision on the timestamp and convert HH:mm:ss to HH:mm:00

time stamp are resetting to Zero when changed from to_date to to_char in postgresql

I need to change the following sql query to the postgres format. how can I do that?
eg:
round((TIME_TO_SEC(testruntest.endtime) - TIME_TO_SEC(testruntest.starttime))/60,2)
I tried this query and got error as "time_to_sec" is not a supported function...
Use the SQL standard EXTRACT function:
EXTRACT(epoch FROM testruntest.endtime)
The documentation describes:
For timestamp with time zone values, the number of seconds since 1970-01-01 00:00:00 UTC (can be negative); for date and timestamp values, the number of seconds since 1970-01-01 00:00:00 local time; for interval values, the total number of seconds in the interval

inconsistency between month, day, second representation of interval data type

I understand why postgresql uses month,day and second fields to representate the sql interval datatype. A month is not always the same length and a day can have 23, 24 or 25 hours if a daylight savings time adjustment is involved. this is from postgresql documentation.
But I then do not understand why this is not consequently handled both for months and days. see the following query which calculates an exact interval where the number of seconds between two points in time is exactly calculatable:
select ('2017-01-01'::timestamp-'2016-01-01'::timestamp); -->366 days.
postgresql chooses to give a result in days. not in months and not in seconds.
But why is the result days and not seconds? it is NOT defined how long days are (they can be 23,24 or 25 hours long). so why does he not give output in seconds?
Then since the length of months is also not defined, why doesn't postgresql give an output of 12 month instead of 366 days?
He does not care that the length of days is not defined, but obviously he cares that the length of month is not defined.
Why this asymmetrie?
For further explanation, see this query:
select ('10 days'::interval-'24 hours'::interval); --> 10 days -24:00:00
you see that postgresql correctly refuses to answer with 9 days. He is pretty aware of the problem that days and hours cannot be interchanged. But then again why does the first query return days?
I can't answer your question, but I think I can point you in the right direction. I think the book SQL-99 Complete, Really is the most accessible source for understanding SQL intervals. It's available online: https://mariadb.com/kb/en/sql-99/08-temporal-values/.
SQL standards describe two kinds of intervals: year-month intervals and day-time intervals. It does this to prevent month parts and day parts from appearing in the same interval, because, as you already know, the number of days in a month is ambiguous. The number of days in the interval '3' month depends on which three months you're talking about.
I think this is the verbose, standard SQL way to write your first query.
select cast(timestamp '2017-01-01' - timestamp '2016-01-01' as interval day to hour) as new_column;
new_column
interval day to hour
--
366 days
I suspect that you'll find that SQL standards have rules for what a SQL dbms is supposed to do when things like interval day to hour are omitted. PostgreSQL might or might not follow those rules.
postgresql chooses to give a result in days. not in months and not in seconds.
Standard SQL prevents month parts and day parts from appearing in the same interval. Also, the range of valid seconds is from 0 to 59.
select interval '59' second;
interval
interval second
--
00:00:59
select interval '60' second;
interval
interval second
--
00:01:00