Converting a 5 digit int into time - sql

In a legacy system (SQL Server 2005) I have a column that stores a 5 digit integer (ie 86340) as time. The legacy application shows 86340 as 23:59:00. I am unsure how how to translate that 5 digit integer into a date-time data type using SQL.

SQL Server 2012+ has TIMEFROMPARTS function:
TIMEFROMPARTS ( hour, minute, seconds, fractions, precision )
Returns a time value for the specified time and with the specified precision.
Which is similiar to Excel's TIME:
TIME(hour, minute, second)
Excel version could handle values over 0-60 range:
Minute Required. A number from 0 to 32767 representing the minute. Any value greater than 59 will be converted to hours and minutes.
And SQL counterpart cannot do that.
It looks like that value is simply number of seconds so you could use:
DECLARE #A1 INT = 86340;
SELECT DATEADD(second, #A1,CAST('00:00:00' AS TIME));
DBFiddle Demo
EDIT:
As SQL Server 2005 does not support TIME data type, you could use DATETIME instead and skip date part in application.
DECLARE #A1 INT = 86340;
SELECT DATEADD(second, #A1,CAST('00:00:00' AS DATETIME));
DBFiddle Demo2

Since the value you have is an integer representation of the seconds since midnight, you have a couple of choices in SQL Server 2005. You can either render the value as a VARCHAR, which is readable, you can render it as DATETIME, which appends the date information, or you can maybe pull in a date from another field to get an meaningful DATETIME for your value.
SELECT CONVERT(VARCHAR(12), DATEADD(SECOND, 86340, 0), 114) AS [InVarchar];
+--------------+
| InVarchar |
+--------------+
| 23:59:00:000 |
+--------------+
SELECT DATEADD(SECOND, 86340, 0) AS [InDatetime];
+-------------------------+
| InDatetime |
+-------------------------+
| 1900-01-01 23:59:00.000 |
+-------------------------+
SELECT DATEADD(SECOND, 86340, CAST('2018-09-05' AS DATETIME)) AS [InDatetimeWithDate];
+-------------------------+
| InDatetimeWithDate |
+-------------------------+
| 2018-09-05 23:59:00.000 |
+-------------------------+

USE below query:
SELECT CONVERT(DATETIME, #Column_Name)
FROM Table;

Related

A proper way to combine date of datetime column with time of datetime column in SQL Server 2000?

My table has two columns, both of type datetime. I would like to combine only the date part of the 1st datetime column with the time part of the 2nd datetime column.
To best describe my question, suppose my table is created in the following way:
CREATE TABLE mytable(
ID INT identity(1,1) PRIMARY KEY,
startDate DATETIME,
startTime DATETIME,
)
INSERT INTO mytable(startDate,startTime) VALUES(GETDATE()-10, GETDATE()-1/3);
INSERT INTO mytable(startDate,startTime) VALUES(GETDATE()-20, GETDATE()-RAND());
INSERT INTO mytable(startDate,startTime) VALUES(GETDATE()-68, GETDATE()-RAND());
I used the following code to do my query:
SELECT *,
CAST(REPLACE(startTime, CAST(startTime AS nchar(11)),CAST(startDate AS nchar(11))) AS DATETIME) [method1:fail],
CAST((CAST(startDate AS nchar(11)) + ' ' + subString(CAST(startTime AS nchar(20)),13,20)) AS datetime) [method2:fail],
CONVERT(VARCHAR, CONVERT(DATE, startDate)) + ' ' + CONVERT(VARCHAR(12), CONVERT(TIME, startTime)) [method3:success]
FROM mytable
However, both method 1 and 2 fail and I don't know why. The error is that the combined result would clear the second to 0.
ID startDate startTime method1:fail method2:fail method3:success
1 2018-01-09 13:56:19.490 2018-01-19 13:56:19.490 2018-01-09 13:56:00.000 2018-01-09 13:56:00.000 2018-01-09 13:56:19.490
2 2017-12-30 13:56:19.490 2018-01-19 11:47:20.133 2017-12-30 11:47:00.000 2017-12-30 11:47:00.000 2017-12-30 11:47:20.133
3 2017-11-12 13:56:19.493 2018-01-19 11:43:41.587 2017-11-12 11:43:00.000 2017-11-12 11:43:00.000 2017-11-12 11:43:41.587
Method 3 works in SQL Server 2008 and newer (I am using SQL Server 2014 on my own computer but my server is 2000). But it would fail SQL server 2000 as date and time data types were introduced in SQL server 2008. Could anybody provide a workaround for SQL Server 2000?
First, if a DATETIME is to represent a DATE, it shouldn't have a time component. It's not possible to have No time component, so it should be set to midnight.
Second, if a DATETIME is to represent a TIME, it shouldn't have a DATE component. That's not possible either, so it should have a date of 0. Which will make note sense shortly.
Strip away the time :
DATEADD(day, DATEDIFF(day, 0, StartDate), 0)
-- Calculate the number of WHOLE days between day zero and StartDate
-- Add that number of days to day zero
Strip away the date :
DATEADD(day, -DATEDIFF(day, 0, StartTime), StartTime)
-- Calculate the number of WHOLE days between day zero and StartTime
-- Subtract that number of days from StartTime
One you've done these things, you should be able to add them together.
Whatever you do, DO NOT USE STRING MANIPULATION :)

SQL Server datetime in format yyyy-mm-ddThh:mi:ss.mmmZ

For an XML message I need SQL server 2008 R2 to select a set of dates in the following format:
yyyy-mm-ddThh:mi:ss.mmmZ
I searched Google and Stack Overflow a bit and came to the following solution:
SELECT STUFF(CONVERT(VARCHAR(50), CAST(GETDATE() AS DATETIMEOFFSET), 127),24,4,'')
This is working fine except for cases where the milliseconds of the date are "000". In such cases it selects NULL.
Can you please help me to find a solution that also works for dates where the milliseconds are "000"?
You can use the following piece of code to play around with:
declare #timestamps table (
i int,
timestamp datetime
)
insert into #timestamps (i, timestamp)
values
(1, '2017-09-13 01:00:00.003'),
(2, '2017-09-13 02:00:00.333'),
(3, '2017-09-13 03:00:00.000'),
(4, '2017-09-13 04:00:00')
select i, timestamp, STUFF(CONVERT(VARCHAR(50), CAST(timestamp AS DATETIMEOFFSET), 127),24,4,'') from #timestamps
From what I understand, you are using stuff() to get rid of the milliseconds beyond the third decimal place.
Instead you can just specify the precision of datetimeoffset as (3) instead of letting it default to (7):
select
i
, dto3 = convert(varchar(32),convert(datetimeoffset(3),timestamp),127)
, plusZ = convert(varchar(32),timestamp,127)+'Z' --without converting to datetimeoffset
-- /* SQL Server 2012+ */, tsFormat = format(timestamp,'yyyy-MM-ddTHH:mm:ss.fffZ')
from #timestamps
rextester demo: http://rextester.com/VKXBET35937
returns:
+---+--------------------------+--------------------------+
| i | dto3 | plusZ |
+---+--------------------------+--------------------------+
| 1 | 2017-09-13T01:00:00.003Z | 2017-09-13T01:00:00.003Z |
| 2 | 2017-09-13T02:00:00.333Z | 2017-09-13T02:00:00.333Z |
| 3 | 2017-09-13T03:00:00Z | 2017-09-13T03:00:00Z |
| 4 | 2017-09-13T04:00:00Z | 2017-09-13T04:00:00Z |
| 5 | 2017-09-13T14:12:34.567Z | 2017-09-13T14:12:34.567Z |
+---+--------------------------+--------------------------+
In SQL Server 2012+ the above works as well, though you could use format() if you wanted to always have 0s for milliseconds:
format(timestamp,'yyyy-MM-ddTHH:mm:ss.fffZ')
But format() can be slower, take a look here: format() is nice and all, but… - Aaron Bertrand
You may possible need to use the same code formatting but create a case statement for when milliseconds = 0

SQL Server - add DATE part of DATETIME to TIME part of DATETIME

In SQL Server 2005 I am interrogating some old legacy data and I need to combine the date component of a datetime column with the time component from another column. Here's an example:
DateColumn: 2016-05-09 00:00:00.000
TimeColumn: 1899-12-30 12:26:00.000
I need the end result converted to the following DateTime:
ResultDateTime: 2016-05-09 12:26:00.000
I tried using:
CAST(DateColumn AS DATETIME) + CAST(TimeColumn AS TIME) AS ResultDateTime
But SQL Server 2005 doesn't recognize the type TIME.
Can someone please show me a way of doing that?
Many thanks!
convert the time column to string HH:MM:SS and add to the date column
ResultDatetIme = DateColumn + convert(varchar(10), TimeColumn, 108)
You can just use DATEADD and DATEDIFF, assuming that the time column's date portion is always 30/12/1899:
declare #t table (DateColumn datetime,TimeColumn datetime)
insert into #t(DateColumn,TimeColumn) values
('2016-05-09T00:00:00.000','1899-12-30T12:26:00.000')
select DATEADD(millisecond,DATEDIFF(millisecond,'18991230',TimeColumn),DateColumn)
from #t
Result:
-----------------------
2016-05-09 12:26:00.000
As you can see following data type supported in SQL 2005:
https://msdn.microsoft.com/en-us/library/ms187819(v=sql.90).aspx
Use datetime and smalldatetime, The smalldatetime data type stores dates and times of day with less precision than datetime. The Database Engine stores smalldatetime values as two 2-byte integers. The first 2 bytes store the number of days after January 1, 1900. The other 2 bytes store the number of minutes since midnight.
datetime values are rounded to increments of .000, .003, or .007 seconds, as shown in the following table.
SELECT CAST('2016-05-09 00:00:00.000' AS DATETIME) + CAST('1900-01-01 12:26:00.000' AS smalldatetime) AS ResultDateTime
Result: 2016-05-09 12:26:00.000
So you can use datetime and smalldatetime, hope fully that will work for you.
Let me know if any issue. love to resolve :)

