Handling and storing elapsed time - c#

I'm having problems deciding on what is the best way is to handle and store time measurements.
I have an app that has a textbox that allows the users to input time in either hh:mm:ss or mm:ss format.
So I was planning on parsing this string, tokenizing it on the colons and creating TimeSpan (or using TimeSpan.Parse() and just adding a "00:" to the mm:ss case) for my business logic. Ok?
How do I store this as in a database though? What would the field type be? DateTime seems wrong. I don't want a time of 00:54:12 to be stored as 1901-01-01 00:54:12 that seems a bit poor?

TimeSpan has an Int64 Ticks property that you can store instead, and a constructor that takes a Ticks value.

I think the simplest is to just convert user input into a integer number of seconds. So 54:12 == 3252 seconds, so store the 3252 in your database or wherever. Then when you need to display it to the user, you can convert it back again.

For periods less than a day, just use seconds as other have said.
For longer periods, it depends on your db engine. If SQL Server, prior to version 2008 you want a datetime. It's okay- you can just ignore the default 1/1/1900 date they'll all have. If you are fortunate enough to have sql server 2008, then there are separate Date and Time datatypes you can use. The advantage with using a real datetime/time type is the use of the DateDiff function for comparing durations.

Most databases have some sort of time interval type. The answer depends on which database you're talking about. For Oracle, it's just a floating point NUMBER that represents the number of days (including fractional days). You can add/subtract that to/from any DATE type and you get the right answer.

As an integer count of seconds (or Milliseconds as appropriate)

Are you collecting both the start time and stop time? If so, you could use the "timestamp" data type, if your DBMS supports that. If not, just as a date/time type. Now, you've said you don't want the date part to be stored - but consider the case where the time period spans midnight - you start at 23:55:01 and end at 00:05:14, for example - unless you also have the date in there. There are standard build in functions to return the elapsed time (in seconds) between two date-time values.

Go with integers for seconds or minutes. Seconds is probably better. you'll never kick yourself for choosing something with too much precision. Also, for your UI, consider using multiple text inputs you don't have to worry about the user actually typing in the ":" properly. It's also much easier to add other constraints such as the minute and second values conting containing 0-59.

and int type should do it, storing it as seconds and parsing it back and forth
http://msdn.microsoft.com/en-us/library/ms187745.aspx

Related

Millisecond is not removed from data

