Snowflake date_trunc to remove time from date - snowflake-cloud-data-platform

I have snowflake column which contains date in yyyy-mm-dd hh:MM:ss format.
I use the below function
date_trunc('DAY', '2019-09-23 12:33:25')
Output : 2019-09-23 00:00:00
Expected as per documentation : 2019-09-23
Is it a bug or is there any other way to remove the time component altogether ?

Depending on what you're wanting to do with the date, having a midnight time is fine.
If you really must get rid of it, this will work:
cast(date_trunc('DAY', '2019-09-23 12:33:25') as date)

date_trunc as the documentation say, truncates a timestamp to values on different grain. But the result is still a timestamp, thus the output format.
if you want just the truncated date, casting to date as cmcau mentions is a simple way to go. But if you are casting to date there is no need to truncate as they are the same value, thus '2019-09-23 12:33:25'::date should be all you need.

In certain environments like Mode Analytics, casting to date like some of the other answers mention still displays a 00:00:00 on the end. If this is the case and you are only using the date for display purposes, you can take your truncated date and cast it to varchar instead like this: '2019-09-23 12:33:25'::date::varchar
Note, I would only recommend this if the other answers are not working for you.

Related

What is the fastest way to get only time part of datetime

My problem is that we are using Datetime column in our database but we need to show our date in different calendar like Hijri or Shamsi With the Time.
So with complex query cost of conversion is very high and i need an efficient way to get Time and concatenate it with the converted date part.
Right now i am using these approaches
1-
CONCAT(dbo.getShamsiDate( JI.Job_start_execution_date ),' ',FORMAT(JI.Job_start_execution_date,'HH:mm:s')) AS [JobStart]
JobStart
1399/05/13 19:25:47
2-
SELECT CONVERT(VARCHAR(10), #Job_start_execution_date , 108) JobStart;
JobStart
----------
14:43:35
My question is this:
Which one is faster or be suited and is there any faster way?
Just cast/convert it to a time, as that retain the correct typing (it's still a date and time data type):
SELECT CONVERT(time(0),datetimevalue), CAST(datetimevalue AS time(3))
As the value is a datetime, the value will be accurate to 1/300th of a second, however, choose a precision appropriate for your data.

TSQL Translation into Snowflake

I have SQL which I run against the on premises database. In the WHERE clause I am narrowing it down to year
WHERE YEAR(SRCSYS_ADD_DATE_TIME)=2020
and I get the results
In Snowflake work sheet I am using
WHERE EXTRACT(YEAR FROM TO_DATE(SRCSYS_ADD_DATE_TIME))=2020
and I am getting this message
Date '2020-05-28-20.42.09.724117' is not recognized'
Please need help.
Snowflake's automatic date-time parsing isn't recognizing your period separated timestamp formatting.
You'll need to explicitly specify a format to read the string during conversion:
EXTRACT(
YEAR FROM
TO_DATE('2020-05-28-20.42.09.724117', 'YYYY-MM-DD-HH24.MI.SS.FF')
) = 2020
bkan.
The problem is the timestamp format. If you don't specify a timestamp format, Snowflake will try to autodetect. In this case it can't, so you'll have to specify the timestamp format:
select year(to_timestamp('2020-05-28-20.42.09.724117', 'YYYY-MM-DD-HH24.MI.SS.FF6'));
If you don't want to specify the timestamp format, your best option is using YYYY-MM-DD HH24:MM:SS.FFFFF (or some other precision of fractional seconds) like this:
select year('2020-05-28 20:42:09.724117'::timestamp);
The second option reformats the timestamp to the standard format, and the ::timestamp syntax casts it to a timestamp.

AngularJS layered date filter for database submission

I am having trouble with date submissions to a database. When date and time are both needed, I parse the values from the database as a timestamp, which gives me the value of the date and time in milliseconds since 1970. Using the AngularJS date filter, I am able to display the value in a user-friendly way.
$filter('date')(1380292078000, 'MM/dd/yyyy hh:mm a'); => 09/27/2013 10:27 AM
But this format as a timestamp when I send the value back to the database, my code throws an error. The database wants the date to be displayed in a different format.
java.lang.IllegalArgumentException: Timestamp format must be yyyy-mm-dd hh:mm:ss
So I add a second filter to convert the value date representation of the millisecond count (the user might have changed the value), but I am just getting a clone of the first date representation.
$filter('date')('09/27/2013 10:27 AM', 'yyyy-mm-dd hh:mm:ss') => 09/27/2013 10:27 AM
Here is a link to the fiddle I wrote to test this. Are we not able to stack filter conversions on top of each other? I had a thought to convert the first conversion result into milliseconds to use as a source for the second conversion, but I didn't see a method to accomplish this in the date documentation. If that would be the only solution, though, I am sure I could whip something up. Because Java has mostly deprecated functions to work with dates, I feel it would be simpler to handle this on the Javascript/AngularJS side.
The date filter will only work with a JSON date string (see source).
You can get around your problem by converting to a date object:
$scope.date2 = $filter('date')(new Date($scope.date), 'yyyy-MM-dd hh:mm:ss')
See updated fiddle
However... You should be validating and formatting this input on the server side. You can't trust data coming from a javascript application to be in the correct or expected format. I'd recommend just posting back $scope.date and allowing the server to format in your database format. By doing the yyyy-MM-dd hh:mm:ss formatting on the client-side, you're tightly coupling your user interface to database implementation and that's generally considered a bad idea.

How to display time in HH:MM format?

How to display a time HH:MM format?
Using SQL 2000
In my Database time column datatype is varchar
Example
Table1
Time
08:00:00
09:00:23
214:23:32
Here I want to take only 08:00, 09:00, 214:23
How to make a query for this condition?
Whilst you could choose to turn the varchar into a datetime and format it there, assuming you do not want rounding, you could could shortcut the process. (Assuming the time format in the varchar is consistent)
select left('08:00:00',5)
Edit : Question altered, now I would use
select substring('243:00:00', 1, len('243:00:00') - 3)
and replace the value I used with the appropriate field
Cheap and cheerful.
I think Andrew was onto a correct solution, just didn't address all of the possibilities:
SELECT LEFT(Time, LEN(TIME)-3)
should trim off the last 3 characters.
Now, if you want to round up, that's another story....

SqlDateTime overflow Exception

I am trying to insert a time only value, but get the following error
ex {"SqlDateTime overflow. Must be between 1/1/1753 12:00:00 AM and 12/31/9999 11:59:59 PM."} System.Exception
From the front end, the time is selected using the "TimeEdit" control, with the up and down arrows. The table in SQL Server has the fields set as smalldatetime. I only need to store the time. I use the following to return data to the app
select id,CONVERT(CHAR(5),timeFrom,8)as timeFrom,CONVERT(CHAR(5),timeTo,8)as timeTo
FROM dbo.Availability
where id = #id
and dayName = #weekday
How do I pass time only to the table?
Edit ~ Solution
As per Euardo and Chris, my solution was to pass a datetime string instead of a time only string. I formatted my result as per Time Format using "g".
Thanks
You can set the date to 1/1/1753 wich is date min value for datetime in MSSQL and then add the hour you want to store. Of course you have to consider this every time you need to get the value, but you can wrap that with some helpers.
Or you can use MSSQL 2008 and use the new TIME datatype.
Pick a date that is in the range(ie, 1/1/1970) and use it for everything you insert.
If you are only keeping track of the time, think about storing it in an int as an offset from midnight in whatever granualarity you need (seconds, minutes, hours, ...). You can then convert it to a TimeSpan in your code using the appropriate TimeSpan.From??() method. To go back the other way, you can use TimeSpan.Total?? and truncate if need be. If you need to do manual queries you can write a SQL function that will convert hours/mins/seconds to the equivalent offset.
I prefer this over using a datetime and picking an arbitrary day as it makes the purpose of the field clearer, which reduces confusion.
there is no such thing as Time in SQL, there is only DateTime.
For your purpose, I would use something like this to only return the time portion.
SELECT (GETDATE() - (CAST(FLOOR(CAST(GETDATE() as FLOAT)) AS DateTime)))
where GETDATE() is the datetime you want to filter.
When setting the time in the database, you will have to add '01/01/1901' or '01/01/1753' to the time.
Dont use CAST and Convert to varchar when working with datetime, its slow. Stick to floating numerical operations.

Resources