Date subtraction error

I have a SQL Server table with a few columns.
One of those columns is a date and another is No of Nights.
Number of nights is always a two character varchar column with values like 1N, 2N, 3N etc depending on the number of nights up to 7N.
I want to subtract the 1 part of the 1N column from the date.
For ex: 25Oct15 - 1N = 24Oct15
Obviously I will be replacing the '1N' with the actual column name. I tried doing a trim as:
date - left(no of nights, 1)
But I get an error
Conversion failed when converting the varchar value '25Oct16' to data type int.
Sample date below
Date | NoofNIghts | Result
2016-04-26 00:00:00.000 | 1N |
2016-04-28 00:00:00.000 | 3N |
Where the result column would be the subtracted value. Any help would be great. Thanks.
SELECT DATEADD ( DAY, - CONVERT(INT, REPLACE(NoofNights, 'N', '')), getdate() ) as Result
Try this
DECLARE #V_Date DATETIME = '2016-04-26 00:00:00.000'
,#V_NoofNIghts VARCHAR(2) = '1N'
SELECT DATEADD(DAY, CAST(LEFT(#V_NoofNIghts,1) AS INT) *-1 ,#V_Date)
Well basic query should be like
Update tablename
set result= DATEADD(d, -CAST(LEFT(NoofNIghts, LEN(NoofNIghts)-1) AS INT),Date)

Two questions for formatting timestamp and number using postgresql

I am selecting a date column which is in the format "YYYY-MM-DD".
I want to cast it to a timestamp such that it will be "YYYY-MM-DD HH:MM:SS:MS"
I attempted:
select CAST(mycolumn as timestamp) from mytable;
but this resulted in the format YYYY-MM-DD HH:MM:SS
I also tried
select TO_TIMESTAMP(mycolumn,YYYY-MM-DD HH:MM:SS:MS) from mytable;
but this did not work either. I cannot seem to figure out the correct way to format this. Note that I only want the first digit of the milliseconds.
//////////////second question
I am also trying to select numeric data such that there will not be any trailing zeros.
For example, if I have values in a table such as 1, 2.00, 3.34, 4.50.
I want to be able to select those values as 1, 2, 3.34, 4.5.
I tried using ::float, but I occasionally strange output. I also tried the rounding function, but how could I use it properly without knowing how many decimal points I need before hand?
thanks for your help!
It seems that the functions to_timestamp() and to_char() are unfortunately not perfect.
If you cannot find anything better, use these workarounds:
with example_data(d) as (
values ('2016-02-02')
)
select d, d::timestamp || '.0' tstamp
from example_data;
d | tstamp
------------+-----------------------
2016-02-02 | 2016-02-02 00:00:00.0
(1 row)
create function my_to_char(numeric)
returns text language sql as $$
select case
when strpos($1::text, '.') = 0 then $1::text
else rtrim($1::text, '.0')
end
$$;
with example_data(n) as (
values (100), (2.00), (3.34), (4.50))
select n::text, my_to_char(n)
from example_data;
n | my_to_char
------+------------
100 | 100
2.00 | 2
3.34 | 3.34
4.50 | 4.5
(4 rows)
See also: How to remove the dot in to_char if the number is an integer
SELECT to_char(current_timestamp, 'YYYY-MM-DD HH:MI:SS:MS');
prints
2016-02-05 03:21:18:346
just add ::timestamp without time zone
select mycolumn::timestamp without time zone from mytable;