TIMEFROMPARTS: Fraction Values Follow the Precision

TIMEFROMPARTS interprets its fractions argument using the requested precision. I keep that precision beside the input because the same integer can describe very different fractional times.

A blue toolbox, an unmarked notebook and a complete woodworking plane on a prepared bench.
A toolbox, a notebook and a plane on a bench, like the parts of one time value.

Name the unit before supplying a fraction

A fraction value of one doesn’t mean one universal amount of time. Its interpretation depends on the requested precision. At precision three, it represents one millisecond. At precision seven, it represents one ten-millionth of a second.

TIMEFROMPARTS builds a time value from its parts and is available since SQL Server 2012. The final argument selects the time precision. Its return type carries that precision. This example compares two fixed choices instead of mixing them into one output column.

I’d avoid naming the input merely Fraction without documenting its unit. A source that records milliseconds needs precision three with appropriately ranged values. Passing those same numbers at precision seven changes the meaning. A successful function call doesn’t detect that mismatch.

Keep both constructed times visible

The example supplies fraction values zero, one, 123 and 999. Every complete input uses twelve hours, thirty-four minutes and fifty-six seconds. Two outputs construct time(3) and time(7). The original integer remains beside them.

The integer 123 becomes .123 at precision three. At precision seven, it becomes .0000123. These are different times despite using the same visible number. Both complete strings belong in the expected result, rather than a shortened display of seconds.

Two additional rows contain a missing fraction and a missing hour. They expose NULL propagation without manufacturing an invalid range. The script uses only valid non-NULL components. It doesn’t run deliberate errors in the same batch as its result demonstration.

WITH Inputs AS
(
    SELECT Id, HourPart, MinutePart, SecondPart, FractionPart
    FROM (VALUES (1, 12, 34, 56, 0), (2, 12, 34, 56, 1),
                 (3, 12, 34, 56, 123), (4, 12, 34, 56, 999),
                 (5, 12, 34, 56, NULL), (6, NULL, 34, 56, 0))
        AS v(Id, HourPart, MinutePart, SecondPart, FractionPart)
)
SELECT Id, HourPart, MinutePart, SecondPart, FractionPart,
       TIMEFROMPARTS(HourPart, MinutePart, SecondPart, FractionPart, 3)
           AS TimePrecision3,
       TIMEFROMPARTS(HourPart, MinutePart, SecondPart, FractionPart, 7)
           AS TimePrecision7
FROM Inputs
ORDER BY Id;
Native SSMS results comparing TIMEFROMPARTS fractions at precision three and precision seven, with missing fraction and hour inputs.
Native SSMS results for all six rows. The same fraction argument is interpreted at the requested precision, and all seven fractional digits remain visible in TimePrecision7. Missing required parts produce NULL. Open the result at full size.
Same number, different time

Keep NULL and invalid input separate

A NULL hour, minute, second or fraction gives a NULL result. A NULL precision is a separate error case. The example always provides a literal valid precision. It doesn’t treat a missing hour as midnight or a missing fraction as zero.

Invalid hour, minute or second values can raise an error. Fractions must also fit the selected precision. A fraction valid for precision seven can be too large for precision three. Validate the original unit and range before constructing the output.

I can justify substituting zero for an omitted fraction when the source contract explicitly permits it. That substitution changes a missing value into a precise time. I’d retain a source-quality flag when that distinction matters. The constructor cannot recover the discarded uncertainty.

Choose the destination precision deliberately

A destination column can apply another conversion after construction. That conversion can round fractional seconds to a lower precision. It belongs to a separate storage contract. This demonstration reads both original constructed times without narrowing either one afterward.

The output column names include their precision to make comparison straightforward. Their SQL types are recorded as time(3) and time(7). A client formatting both without fractions would obscure the demonstrated difference. Display formatting shouldn’t define the underlying precision.

These values contain no date or time zone. TIMEFROMPARTS doesn’t attach a calendar day or establish an instant. An event timestamp may need additional information. I would choose the required temporal type before using a time-only constructor.

Read the complete result contract

The CTE supplies literal components and the final SELECT reads them. No objects, settings or transactions are created. ORDER BY fixes the six-row sequence. Each original component stays visible beside both outputs for a complete tuple comparison.

Keep every time value at its full fractional width, including both NULL cases. Compare each component with its resulting time. Check the declared precision beside the fractional argument. A screenshot showing only whole seconds would miss the central distinction.

Name the unit out loud, and the same number stays honest.

A fraction is not a universal time unit, it is a number interpreted through the selected precision.

Published by Pinal Dave on SQLAuthority. More of my work at pinaldave.com.


Discover more from SQL Authority with Pinal Dave

Subscribe to get the latest posts sent to your email.

SQL Datatype, SQL Function, SQL Scripts, SQL Server
Previous Post
SQL SERVER – Default Collation of SQL Server 2008
Next Post
Comparing Float Values: Why 0.1 + 0.2 Is Not 0.3 in SQL Server

Related Posts

Leave a Reply

Your email address will not be published. Required fields are marked *

Fill out this field
Fill out this field
Please enter a valid email address.