1

I have a SQL Server table that has a datetime column. Its default value is provided by the GETDATE() function.

I want to select the millisecond portion of the value by using DATEPART() function. Interestingly, it is rounding the millisecond portion like 637 to 636. There is a problem.

What is causing the problem or how can I solve it? By using convert function I can exactly handle the millisecond portion but why is the DATEPART function is rounding I couldn't find.

Screen shot of the table query result:

enter image description here

The query

SELECT 
    [ID],
    DATETIME_COLUMN,
    DATEPART(ms, DATETIME_COLUMN) MS_PART_W_DATEPART,
    RIGHT(CONVERT(VARCHAR,DATETIME_COLUMN,27),3) MS_PART_VARCHAR      
FROM 
    DATETIME_TABLE

You can test with the script and data set.

Table script:

CREATE TABLE [dbo].[DATETIME_TABLE]
(
    [ID] [int] NOT NULL,
    [DATETIME_COLUMN] [datetime] NULL   
) ON [PRIMARY]

Data set:

INSERT INTO [dbo].[DATETIME_TABLE]
([ID], [DATETIME_COLUMN])
VALUES
(613577,    '2024-01-01 09:52:06.637'),
(613578,    '2024-01-01 09:52:39.050'),
(613579,    '2024-01-01 09:53:04.557'),
(613580,    '2024-01-01 09:53:36.200'),
(613581,    '2024-01-01 09:53:49.307'),
(613582,    '2024-01-01 09:53:55.813'),
(613583,    '2024-01-01 09:54:01.823'),
(613584,    '2024-01-01 09:54:45.277'),
(613585,    '2024-01-01 09:55:03.917'),
(613586,    '2024-01-01 09:55:27.340'),
(613587,    '2024-01-01 09:56:15.700'),
(613588,    '2024-01-01 09:57:11.493'),
(613589,    '2024-01-01 09:58:10.947'),
(613590,    '2024-01-01 09:58:52.040'),
(613591,    '2024-01-01 10:00:13.360'),
(613592,    '2024-01-01 10:00:59.837'),
(613593,    '2024-01-01 10:01:24.680'),
(613594,    '2024-01-01 10:01:54.480'),
(613595,    '2024-01-01 10:03:37.580'),
(613596,    '2024-01-01 10:04:48.683'),
(613597,    '2024-01-01 10:05:51.057'),
(613598,    '2024-01-01 10:08:00.070'),
(613599,    '2024-01-01 10:09:00.627'),
(613600,    '2024-01-01 10:10:30.693'),
(613601,    '2024-01-01 10:11:23.090'),
(613602,    '2024-01-01 10:12:00.417'),
(613603,    '2024-01-01 10:12:30.977'),
(613604,    '2024-01-01 10:14:46.230'),
(613605,    '2024-01-01 10:15:22.373'),
(613606,    '2024-01-01 10:16:07.153'),
(613607,    '2024-01-01 10:16:44.523'),
(613608,    '2024-01-01 10:17:27.480'),
(613610,    '2024-01-01 10:50:58.017'),
(613611,    '2024-01-01 10:51:20.437'),
(613612,    '2024-01-01 10:51:34.000'),
(613613,    '2024-01-01 10:51:57.530'),
(613614,    '2024-01-01 10:52:15.593'),
(613615,    '2024-01-01 10:53:49.623'),
(613616,    '2024-01-01 10:54:39.420'),
(613617,    '2024-01-01 10:55:10.610'),
(613618,    '2024-01-01 10:55:30.093'),
(613619,    '2024-01-01 10:55:54.220'),
(613620,    '2024-01-01 10:56:08.860'),
(613621,    '2024-01-01 10:57:00.830'),
(613622,    '2024-01-01 10:57:22.907'),
(613623,    '2024-01-01 10:57:35.447'),
(613624,    '2024-01-01 10:58:09.763'),
(613625,    '2024-01-01 10:58:42.780'),
(613626,    '2024-01-01 10:59:00.500'),
(613627,    '2024-01-01 10:59:55.590'),
(613628,    '2024-01-01 11:00:54.203'),
(613629,    '2024-01-01 11:01:31.047'),
(613630,    '2024-01-01 11:01:35.657'),
(613631,    '2024-01-01 11:01:38.483'),
(613632,    '2024-01-01 11:01:41.713'),
(613633,    '2024-01-01 11:01:44.360'),
(613634,    '2024-01-01 11:01:47.410'),
(613635,    '2024-01-01 11:01:54.907'),
(613636,    '2024-01-01 11:01:58.360'),
(613637,    '2024-01-01 11:40:37.320'),
(613638,    '2024-01-01 11:41:40.877'),
(613639,    '2024-01-01 11:42:01.297'),
(613640,    '2024-01-01 11:42:29.360'),
(613641,    '2024-01-01 11:42:51.533'),
(613642,    '2024-01-01 11:43:10.940'),
(613643,    '2024-01-01 11:43:50.097'),
(613644,    '2024-01-01 11:44:26.033'),
(613645,    '2024-01-01 11:44:42.317'),
(613646,    '2024-01-01 11:45:18.250'),
(613647,    '2024-01-01 11:45:45.597'),
(613648,    '2024-01-01 11:45:54.957'),
(613649,    '2024-01-01 11:46:11.287'),
(613650,    '2024-01-01 11:46:36.733'),
(613651,    '2024-01-01 11:46:57.487'),
(613652,    '2024-01-01 11:47:34.220'),
(613653,    '2024-01-01 11:50:25.503'),
(613654,    '2024-01-01 11:51:03.487'),
(613655,    '2024-01-01 11:51:13.737'),
(613656,    '2024-01-01 11:51:28.120'),
(613657,    '2024-01-01 11:51:44.520'),
(613658,    '2024-01-01 11:51:47.980'),
(613659,    '2024-01-01 11:51:56.707'),
(613660,    '2024-01-01 11:52:16.320'),
(613661,    '2024-01-01 11:52:26.113'),
(613662,    '2024-01-01 11:52:29.987'),
(613663,    '2024-01-01 11:52:32.940'),
(613664,    '2024-01-01 11:52:36.003'),
(613665,    '2024-01-01 11:52:43.080'),
(613666,    '2024-01-01 11:52:55.503'),
(613667,    '2024-01-01 11:53:29.017'),
(613668,    '2024-01-01 11:53:55.403'),
(613669,    '2024-01-01 11:58:16.183'),
(613670,    '2024-01-01 11:58:34.097'),
(613671,    '2024-01-01 12:02:31.927'),
(613672,    '2024-01-01 12:03:25.807'),
(613673,    '2024-01-01 12:08:14.473'),
(613674,    '2024-01-01 12:08:17.620'),
(613675,    '2024-01-01 12:08:45.040'),
(613676,    '2024-01-01 12:09:07.623'),
(613677,    '2024-01-01 12:09:13.787')

