Store and Retrieve DateTime to SQL as Integer - c#

I've played a little with SQLite in the past, and I like it enough that I want to use it for a new project.
Step 1 is creating the database, and I need to create a DateStamp field where I place a time stamp on when an event occurred.
In the SQLite Documentation, the Date and Time Datatype is defined as follows:
1.2 Date and Time Datatype
SQLite does not have a storage class set aside for storing dates
and/or times. Instead, the built-in Date And Time Functions of SQLite
are capable of storing dates and times as TEXT, REAL, or INTEGER
values:
TEXT as ISO8601 strings ("YYYY-MM-DD HH:MM:SS.SSS").
REAL as Julian day numbers, the number of days since noon in Greenwich on November 24, 4714 B.C. according to the proleptic
Gregorian calendar.
INTEGER as Unix Time, the number of seconds since 1970-01-01 00:00:00 UTC.
Applications can chose to store dates and times in any of these
formats and freely convert between formats using the built-in date and
time functions.
I'd rather not save dates as text, and since the Windows DateTime object does not go back to November 24, 4714 B.C., I supposed I'm left with storing DateTime values as an INTEGER.
So, how do I store the DateTime as an Integer? Would I get the TimeSpan between base date and date I want, extract the number of days, and store that?
// is this a UTC date?
private static readonly DateTime utc1970_01_01 = new DateTime(1970, 1, 1);
public static double GetIntDate(DateTime dateTime) {
// FYI: subtracting dates in .NET returns a time span object
return (dateTime - nov24_4714bc).TotalSeconds;
}
Is that right? Is this what everyone else is doing that uses SQLite?
It also says that SQLite stores datetime in UTC time, so I need to convert again on top of that.
Surely someone has done this before. I would appreciate seeing tools someone has made already that handles these inputs. SQLite has some built in functions, but I don't really understand how to use them.
Solved:
Well poo.
Could it be as simple as this?
public static long ToFileTimeUtc(DateTime dateTime) {
return dateTime.ToFileTimeUtc();
}
public static DateTime FromFileTimeUtc(long fileTimeUtc) {
return DateTime.FromFileTimeUtc(fileTimeUtc);
}
Comments?
Can I not do that?

Whether or not you can use FileTime depends on whether anything but your app will ever be accessing the data. FileTime represents the number of 100-nanosecond intervals since January 1, 1601 (UTC).
As such, you will need to make sure the integer is an 8 byte integer in SQLLite in order to store the entire value.
As long as your app is the only app to deal with this data, and you always use FileTime, then there's no problem. If others will access this data, and they're capable of understanding FileTime, and they are aware that this is what it is, then there is also no problem.

Well poo.
Could it be as simple as this?
public static long ToFileTimeUtc(DateTime dateTime) {
return dateTime.ToFileTimeUtc();
}
public static DateTime FromFileTimeUtc(long fileTimeUtc) {
return DateTime.FromFileTimeUtc(fileTimeUtc);
}
Comments?
Can I not do that?

Related

DateTime Precision / Accuracy

