How to convert UNIX epoch days to DATE in Snowflake? - sql

I have some values which correspond to the number of days since Epoch and want to store them in DATE column in Snowflake.
Example:
33057
Corresponds to Sunday, July 4, 2060
Would be really helpful if someone can point me to the correct Snowflake documentation(if available out of the box) for such

I think this will work:
select dateadd(day, <your number> - 33057, '2060-07-04')
So, for the specific conversion of "33057", this would be:
select dateadd(day, 33057 - 33057, '2060-07-04')
But it should work for any integer.

TO_TIMESTAMP_x(numeric_expr) is what your looking for. And if you only want the date part I would then truncate via ::DATE
numeric_expr
A number of seconds (if scale = 0 or is absent) or fractions of a second (e.g. milliseconds or nanoseconds) since the start of the Unix epoch (1970-01-01 00:00:00 UTC). If a non-integer decimal expression is input, the scale of the result is inherited.
if you have milliseconds you can use the TO_TIMESTAMP_x(numeric_expr, scale) form
select to_timestamp(12334567) as t_from_s
,to_timestamp(12334567000, 3) as t_from_ms;
gives
T_FROM_S T_FROM_MS
1970-05-23 18:16:07.000 1970-05-23 18:16:07.000
We use the _NTZ variant for all our usages, as we have all data in UTC from the servers.

Related

How to convert epoch to datetime in bigquery?

I have a column in a bigquery table with epoch values in milliseconds. These include negative epoch values for dates before 1970 also.
How do I convert them into DATETIME format using Standard and Legacy SQL to the format:1998-10-18 13:45:55?
This should work even for dates before 1970 .i.e. negative epoch values.
I tried EXTRACT(DATETIME FROM TIMESTAMP_MILLIS(-2494865480000));
But it returns me a value with a T included in it:
1890-12-10T05:48:40
Putting aside that I don't understand your expectation on dates before 1970 you can use FORMAT_DATETIME function to format your date result as follow:
SELECT FORMAT_DATETIME("%F %T", EXTRACT(DATETIME FROM TIMESTAMP_MILLIS(-2494865480000)))
The result of this SQL is
1890-12-10 05:48:40

Convert DOUBLE column to TIMESTAMP in Firebird database

I have a Firebird database that saves the datetime field as a DOUBLE. I have created a ColdFusion datasource connection, so I can query the data remotely. While the rest of the data is being returned correctly, the datetime field is unreadable. I have tried using CAST and CONVERT to no avail. How can I convert this to a timestamp?
An example of the data stored is: 43016.988360
You can't just convert a DOUBLE PRECISION to a TIMESTAMP, not without explicitly defining how you want it mapped and writing that conversion yourself (or hoping there is an existing third-party UDF that does this for you).
A TIMESTAMP in Firebird is a date + time represented as an 8 byte value, where the date range is from January 1, 1 a.d. to December 31, 9999 a.d. and the time range is 00:00 to 23:59.9999 (so, 100 microsecond precision).
A DOUBLE PRECISION is - usually - the wrong type for storing date and time information, and as you haven't provided how that double value should be interpreted, we can't help you other than saying: there is no default method in Firebird to do this.
Based on the comments below, it looks like the value is a ColdFusion date value stored as double precision with the number of days since December 30th 1899, see also why is ColdFusion's Epoch Time Dec 30, 1899?. If this is really the case, then you can use the following for conversion to a TIMESTAMP:
select timestamp'1899-12-30 00:00' + 43016.988360 from rdb$database
Which will yield the value 2017-10-08 23:43:14.304. Using the value 43182.4931754 from the comments will yield 2018-03-23 11:50:10.354. That is a millisecond off from your expectation, but that might be a rounding/presentation issue, eg I get the exact expected date if I use 43182.49317539 instead.
I would strongly suggest you carefully test this with known values.

SAS timestamp from scientific notation to yyyy/mm/dd hh:mm:ss

