SQL Server convert datetimeoffset to timestamp - sql-server

I have a datetimeoffset column DateEntry in my SQL Server table. When I want to convert it to a timestamp format with this query :
SELECT CAST(Table1.[DateEntry] AS timestamp)
FROM Table1
I get the following error :
Error : 529- Explicit conversion from data type datetimeoffset to
timestamp is not allowed.

TIMESTAMP in SQL Server has absolutely nothing to do with a date and time, therefore you cannot convert an existing date&time into a TIMESTAMP.
TIMESTAMP or more recently called ROWVERSION is really just a binary counter that SQL Server updates internally whenever row has been modified. You cannot set a TIMESTAMP column yourself, you can just read it out. It is used almost exclusively for optimistic concurrency checks - checking to see whether a row has been modified since it's been read, before updating it.

According to MSDN:
The timestamp data type is just an incrementing number and does not
preserve a date or a time. To record a date or time, use a datetime
data type.
If your are absolutely sure, you can use indirect conversion:
DECLARE #dto datetimeoffset = '2016-01-01 12:30:56.45678'
SELECT CONVERT(timestamp, CONVERT(varbinary(12), #dto))
See also #marc_s's answer.

Try the following script if this this is what you are trying your side
SELECT CAST(CAST(Table1.[DateEntry] AS datetime) as timestamp) FROM Table1

Related

HSQLDB inserting datetime format for SQL Server throws exception

I am trying to run unit tests for my SQL Server query. Query is simply inserting date to the table. I tried two different formats but didn't work:
parameters.addValue(STUDY_DATE, getDate(studyEvent.getStudy().getStudyDate()));
Timestamp timestamp = new Timestamp(getDate(studyEvent.getStudy().getStudyDate()).getTimeInMillis());
parameters.addValue(STUDY_DATE, timestamp);
And this is getDate() method that returns Calendar object:
private Calendar getDate(long time) {
Calendar calendar = new GregorianCalendar(TimeZone.getTimeZone("America/New_York"));
calendar.setTimeInMillis(time);
return calendar;
}
I am not sure if the problem is that SQL Server's datetime format issue or hsqldb issue. Here is my hsqldb create table:
SET DATABASE SQL SYNTAX MSS TRUE;
DROP TABLE event_study IF EXISTS;
CREATE TABLE event_study
(
STUDY_ID INT,
STUDY_DATE DATE
)
Is my hsqldb setup wrong? or should I use different datetime format for SQL Server?
Error I am getting is:
data exception: invalid datetime format; nested exception is java.sql.SQLDataException: data exception: invalid datetime format
and SQL query that I am running is:
INSERT INTO event_study(study_id, study_date)
SELECT x.*
FROM (VALUES(:study_id, :study_date))
AS x(study_id, study_date)
WHERE NOT EXISTS (SELECT 1 FROM event_study s WHERE s.study_id = x.study_id)
As you are not using strings for dates, this is not actually a formatting issue, but a Java type issue. With your table definition, DATE does not have time information. You can create and use a java.sql.Date object for the parameter value. If you want a datetime column, which includes information on time of the day, then use TIMESTAMP in your table definition and a java.sql.Timestamp for the parameter value.
In either case, you cannot use a Calendar object as parameter value.

What date format is this? (001281379300724)

Need to convert this timestamp (001281379300724) to YYYY-MM-DD hh:mm:ss format in SQL Server, if possible. Any suggestions?
This presumes the timestamp is ms since UNIX epoch. It only converts to the nearest second, but you could add ms to it(see below). It has to use two steps since dateadd requires an int. First add minutes by dividing by 60000, then add seconds.
DECLARE #yournum bigint
SET #yournum = 1281379300724
SELECT DATEADD(ss, (#yournum / 1000)%60 , (DATEADD(mi, #yournum/1000/60, '19700101')))
Gives
2010-08-09 18:41:40.000
To get ms precision: (yuck, probably a better way)
DECLARE #yournum bigint
SET #yournum = 1281379300724
SELECT DATEADD(ms, (#yournum%1000),DATEADD(ss, (#yournum / 1000)%60 , (DATEADD(mi, #yournum/1000/60, '19700101'))))
Gives
2010-08-09 18:41:40.723
The simple answer is that if this is a SQL timestamp column (a.k.a rowversion), you can't. Per the documentation for the type:
Each database has a counter that is incremented for each insert or
update operation that is performed on a table that contains a
rowversion column within the database. This counter is the database
rowversion. This tracks a relative time within a database, not an
actual time that can be associated with a clock.
...
The Transact-SQL timestamp data type is different from the timestamp
data type defined in the ISO standard.
You can get slightly closer this way:
SELECT DATEADD(MINUTE, 1281379300724/1000/60, '19700101')
Result:
2010-08-09 18:41:00.000

The conversion of a datetimeoffset data type to a datetime data type resulted in an out-of-range value

Using SQL Server 2008.I have a table called User which has a column LastLogindata with datetimeoffset datatype
The following query works on production server but not on replication server.
select top 10 CAST(LastLoginDate AS DATETIME) from User.
I am getting the following error.The conversion of a datetimeoffset data type to a datetime data type resulted in an out-of-range value.
Thanks
Check the LastLoginDate columns value like this '0001-01-01' or '0001/01/01'.
If u have means get this error ..
Try this one
select top 10 CAST(CASE when cast(LastLoginDate as varchar) = '0001-01-01 00:00:00'
THEN NULL ELSE GETDATE() end AS DATETIME) from User
If a field in database is of type datetimeoffset type, then it should contain date within range 0001-01-01 through 9999-12-31. I think the issue is the date inside your database.
Please check the official link of SQL server Click Here
I solved it this way. I had an nvarchar(max) column casted as an xml and used the T-SQL expression ISDATE() to exclude the bad rows in the where clause.
where cast(DataObject as xml).value('(/DataObjects/#LastLoginDate)[1]', 'varchar(10)') is not null
and isdate(cast(DataObject as xml).value('(/DataObjects/#LastLoginDate)[1]', 'varchar(10)')) = 1
On SQL Server 2016, I used:
CONVERT(DATETIME2, DateValueColumn)
This worked for values that were giving errors when trying to convert to DATETIME, giving the message "The conversion of a datetimeoffset data type to a datetime data type resulted in an out-of-range value." The offending values had dates of 0001-01-01, as a previous answer has mentioned.
Not sure if this works on SQL Server 2008 though.

Issue with Datetime in SQL Server 2008

I am importing some data from excel to db, the issue is I want to set the specific default value like 00/00/0000 to datetime column when there is no date available from the Excel file.
The getdate() sets the date to current one, but I want to set to a specific date, is it possible to achieve something like this.
Sure you can set a default value - but be aware: DATETIME has a valid range from 1/1/1753 through 12/31/9999 - so setting it to 0/0/0000 will NOT be a valid DATETIME value!
If you need such a value - use either DATETIME2 in SQL Server 2008 (range is from 1/1/0001 through 12/31/9999) - or use DATE (without any time - same range as DATETIME2)
Or: just make your DATETIME/DATETIME2/DATE column nullable and insert NULL when no date is present - that would be the cleanest solution.
When you use bcp or BULK INSERT or SQLBulkCopy, then you have the option of keeping NULLs.
If you don't, then you get the default for the column.
See "Keeping Nulls or Using Default Values During Bulk Import" on MSDN
If you can't (say because you get empty string not NULL) then you can use a a staging table first, then load the data from that with a combination of NULLID, ISNULL and CASE. Or use a trigger, but this will slow you down more so than doing the load in 2 steps
I'm not sure how you are performing your import, but if you wish to check whether a value is NULL and set it to a defined value then you can use the SQL IsNull(a,b) where a is the value to check and b is the value to return.
insert into [dbo].[tblSomeTable]
set [someField] = IsNull(#thisValueMayBeNull, thisValueIfNull)
Probably not a good example but should point you in the right direction.
Or once your data has been imported you could run an update script to replace all NULL dates with a fixed value;
Or you could set the date field in the database to NOT NULL and give it a defaut value.

How to convert SQL Server's timestamp column to datetime format

As SQL Server returns timestamp like 'Nov 14 2011 03:12:12:947PM', is there some easy way to convert string to date format like 'Y-m-d H:i:s'.
So far I use
date('Y-m-d H:i:s',strtotime('Nov 14 2011 03:12:12:947PM'))
SQL Server's TIMESTAMP datatype has nothing to do with a date and time!
It's just a hexadecimal representation of a consecutive 8 byte integer - it's only good for making sure a row hasn't change since it's been read.
You can read off the hexadecimal integer or if you want a BIGINT. As an example:
SELECT CAST (0x0000000017E30D64 AS BIGINT)
The result is
400756068
In newer versions of SQL Server, it's being called RowVersion - since that's really what it is. See the MSDN docs on ROWVERSION:
Is a data type that exposes automatically generated, unique binary numbers within a database. rowversion is generally used as a mechanism
for version-stamping table rows. The
rowversion data type is just an incrementing number and does not
preserve a date or a time. To record a date or time, use a datetime2
data type.
So you cannot convert a SQL Server TIMESTAMP to a date/time - it's just not a date/time.
But if you're saying timestamp but really you mean a DATETIME column - then you can use any of those valid date formats described in the CAST and CONVERT topic in the MSDN help. Those are defined and supported "out of the box" by SQL Server. Anything else is not supported, e.g. you have to do a lot of manual casting and concatenating (not recommended).
The format you're looking for looks a bit like the ODBC canonical (style = 121):
DECLARE #today DATETIME = SYSDATETIME()
SELECT CONVERT(VARCHAR(50), #today, 121)
gives:
2011-11-14 10:29:00.470
SQL Server 2012 will finally have a FORMAT function to do custom formatting......
The simplest way of doing this is:
SELECT id,name,FROM_UNIXTIME(registration_date) FROM `tbl_registration`;
This gives the date column atleast in a readable format.
Further if you want to change te format click here.
Using cast you can get date from a timestamp field:
SELECT CAST(timestamp_field AS DATE) FROM tbl_name
Works fine, except this message:
Implicit conversion from data type varchar to timestamp is not allowed. Use the CONVERT function to run this query
So yes, TIMESTAMP (RowVersion) is NOT a DATE :)
To be honest, I fidddled around quite some time myself to find a way to convert it to a date.
Best way is to convert it to INT and compare. That's what this type is meant to be.
If you want a date - just add a Datetime column and live happily ever after :)
cheers mac
My coworkers helped me with this:
select CONVERT(VARCHAR(10), <tms_column>, 112), count(*)
from table where <tms_column> > '2012-09-10'
group by CONVERT(VARCHAR(10), <tms_column>, 112);
or
select CONVERT(DATE, <tms_column>, 112), count(*)
from table where <tms_column> > '2012-09-10'
group by CONVERT(DATE, <tms_column>, 112);
"You keep using that word. I do not think it means what you think it means."
— Inigo Montoya
The timestamp has absolutely no relationship to time as marc_s originally said.
declare #Test table (
TestId int identity(1,1) primary key clustered
,Ts timestamp
,CurrentDt datetime default getdate()
,Something varchar(max)
)
insert into #Test (Something)
select name from sys.tables
waitfor delay '00:00:10'
insert into #Test (Something)
select name from sys.tables
select * from #Test
Notice in the output that Ts (hex) increments by one for each record, but the actual time has a gap of 10 seconds. If it were related to time then there would be a gap in the timestamp to correspond with the difference in the time.
for me works:
TO_DATE('19700101', 'yyyymmdd') + (TIME / 24 / 60 / 60)
(oracle DB)
Robert Mauro has the correct comment. For those who know the Sybase origins, datetime was really two separate integers, one for date, one for time, so timestamp aka rowversion could just be considered the raw value captured from the server. Much faster.
After impelemtation of conversion to integer
CONVERT(BIGINT, [timestamp]) as Timestamp
I've got the result like
446701117
446701118
446701119
446701120
446701121
446701122
446701123
446701124
446701125
446701126
Yes, this is not a date and time, It's serial numbers
Why not try FROM_UNIXTIME(unix_timestamp, format)?
I had the same problem with timestamp eg:'29-JUL-20 04.46.42.000000000 PM'. I wanted to turn it into 'yyyy-MM-dd' format. The solution that finally works for me is
SELECT TO_CHAR(mytimestamp, 'YYYY-MM-DD') FROM mytable;
I will assume that you've done a data dump as insert statements, and you (or whoever Googles this) are attempting to figure out the date and time, or translate it for use elsewhere (eg: to convert to MySQL inserts). This is actually easy in any programming language.
Let's work with this:
CAST(0x0000A61300B1F1EB AS DateTime)
This Hex representation is actually two separate data elements... Date and Time. The first four bytes are date, the second four bytes are time.
The date is 0x0000A613
The time is 0x00B1F1EB
Convert both of the segments to integers using the programming language of your choice (it's a direct hex to integer conversion, which is supported in every modern programming language, so, I will not waste space with code that may or may not be the programming language you're working in).
The date of 0x0000A613 becomes 42515
The time of 0x00B1F1EB becomes 11661803
Now, what to do with those integers:
Date
Date is since 01/01/1900, and is represented as days. So, add 42,515 days to 01/01/1900, and your result is 05/27/2016.
Time
Time is a little more complex. Take that INT and do the following to get your time in microseconds since midnight (pseudocode):
TimeINT=Hex2Int(HexTime)
MicrosecondsTime = TimeINT*10000/3
From there, use your language's favorite function calls to translate microseconds (38872676666.7 µs in the example above) into time.
The result would be 10:47:52.677
Some of them actually does covert to a date-time from SQL Server 2008 onwards.
Try the following SQL query and you will see for yourself:
SELECT CAST (0x00009CEF00A25634 AS datetime)
The above will result in 2009-12-30 09:51:03:000 but I have encountered ones that actually don't map to a date-time.
Not sure if I'm missing something here but can't you just convert the timestamp like this:
CONVERT(VARCHAR,CAST(ZEIT AS DATETIME), 110)

Resources