I'd like to represent dates with different precisions (accuracies). Ideally I can use the DateTime datatype to store the date information though it doesn't come with a precision setting. For example, I have the date "1/1/2015", but depending on its precision it will be understood to be:
an exact date: 1 JAN 2015
month and year only: JAN 2015
year only: 2015
The precision is needed for both UI formatting as well as business logic hence I don't like to use the .NET out of the box formatting options that come with DateTimeFormatInfo or others - they have a different purpose.
Consequently, there is my own solution that is essentially an enumeration ...
public enum DateTimePrecision
{
DayMonthYear = 0,
MonthYear,
Year,
...
}
... that goes with the date (struct or class) ...
public class MySuperDupaAwesomeDateTime
{
public DateTime Date { get; set; }
public DateTimePrecision Precision { get; set; }
}
Alternatively, I could build my own custom DateTime of course.
Anyway, this is like re-inventing something that feels so common and must be out there already. Can anybody think of an improvement of the above approach or knows about a .NET Framework feature? I am not looking for a library or anything, but a solution that comes straight out of .NET.
DateTime has some identifiers for Month and Year that are integers. Use them and format it into a String.
If you need more accuracy than just a day, DateTime also has other identifiers for Seconds, Minutes, Hours, Milliseconds... check the attributes for yourself!
After you get the integer values for them, you can even start to do calculations for getting elapsed time for something to complete (by getting a DateTime and setting it for Now when you start and getting another DateTime and setting that for Now when it's over, then use the name of second object.Subtract( name of the first object ), or .Add())!

Converting datetime to time in C# / ASP.NET

I am trying to insert time on my asp.net project.
RequestUpdateEmployeeDTR requestUpdateEmployeeDTR = new RequestUpdateEmployeeDTR();
requestUpdateEmployeeDTR.AttendanceDeducID = int.Parse(txtAttendanceDeducID.Text);
requestUpdateEmployeeDTR.TimeInChange = txtTimeOutChange.Text;
requestUpdateEmployeeDTR.TimeOutChange = txtTimeOutChange.Text;
TimeInChange and TimeOutChange are DateTime data types. But I am inserting a time data type. How can I convert that into a time data type using C#? Thanks!
The .NET Framework does not have a native Time data type to represent a time of day. You will have to decide between one of the three following options:
Option 1
Use a DateTime type, and ignore the date portion. Pick a date that's outside of a normal range of values for your application. I typically use 0001-01-01, which is conveniently available as DateTime.MinValue.
If you are parsing a time from a string, the easiest way to do this is with the DateTimeStyles.NoCurrentDateDefault option. Without this option, it would use today's date instead of the min date.
DateTime myTime = DateTime.Parse("12:34", CultureInfo.InvariantCulture,
DateTimeStyles.NoCurrentDateDefault);
// Result: 0001-01-01 12:34:00
Of course, if you prefer to use today's date, you can do that. I just think it confuses the issue because you might be looking to apply this to some other date entirely.
Note that once you have a DateTime value, you can use the .TimeOfDay property to get at just the time portion, represented as a TimeSpan, which leads to option 2...
Option 2
Use a TimeSpan type, but be careful in how you interpret it. Understand that TimeSpan is first and foremost a type for representing an elapsed duration of time, not a time of day. That means it can store more than 24 hours, and it can also store negative values to represent moving backwards in time.
When you use it as a time of day, you might be inclined to think of it as "elapsed time since midnight". This, however, will get you into trouble because there are days where midnight does not exist in the local time zone.
For example, October 20th 2013 in Brazil started at 1:00 AM due to daylight saving time. So a TimeSpan of 8:00 on this day would actually have been only 7 hours elapsed since 1:00, not 8 hours elapsed since midnight.
Even in the United States, for locations that use daylight saving time, this value is misleading. For example, November 3rd 2013 in Los Angeles had a duplicated hour for when DST rolled back. So a TimeSpan of 8:00 on this day would actually had 9 hours elapsed since midnight.
So if you use this option, just be careful to treat it as the representative time value that matches a clock, and not as "time elapsed since midnight".
You can get it directly from a string with the following code:
TimeSpan myTime = TimeSpan.Parse("12:34", CultureInfo.InvariantCulture);
Option 3
Use a library that has a true "time of day" type. You'll find this in Noda Time, which offers a much better API for working with date and time in .NET.
The type that represents a "time of day" is called LocalTime, and you can get one from a string like this:
var pattern = LocalTimePattern.CreateWithInvariantCulture("HH:mm");
LocalTime myTime = pattern.Parse("12:34").Value;
Since it appears from your question that you are working with time and attendance data, I strongly suggest you use Noda Time for all your date and time needs. It will force you to put more thought into what you are doing. In the process, you will avoid the pitfalls that can come about with the built-in date/time types.
If you are storing a Time type in your database (such as SQL server), that gets translated as a TimeSpan in .Net. So if you go with this option, you'll need to convert the LocalTime to a TimeSpan as follows:
TimeSpan ts = new TimeSpan(myTime.TickOfDay);

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. )

how to add current date time in bigint field