Problem:
My timestamp is being displayed in scientific notation. I would like to display the column without scientific notation, and create a second column formatted as a long date, yyyy/mm/dd hh:mm:ss.
Steps taken:
I've already converted the column from a UNIX Epoch (1960) timestamp to SAS time (1970) timestamp. But scientific notation persists. I tried date20. doesn't do the trick, either.
Timestamp in Scientific Notation
My current insufficient code fails to format the timestamp column as a date.
proc print data=heart._23a;
format timestamp date9.;
run;
Results:
It results in no errors, but it redimensions my matrix to a 1x3. I need to obtain a matrix of the same dimension, just with a reformatted timestamp. I appreciate any help, but please keep it simple, I am in unknown territory!
datetime17. is the standard timestamp format in SAS, though you have many other choices as well. ymddttm. is the closest to what you're looking for, I believe.
One important distinction here: SAS has two concepts, date and datetime. date is number of days since 1/1/1960 and has no time part, while datetime is number of seconds since 1/1/1960 00:00:00 and has both time and date. You can use datepart to convert datetime -> date, or dhms to convert date -> datetime.
Your question also seems to get the two epochs backwards. UNIX epoch is 1970. SAS epoch is 1960.
Finally, if you want to display the raw number of seconds, use w.d format instead of bestw.d format - format timestampvar 14. for example, where w is number of characters (digits) wide total including decimal.

SELECT average timestamp difference in JPA with Postgres and HSQL

I have a table with two timestamp columns, startTime and stopTime, and I would like to calculate the average difference of these timestamps in my table. I have a solution that works in Postgres and in HSQLDB (which I use for local unit testing) but not both, and I'm having trouble trying to figure out a common solution.
Postgres:
select EXTRACT(EPOCH FROM(avg(m.stopTime - m.startTime))) from Measures m
HSQL:
select avg(FUNC('UNIX_TIMESTAMP', m.stopTime) - FUNC('UNIX_TIMESTAMP', m.startTime) from Measures m
Is there a way to use the same query for both databases? All of the functions I've found seem to only be supported in one database or the other.
I think my main problem is that there isn't a common function to convert a timestamp to seconds in order to perform the calculation. EPOCH is only compatible with Postgres and UNIX_TIMESTAMP is only compatible with HSQL.
The crux of your problem is converting the dates and timestamps down to a number of seconds. Instead of using epoch, I'll use a julian date for the date. I'll convert the julian date to seconds, then add the number of seconds since minight for each timestamp being compared. The following query does not calculate the difference, it simply converts the date to a number that's similar on both platforms .. you'll have to do this once for each date being compared. note: replace "current"timestamp" with m.startTime and m.stopTime respectively.
select
(to_number(to_char(current_timestamp,'J'),'99999999999999999999')*86400/*convert from julian days to julian seconds*/)
+ (to_number(to_char(current_timestamp,'HH'),'99') * 3600) /*Hours to seconds */
+ (to_number(to_char(current_timestamp,'MM'),'99') * 60) /*Minutes to seconds */
+ (to_number(to_char(current_timestamp,'SS'),'99') /*add in the seconds*/
Ugly as sin, I know-- perhaps you can rewrite it easier as function, but as I don't know hsqls full feature set, I'll leave it in this form rather than using a CTE or function.

MySql difference between two timestamps in Seconds?

Is it possible to calculate difference between two timestamps in Mysql and get output result in seconds? like 2010-11-29 13:16:55 - 2010-11-29 13:13:55 should give 180 seconds.
Thank you
I do not think the accepted answer is a good universal solution!
This is because the UNIX_TIMESTAMP() function fails for DATEs before 1970-01-01 (and for dates in the far future using 32 bit integers). This may happen easily for the day of birth of many living people.
A better solution is:
SELECT TIMESTAMPDIFF(SECOND, '2010-11-29 13:13:55', '2010-11-29 13:16:55')
Which can be modified to return DAY YEAR MONTH HOUR and MINUTE too!
Use the UNIX_TIMESTAMP function to convert the DATETIME into the value in seconds, starting from Jan 1st, 1970:
SELECT UNIX_TIMESTAMP('2010-11-29 13:16:55') - UNIX_TIMESTAMP('2010-11-29 13:13:55') as output
Result:
output
-------
180
An easy way to deal with if you're not sure which value is bigger than the other -- use the ABS function:
SELECT ABS(UNIX_TIMESTAMP(t.datetime_col1) - UNIX_TIMESTAMP(t.datetime_col2)) as output
TIMESTAMPDIFF method only works with datetime format. If you want the difference between just two times like '11:10:00' minus '10:20:00' then use
select TIME_TO_SEC('11:10:00')-TIME_TO_SEC('10:20:00')