I tried to solve the problem on my own experience, search the net. Then decide to ask the question.

Result

After reading comments. I added a datetime2 column into the table and update its values from the datetime column.

.7 actually recorded as .66667

enter image description here

8
  • 4
    avoid using datetime and use datetime2 instead because datetime is lacking accuracy which might result in the ms part to return "unexpected" results learn.microsoft.com/en-us/sql/t-sql/data-types/… Commented Feb 24 at 13:18
  • 1
    For the legacy datetime datatype it likes to maintain the idea that values ending 7 are really .666666 recurring. This DATEPART behaviour was a change under compat 130 Commented Feb 24 at 13:19
  • 2
    This is a very well-known issue with the DATETIME datatype - it's accurate only to 3.33ms. No way to change or "fix" that - other than using DATETIME2(n) datatype instead (which has been introduced in SQL Server 2008 - well over 15 years ago.....) It's really NOT DATEPART doing any rounding - it's just DATETIME which is unable to handle millisecond precision - DATETIME2 can. Commented Feb 24 at 13:19
  • I didn't know that datepart ms was unreliable. Funnily, DATEPART(ms, '20240101 23:59:59.637') seems to work correctly, as well as: DATEPART(ms, convert(varchar(30),cast('20240101 23:59:59.637' as datetime), 121)) Commented Feb 24 at 13:28
  • 2
    If you need the 7 for now, I would suggest casting your column to a datetime2(3) for now, as this then returns 7. For example: SELECT DATEPART(MILLISECOND,V.YourColumn) AS DT, DATEPART(MILLISECOND,CONVERT(datetime2(3),V.YourColumn)) AS DT2 FROM (VALUES(CONVERT(datetime,'2024-01-01T09:52:06.637')))V(YourColumn); Commented Feb 24 at 14:30

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.