I have a DateTime column in my table. I want to store RUN date without millisecond stamp.
I tried below code, but in table, millisecond comes as 0000000.
Is that possible to store only date in "2021-06-09 08:58:03" format?
DateTime dt = Convert.ToDateTime(System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
Thanks in advance. Any help will be appreciated.
Upfront
Decide if you want to store a SQL datetime (or related) type or just a formatted string representation of a date and time.
Also decide if you want to use a local clock (of client workstation or even web server, with a clock that may be in a time zone different from your database server or maybe just out of time-sync with the database server).
Because
If the need is to be able to audit/report/coordinate the "order of events" you should choose an appropriate SQL type like datetime/datetime2/smalldatetime and instead of using client-side code to query the client-side clock, use SQL DATE and TIME functions MS T-SQL date and time types and functions. If you do this then record values at whatever precision they are offered and worry about string formatting when values are retrieved for display.
Only if you wish to store a string representation of a date and time in the database should you concern yourself with format at the time of insertion.
Final Answer
Consider a floating point numeric type like C#'s double. You can declare double d1 = 1.23E+2; or double d2 = 123. Both d1 and d2 contain an equal value (approximately 123.00...0 with about 13 zeroes all of which are significant). The format used at the time of assignment cannot influence future use of the value or system behaviour when it is used, whether for arithmetic or display purposes. The same applies to date and time types.
#mjwills comment taught me something I wasn't aware of: datetime2(0) seems to offer what you want - date and time with a precision of whole seconds, however fractions of a second are still recorded (try insert value CURRENT_TIMESTAMP to a datetime2(0) column), so treat the precision parameter as a storage-allocation hint rather than a hard limit on "significant digits recorded" and you will still need to worry about formatting values when retrieved for reporting/display.

Using DateTime for a duration of time e.g. 45:00

I'd just like to know if it is possible to use the DateTime type for durations such as 45:00 (45 minutes) or 120:00 (120 minutes). These values also need to be stored into a Local Sql Server DB. If it is possible, could anyone possibly hint how this could be done using Datetime, or if not just let me know a way it could be done using a different type.
Thank you in advance,
Jamie
You should use the TimeSpan structure
TimeSpan interval = new TimeSpan(0, 45, 0);
Console.WriteLine(interval.ToString());
For the database storing part, you could store the property Ticks because a specific constructor for the TimeSpan structure allows to instantiate a new TimeSpan passing the Ticks value
long ticks = GetTimeSpanValueFromDb();
TimeSpan interval = new TimeSpan(ticks);
I wish to add also that you need a BIGINT T-SQL datatype field to store a long NET datatype
I store durations in seconds in the database and then convert to HH:MM:SS format when comes time to display the data.
Why don't you use TimeSpan instead? You can convert them to Ticks (int), store them in the db and the reverse the process when you need the value.
This is merely a matter of interpretation. SQL Server stores datetime as two four byte integers. One is a signed int count of days from a reference date, the other is an unsigned time of day such that 32bits exactly maps 24 hours. Without the implicit epoch, this isn't a datetime, it's a duration. Nothing prevents you from interpreting it that way.
Of course, it would be more convenient to pick a unit and simply use a float. This is what Windows does, storing datetime as a number of days from a reference date expressed as an 8-byte float (a double).
Personally I don't like "day" as a unit of time. The rotational period of our planet is not constant, and it is necessary to mess about with leap seconds to maintain the illusion that there are 86400 seconds in every day. A better choice is the SI unit, the second, which is defined in terms of repeatable, invariant physical constants.
Better again would be the picosecond, since we could dump the double and use an int64, with all the attendant arithmetical and comparative performance advantages. Depiction in mixed human scale units (yyyy mmm d HH:mm:ss) is already something of a trial. Mapping functions that currently work with fractional days could trivially be scaled to microseconds, although the compensation for leap seconds and leap days would have to be rewritten.
I say picosecond because this is the finest division that fits in 64 bits while encompassing a useful span of time (50,000 years). Femto fits, but fifty years isn't wide enough. I know that eventually there be a year 50K problem but frankly I doubt anyone but archeologists will care about records from 50,000 years ago.

Add 1 week to current date

I've got something like this DateTime.Now.ToString("dd.MM.yy"); In my code, And I need to add 1 week to it, like 5.4.2012 to become 12.4.2012 I tried to convert it to int and then add it up, but there is a problem when it's up to 30.
Can you tell me some clever way how to do it?
You want to leave it as a DateTime until you are ready to convert it to a string.
DateTime.Now.AddDays(7).ToString("dd.MM.yy");
First, always keep the data in it's native type until you are ready to either display it or serialize it (for example, to JSON or to save in a file). You wouldn't convert two int variables to strings before adding or multiplying them, so don't do it with dates either.
Staying in the native type has a few advantages, such as storing the DateTime internally as 8 bytes, which is smaller than most of the string formats. But the biggest advantage is that the .NET Framework gives you a bunch of built in methods for performing date and time calculations, as well as parsing datetime values from a source string. The full list can be found here.
So your answer becomes:
Get the current timestamp from DateTime.Now. Use DateTime.Now.Date if you'd rather use midnight than the current time.
Use AddDays(7) to calculate one week later. Note that this method automatically takes into account rolling over to the next month or year, if applicable. Leap days are also factored in for you.
Convert the result to a string using your desired format
// Current local server time + 7 days
DateTime.Now.AddDays(7).ToString("dd.MM.yy");
// Midnight + 7 days
DateTime.Now.Date.AddDays(7).ToString("dd.MM.yy");
And there are plenty of other methods in the framework to help with:
Internationalization
UTC and timezones (though you might want to check out NodaTime for more advanced applications)
Operator overloading for some basic math calcs
The TimeSpan class for working with time intervals
Any reason you can't use the AddDays method as in
DateTime.Now.AddDays(7)

Type to store time in C# and corresponding type in T-SQL

I would like to know how to store time in C# and T-SQL. I know that both of them provide a DateTime type but I just need to store a time. For instance:
var startTime = 9PM;
var endTime = 10PM;
And then store/retrieve this values from a database. Thanks in advance.
Francesco
C#
Whether to use a DateTime or TimeSpan type in C# to store 9 PM is up to taste. Personally, I'd use DateTime, leaving the date component empty, since that's semantically closer to what you want. (A TimeSpan is designed to hold time intervals, such as "21 hours".)
The documentation supports both options. This is from the documentation of TimeSpan:
The TimeSpan structure can also be used to represent the time of day, but only if the time is unrelated to a particular date.
On the other hand, the MSDN article Choosing Between DateTime, DateTimeOffset, and TimeZoneInfo mentions the following:
The DateTime structure is suitable for applications that do the following:
* Work with dates only.
* Work with times only.
[...]
T-SQL
SQL Server has a time data type.
In C# there is not a type to hold only a time. There is TimeSpan, but it's intended to keep a period of time and not really a component of a DateTime (i.e. hours and minutes) only.
Starting with SQL Server 2008 there is a time type (Using Date and Time Data) that does only store a time component.
EDIT: Misread your question at first. TimeSpan is exactly what you're looking for and it can be stored in a time type with SQL 2K8.
In C# you'd probably want to use a TimeSpan structure if you just wanted to store a time interval. However, you seem to want to appear to store a start-time and an end-time, which would require storing two values. You could, therefore, use two TimeSpans (based on, say, number of minutes from midnight to represent the time) or you could just use two DateTime values and throw away the date component.
As has been noted, SQL Server 2008 has a Time datatype, but this isn't available in earlier versions which only have DateTime. You could also just store an Int representing number of minutes past midnight which can be easily converted to a TimeSpan (TimeSpan interval = TimeSpan.FromMinutes(60)).
Timespan in c# is how you manipulate time intervals. Contrary to what other posters are saying i don't think the Time data type is correct for storing time intervals in SQL, unless you actually want to store the start time and end time and not the time interval (i.e. 1 hour in you example). It is for storing a time of day, a bit like a DateTime but with no date. When i want to store a time interval in SQL I just use an int and then have it represent a unit of time appropriate to what I am trying to do (e.g.minutes, seconds, milliseconds etc. )

Is it ok to use ticks to pass datetime using ticks between pages of an application

I'm currently passing some date-time info to a web page using url parameters, which are ticks of date times, and then converting the ticks back into date times when I need to at the other end.
Is there a better way to do this, and why.
for example
http://localhost:57765/dinners/updatedinner/38?startDate=633917664000000000
that's fine, in fact that the standard format for encoding dates for JSON. only concern is timezones, as your tickcount doesn't encode that. you can either always assume the timzone, and do offset calculations based on that, or encode the timezone in the value (eg sD=12343245345-0500)
Representing datetime in human readable format would be much better for developers (troubleshooting etc.) and potential customers of your site.
Given that Ticks is defined as the number of 100-nanosecond intervals that have passed since 12 midnight, January 1, 0001, I can't see there being any functional issues, as long as you either convert to UTC before passing (and from UTC after) or otherwise deal with timezone issues.
That said, there are more human-friendly ways to pass the information, for example passing it as yyyyMMddThhmmss.nnn will be more friendly if anyone wants to manually enter the URL, although it's not quite as precise (if you need better than millisecond precision).

Categories