String of date time convert to date time in SQL Server - sql-server

I have this string which is a combination of date and time but in string format meaning that it has no space. I parsed it from a very long string but I now have or need to convert it to a standard date and time.
This is my string for date and time:
141007024755
This is how I parsed it from a very long string of data
[date&time] = SUBSTRING(#ProductCode, 27, 12)
This is the format I'm expecting but can't do it.
2014-10-07 02:47:55.000
Can anyone give me a hint on how to do this? An advice perhaps.
Thanks.

If the string is always 12 characters long you could try this:
select cast(stuff(stuff(stuff('141007024755', 7,0,' '), 10,0,':'), 13,0,':') as datetime)
Basically it uses the stuff function to insert a space between the date and time parts and colons between the different time parts producing a string like141007 02:47:55that can be converted todatetimeusingcast.

Assuming the dates are formatted exactly as your sample string, you can just keep chopping up the string and appending it back together and cast the result to date. Simple function like this may help:
CREATE FUNCTION dbo.udf_ReturnDateFromString(#DateString AS VARCHAR(14))
RETURNS DATETIME
AS
BEGIN
SET #DateString = '20' + #DateString
RETURN CAST(LEFT(#DateString, 4) + '-' +
SUBSTRING(#DateString, 5, 2) + '-' +
SUBSTRING(#DateString, 7, 2) + ' ' +
SUBSTRING(#DateString, 9, 2) + ':' +
SUBSTRING(#DateString, 11, 2) + ':' +
SUBSTRING(#DateString, 13, 2) AS DATETIME)
END;
GO
SELECT dbo.udf_ReturnDateFromString('141007024755');
The result is:
2014-10-07 02:47:55.000
You get the idea. This was done on SS 2008 R2.

Related

Fix datetime string in SQL Server

I have a table with 43 000 000 rows. In datetime column data looks 2020.04.22T04:39:29.359 and it's of type VARCHAR.
It looks like an ISO format but there are ., and for ISO I need -.
What is the best way to convert the values in these rows to datetime?
One of my variant was subst . to -:
UPDATE table
SET [Column 3] = REPLACE([Column 3], '.', '-');
but then I need to cut a microseconds from the end.
How to do this cut?
Or maybe you can advice more truish way.
You may use TRY_CONVERT here, after first doing a bit of massaging to bring your raw datetime strings into a format which SQL Server recognizes:
UPDATE yourTable
SET new_dt_col = TRY_CONVERT(
datetime,
REPLACE(LEFT(dt_col, 19), '.', '-') + '.' + RIGHT(dt_col, 3)
);
To be explicit, the replacement logic used above would first convert this:
2020.04.22T04:39:29.359
into this:
2020-04-22T04:39:29.359
You may verify for yourself that the following conversion works correctly:
SELECT TRY_CONVERT(datetime, '2020-04-22T04:39:29.359');
If every single row in the table has the date that follows the format 2020.04.22T04:39:29.359 you can do the following update statement:
UPDATE table
SET [Column 3] = SUBSTRING([Column 3],1,4) + '-' + SUBSTRING([Column 3],6,2) + '-' + SUBSTRING([Column 3],9,15)
To only fix the 5th and 8th character without affecting the "." character from the microseconds.
After that you should be able to do the conversion to datetime.

Migrate SQL Server functions to PostgreSQL

How can I do these same conversions that are written in SQL Server to PostgreSQL.
These are the data I receive:
#AVLData_GPSElement_Longitude #AVLData_GPSElement_Latitude
D224E31D F8C95DB9
This is the conversion that is written in SQL Server.
SUBSTRING(CONVERT(VARCHAR(50), CONVERT(INT, CONVERT(VARBINARY, #AVLData_GPSElement_Latitude, 2))), 1, 3) + '.' + SUBSTRING(CONVERT(VARCHAR(50), CONVERT(INT, CONVERT(VARBINARY, #AVLData_GPSElement_Latitude, 2))), 4, 7)
SUBSTRING(CONVERT(VARCHAR(50), CONVERT(INT, CONVERT(VARBINARY, #AVLData_GPSElement_Longitude, 2))), 1, 3) + '.' + SUBSTRING(CONVERT(VARCHAR(50), CONVERT(INT, CONVERT(VARBINARY, #AVLData_GPSElement_Longitude, 2))), 4, 7)
and the result it gives is the following:
#MOPO_LAT #MOPO_LON
-12.102099900 -76.933449900
So far I have managed to do this conversion so far:
SUBSTRING(CONVERT(VARBINARY, AVLData_GPSElement_Latitude, 2)::INTEGER ::VARCHAR FROM 1 FOR 3) + '.' + SUBSTRING(CONVERT(VARBINARY, AVLData_GPSElement_Latitude, 2)::INTEGER ::VARCHAR) FROM 4 FOR 7);
but my big question arises in this function:
CONVERT (VARBINARY, #AVLData_GPSElement_Latitude, 2)
I don't know how to translate it because I don't find much information about it.
I am working on conversions of teltonika fm920 gps equipment.
I appreciate your help in advance.
This function is first converting hex to an integer. F8C95DB9 is -121020999. Use the technique here. Stick an x on the front so bit(32) will cast it as hex, then cast that to a 32 bit integer.
select ('x'||'F8C95DB9')::bit(32)::int4
int4
------------
-121020999
Then divide by 10000000.0.
select ('x'||'F8C95DB9')::bit(32)::int4 / 10000000.0 as lat;
lat
----------------------
-12.1020999000000000
And at that point I would stop and leave further formatting to the display layer.
Note: If you're working with Latitude and Longitude, consider PostGIS.

formatting datetime to varchar with padded zeros

I have the following field called "MaterialPrice". It is a data type of -
DECIMAL (18,2)
So a sample values is "10.88"
What I need to change it to is something like below -
0000000000000**1088**0
So the field length is 18, where the last character (to the left is always 0) and the characters in front of the original value are padded with zeros also.
Another example would be
501.02
would be
000000000000**50102**0
Any help would be appreciated.
Thanks
If I understand correctly the requirement, you could as the below:
DECLARE #val DECIMAL(18, 2) = 501.02
SELECT REPLICATE(0, 18 - LEN(#val)) + '**' + REPLACE(CAST(#val AS VARCHAR(50)), '.', '') + '**0'
Result: 000000000000**50102**0
I would:
Multiply by 100,
cast to string,
Measure length,
Concatenate: (17-length) "0"s, "**", the string number and "**0

Convert from 4 digit Military time to Standard time

I am using SQL Server 2016 and I'm trying to convert military time to standard time. The military time is a 4 digit integer and I'm trying to get the standard time format (00:00 am/pm).
I ran a simple CASE statement that made it standard but without ':' and 'am/pm'.
CASE
WHEN SA_BEGTIME between 0 and 1259 then SA_BEGTIME
WHEN SA_BEGTIME between 1300 and 2400 then SA_BEGTIME - 1200
ELSE ''
END as Time
Results
How do I convert it so that it is in the right format: '00:00 am/pm'
Thank you!
You can split it into parts with integer division and modulo, cast it to a VARCHAR and then you can convert it to a TIME:
declare #x int = 109
select cast(cast(#x / 100 as varchar(2)) + ':' + cast(#x % 100 as varchar(2)) as time)
Or you can use the new TIMEFROMPARTS() function (SQL Server 2012+):
declare #x int = 109
select TIMEFROMPARTS(#x / 100,#x % 100, 0, 0, 0)
You can then format it however you'd like.
Assuming your data is stored as an integer, and also assuming there is not invalid time stored (i.e. values above 2400 or below 0) you can use the following:
declare #TheTime int = 900
select right(convert(varchar(20),
cast(stuff(right('0000' + convert(varchar(4),#TheTime),4),3,0,':')
as datetime),100),7)
-------
9:00AM
Sorry for the density of the solution. This is what I did:
Convert #TheTime to varchar(4)
Add a string of zeros at the front
Take the rightmost 4 characters from this new string
Stuff a colon sign in the middle of this new string
Cast the string as datetime
Convert back to string using 100 as the style indicator to get AM/PM
Get the right most 7 characters of the string.
I am sure there are more elegant ways, but this one works for me quite well.
I'm using the solution that #BaconBits provided but I had to make a tweak because 2400 was a valid representation but it failed with that code. Here's the tweaked solution:
declare #x int = 2400
select TIMEFROMPARTS((#x / 100) % 24,#x % 100, 0, 0, 0)
I needed to convert a datetime field where the time was military to just the time in AM/PM format. This worked beautifully.
Left(convert(varchar(20), cast(MyDateField as time),100),7)
You can use convert to get n appropriate presentation of time.
declare #mt varchar(4) = '1500'
select convert(varchar, cast(left(#mt, 2) + ':' + right(#mt, 2) as time), 0)

Convert GETDATE() to YYYYMMDDhhmmss as derived column

I'm trying to convert getdate to a string in YYYYMMDDHHmmss format without much luck. I need to do this in SSIS as a derived column.
I've tried using Datepart, but it's not working.
Datepart("YYYY",(GETDATE())) & datepart("MM",MONTH(GETDATE())) & DATEPART("DD",(GETDATE())) & DATEPART("HH",(GETDATE()) & DATEPART("MM",(GETDATE())) & DATEPART("SS",(GETDATE()))
Any clues what I'm doing wrong?
Try this:
(DT_STR,4,1252)DATEPART( "yyyy" , getdate() ) +
RIGHT("0" + (DT_STR,4,1252)DATEPART( "mm" , getdate() ), 2) +
RIGHT("0" + (DT_STR,4,1252)DATEPART( "dd" , getdate() ), 2) +
RIGHT("0" + (DT_STR,4,1252)DATEPART( "Hh" , getdate() ), 2) +
RIGHT("0" + (DT_STR,4,1252)DATEPART( "mi" , getdate() ), 2) +
RIGHT("0" + (DT_STR,4,1252)DATEPART( "ss" , getdate() ), 2)
This should do it, it simply casts GETDATE() as a string and replaces unnecessary characters.
LEFT(REPLACE(REPLACE(REPLACE((DT_STR,30,1252)GETDATE(),"-",""),":","")," ",""),14)
DATEPART
Returns an integer representing a datepart of a date.
The operation you would like to do is string concatenation for those values. The operator for string concatenation in the SSIS Expression language is +. However, + is also the addition operator for the integer data type so if you use
Datepart("YYYY",(GETDATE())) + datepart("MM",MONTH(GETDATE()))
You would not get 201410. Instead, you'd have a value of 2024. Now, you can use addition to get you were you want to be, you'll just need multiplication as well. (2014 * 100) + 10 will equal 201410 and returns the value as integer so perhaps that fits with what you want. However, once you build out to YYYYMMDDHHMMSS you're probably outside the bounds of Int32 and I'm too lazy to look it up, possibly Int64.
The better approach will be to cast the results of the DatePart to a string and use concatenation. But, there's still a problem there. 05 as an integer is just 5. That leading zero is an artifact of presentation so if you want it in your value, you'll need to explicitly put it there. The preferred method of doing so is to concatenate a leading 0 and then shave off the last 2 characters. For October-December, you'll have a 3 character string 010/011/012 that then gets turned back into 10/11/12. The remaining months will become 01/02/../09 and taking the right two most characters yields the correct values.
RIGHT(("0" +(DT_WSTR, 2) MONTH(GETDATE())), 2)
The & isn't a concatenation operator in this languages so that is problem #1 with your formula.
Here's what worked for me.
(DT_STR, 4, 1252)DATEPART("YYYY", GETDATE())+(DT_STR,2,1252)DATEPART("MM", GETDATE())+(DT_STR,2,1252)DATEPART("DD", GETDATE())+(DT_STR,2,1252)DATEPART("HH", GETDATE())+(DT_STR,2,1252)DATEPART("MI", GETDATE())+(DT_STR,2,1252)DATEPART("SS", GETDATE())
This should give you what you want:
REPLACE(REPLACE(REPLACE(CONVERT(varchar, GETDATE(), 20), '-', ''), ':', ''), ' ', '')
See here for more date formats you can use with convert

Resources