I need to add the current date time in a bigint field in a database... and then display from that only the date in format: october 1, 2009.
I am currently thinking of storing the value in string variable and then converting it to int...
String s = DateTime.Now.ToString();
i dont know what to do next..
please help
You could just store the number of ticks as your bigint value. Ticks represent the number of elapsed 1/10,000 of milliseconds since January 1, 0001.
DateTime.Now.Ticks;
This can always be converted back to a DateTime by using the constructor that accepts a long:
DateTime storedTime = new DateTime(ticksFromDatabase);
To format your date, just use any of the standard date format strings. A custom format string might work better actually, I just perused them and it doesn't look like there's a built in one for the format you want. This should work:
date1.ToString("MMMM d, yyyy", CultureInfo.CreateSpecificCulture("en-US"))
I'd use a smart date key, since it's easier to find that using SQL:
20090927235000
yyyyMMddhhmmss
This way, if you want to find anything that happened on a given day, you could do:
select * from tbl where datecol between 20090927000000 and 20090927240000
Thereby making data validation a lot easier, even if you are using an ORM.

Incomplete DateTime In C#

In C# if I want to parse a datetime, but some times I just have either a date and not a time component or no date but a time component, how would I do this? Usually when you leave out the time component, it automatically assumes that the time is 12:00AM. But I don't want this. If the time component is missing then I just want the DateTime to store a date only and the leave the time component off.
The value of a DateTime internally is just an UInt64 (ulong in C#) that stores the number of ticks since some date in the past, so whether you like it or not, the time component will always be there.
If you only need to display certain parts, just use any of the format strings (examples are for "en-us" culture):
DateTime.Now.ToString("d"); // 5/26/2009
DateTime.Now.ToString("t"); // 4:56 PM
The complete reference: http://msdn.microsoft.com/en-us/library/az4se3k1.aspx
It's not possible to have a DateTime without a time component. You could store a boolean flag along with it in a struct to store data about existence of that component. However, there's no way to use the automatic parsing routine to distinguish between a DateTime string with a time specified as 12:00 PM and a nonexistent one.
If it really bugs you you can always create a wrapper class that can hide the time portions of the datetime class.
No you will have the time component no matter what. The best you can do is access the Date property on your DateTime object if you really have to.
http://msdn.microsoft.com/en-us/library/system.datetime.date.aspx
DateTime by definition stores a date and a time such that it cannot just represent one of them without representing the other. If you only want the date (or only the time), parse out the information you need and discard the rest of it.
As mentioned before DateTime will always have a Date and a Time part of it if you only want a single part use the way described by the others
DateTime date = DateTime.Parse("2009-11-30);
date.Year; = 2009
date.Month; = 11
date.Day; = 30
date.Hour; = 0
and so on
The thing you must be aware is that all of these methods will only return an integer.
If you want to know all the possible ways to parse a string John Sheehan has put together a great Cheat Sheet wit all possible ways to parse and manipulate dates, and other strings for that matter.
You could have a class that stores a DateTime and determines if the time was ever set or if just the date was set and return values accordingly.
Use
DateTime date = new DateTime();
date = DateTime.Parse("1/1/2001");
to set the date, then use
date.ToShortDateString();
or
date.Year;
date.Month;
date.Day;
to get what you need. Hope that helps!
A DateTime object is always stores a date + a time, not just one. You can always choose to work only with the date part, i.e. only use properties like Year, Month, DayOfWeek. But underneath there will aways be some stored time.
It is very dangerous to assume that the date portion of a DateTime is necessarily the date you are expecting. As pointed-out, DateTime always includes and considers the time aspect, even when you don't see it.
This is a big problem when you have data stored in different time-zones (and particularly if knowledge of that offset is not also kept, because it is assumed that what is being stored is a Date, not a date-with-time).
You may store a birthdate as '01/01/2000 00:00:00' during Summer-Time, which then is stored in UCT as '31/12/1999 23:00:00'. When you then read that birth-date later, the date portion is now a day early.
Best to create your own type. Strange that Microsoft didn't think it worth having a Date type.

Categories