Wrong datetime in sqlite expert personal - c#

I'm trying to write to my sqlite db from visual studio in c#. When using datetime. Now in visual studio it shows me the correct date and time but when writing to the db it shows something like 1899/30/12. Why is that? Here is my code:
SQLiteCommand cmd = new SQLiteCommand("INSERT INTO tblLicenseInfo (ID, UserID, MachineID, ExpirationDate, DateOfChange, LicenseKey)
VALUES(1, 1, 1, #test, #test, 'sdfsafge45345345');", SqLite);
cmd.Parameters.Add("#test", DateTime.Now);
SqLite.Open();
cmd.ExecuteNonQuery();
SqLite.Close();
Thanks for your help.

DateTime.Now is in the incorrect format, so you have 2 options:
Use CURRENT_TIMESTAMP as value. This is a SQLite keyword.
Or
Format Datetime: DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");

I'm not quite sure why SQLiteParameterCollection.Add(String,Object) method overload doesn't work because it says:
Adds a SQLiteParameter to the SQLiteParameterCollection given the
parameter name and value.
As an alternative, you can use other overloads or AddWithValue as well like;
cmd.Parameters.Add("#test", SQLiteType.DateTime).Value = DateTime.Now;
or
cmd.Parameters.AddWithValue("#test", DateTime.Now);
More informations;
Using Parameters
But wait a second.. You said your column type is DATETIME but there is no data type like that in SQLite.
From Datatypes In SQLite Version 3
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.
Please tell the real type of your columns. I assume DateTime.Now doesn't fit these 3 type formats (or values) and that's why you get 1899/30/12 used as a "default" date in SQLite.
From Date And Time Functions
The date and time functions use a subset of IS0-8601 date and time
formats. The date() function returns the date in this format:
YYYY-MM-DD.
I feel like if you make your column type as TEXT and if you send your DateTime.Now with YYYY-MM-dd format, your code should work;
cmd.Parameters.Add("#test", SQLiteType.TEXT).Value = DateTime.Now.ToString("YYYY-MM-dd");

Related

C# DateTime.Parse(String) returns different value in different system

Today, I observed some strange behavior in the DateTime.Parse(String) method when running on different servers. This can be observed in different online C# compilers.
My input in the yyyy-MM-ddTHH:mm:ssZ format. Example: lets use 2020-02-12T16:57:36Z which converted to ticks is: 637171234560000000 (converted using https://tickstodatetime.azurewebsites.net/)
This is the code I use for testing this behavior:
DateTime parsedDateTime = DateTime.Parse("2020-02-12T16:57:36Z");
Console.WriteLine(parsedDateTime + " " + parsedDateTime.Kind.ToString() + " " + parsedDateTime.Ticks);
On https://dotnetfiddle.net/akuyiI, it returns 02/12/2020 16:57:36 Local 637171234560000000.
On https://rextester.com/XWH12209, it returns 12.02.2020 17:57:36 Local 637171270560000000
I understand that the DateTime is parsed into local timezone and displayed in local time, but why the number of ticks is also different between systems?
A string in the yyyy-MM-ddTHH:mm:ssZ format represents a date in UTC.
It is correctly parsed as such, but unfortunately, the resulting DateTime value is DatetimeKind.Local, and its value is adjusted accordingly to the time zone of the computer.
As stated in the comment in the beginning of the DateTime source code file,
Starting from V2.0, DateTime also stored some context about its time
zone in the form of a 3-state value representing Unspecified, Utc or
Local. This is stored in the two top bits of the 64-bit numeric value
with the remainder of the bits storing the tick count. This information
is only used during time zone conversions and is not part of the
identity of the DateTime. Thus, operations like Compare and Equals
ignore this state. This is to stay compatible with earlier behavior
and performance characteristics and to avoid forcing people into dealing
with the effects of daylight savings. Note, that this has little effect
on how the DateTime works except in a context where its specific time
zone is needed, such as during conversions and some parsing and formatting
cases.
Thus, the Ticks property of a DatetimeKind.Local date is relative to the local 12:00:00 midnight, January 1, 0001, not to the UTC 12:00:00 midnight, January 1, 0001.
This is documented in the remarks for the Ticks property.
This also means that the two date instances obtained via this kind of DateTime.Parse on different servers in different timezones, would compare as "unequal" even though they originate from the same string that describes the same UTC date. This is for backward compatibility.
In order to compare the ticks directly, you need to convert both dates to Kind.UTC first.
It's about CultureInfo of the server you run on. DateTime.Parse has different overloads and parsing a datetime and also currency too, is depending on system's CultureInfo(language and region and etc.)
A possible solution for different timezones in which date is parsed could be this:
DateTime parsedDateTime = DateTime.Parse(
"2020-02-12T16:57:36Z",
CultureInfo.InvariantCulture,
DateTimeStyles.AdjustToUniversal);
The answer is already in the question. The key point is in the output: 12.02.2020 17:57:36 Local 637171270560000000
The dateTime.kind shows what type of date it is? As the two website is most likely in two different places it shows two different times because .net has converted the given UTC time to their local time, which is reflected through DateTime.Kind.
If you instead run this
DateTime parsedDateTime = DateTime.Parse("2020-02-12T16:57:36Z").ToUniversalTime();
Console.WriteLine(parsedDateTime + " " + parsedDateTime.Kind.ToString() + " " + parsedDateTime.Ticks);
https://rextester.com/XWH12209
https://dotnetfiddle.net/o4XRFS
You will get the same date/time combination, because now it's not converted to local datetime but UTC instead.
For more clarification when I run your code on my local machine my output is:
12-Feb-20 10:57:36 PM Local 637171450560000000
Which basically means at the given UTC time it was 12-Feb-20 10:57:36 PM in my country.
DateTime.ParseExact(DateTime, Format, DateTimeFormatInfo.InvariantInfo,
DateTimeStyles.AllowLeadingWhite | DateTimeStyles.AllowTrailingWhite);
for example:
DateTime.ParseExact("06APR22/1605", "ddMMMyy/HHmm", DateTimeFormatInfo.InvariantInfo,
DateTimeStyles.AllowLeadingWhite | DateTimeStyles.AllowTrailingWhite);

DateTime.FromOADate vs MSSQL Cast as DateTime

I assumed that DateTime.FromOADate in .NET and casting to a DateTime in MS SQL worked the same way.
However, given the value: 41640
DateTime.FromOADate(value) returns: 2014-01-01
CAST(value AS DATETIME) returns: 2014-01-03
Is this expected behaviour because of different starting days, or is something not right?
This is the third day of January in 2014 in T-SQL:
SELECT CAST(41640 AS DATETIME)
and this is the first day of January in 2014 in .NET:
DateTime dt = DateTime.FromOADate(41640)
The reason is documented in MSDN:
CAST
The "zero"-date is 1900-01-01
DateTime.FromOADate
base date, midnight, 30 December 1899
So there is a two days difference between 01/01/1900 and 12/30/1899.
To investigate this you have to look into the base date first,
In MSSQL print CAST(0 AS DATETIME) will output:
Jan 1 1900 12:00AM
In C# .Net Console.WriteLine(DateTime.FromOADate(0)); will output:
12/30/1899 12:00:00 AM
So you can see there are 2 days of difference between 2 base date. That's why you are facing such problem.
OLE Automation Dates (aka "OADates") are for compatibility with COM interfaces, and used in communicating to things like Microsoft Excel through VBA. You shouldn't use them in communicating with SQL Server. Just return the native SQL date, datetime, or datetime2 type in your query and cast it to a DateTime in your .NET code.
DateTime dt = (DateTime) myDataReader["FooDateTime"];
As others have mentioned, the SQL Server epoch is not the same as the OLE Automation epoch. OLE Automation dates also have some quirky behaviors with negative values, and also that dates before March 1st 1900 might use an epoch of 12/30/1899 or 12/31/1899 depending on which program is using it. SQL Server uses a fixed epoch of 1/1/1900.
And like many of Windows and .NET types, the epoch isn't fixed to UTC, so you have to know what contextual time zone information is in play also. (Though this also occurs with DateTime unless you pay attention to the .Kind property.)
SQL Server's base date is '19000101'; try CASTing 0.
According to this: http://msdn.microsoft.com/en-us/library/system.datetime.fromoadate.aspx
FromOADate starts at 1899-12-30

want 24 hr format time in DateTime in C#

My date and time are stored in database in 24 hr format.What i do is use a stored procedure to fetch the required date and times and insert in a datatable. But in the datatable it automatically converts in 12 hr format.After fetching data from datatable it is possible to convert it into 24hr pattern but it has to be converted into string.But the problem is that i need to use the data to create a chart which would only accept DateTime format.
So what i want is some way to convert 12 hr time to 24 hr time format without changing it to string.Please help.
My date and time are stored in database in 24 hr format.
I hope they're not actually stored in any text format, but instead in a DateTime field or something similar. Don't confuse "what I see when I run a SQL query" with "what's stored in the database." Just as numbers aren't stored as sequences of decimal digits, dates and times shouldn't be stored as text.
But in the datatable it automatically converts in 12 hr format.
No, if you've done everything properly it should be storing everything in the DataTable as a DateTime. In the debugger you may see a 12-hour string representation, but the object itself should be a DateTime.
Basically the 12/24-hour problem is only a symptom of the real problem: unnecessary string conversions. Track those down (and remove them), and the rest should take care of itself. So if yo're currently calling ToString() when you extract the value from the DataTable, stop doing that. Instead, just cast:
DateTime dateTime = (DateTime) row["foo"];
From your story, I understand that the DataTable actually contains a DateTime value, which doesn't have any format by itself, it basically just stores a number of ticks since an arbitrary date and time. What you are seeing in your table visualization is the default ToString() conversion, based on your application's culture settings.
Most likely, if you were to do something like this before running your existing code, the format would change:
var cultureInfo = new CultureInfo(CultureInfo.CurrentCulture.Name);
cultureInfo.DateTimeFormat.LongTimePattern = "HH:mm:ss";
Thread.CurrentThread.CurrentCulture = cultureInfo;
I would recommend converting to a format of your preference by calling ToString explictly however. How exactly you would best accomplish this depends on how you are visualizing the data from the DataTable.
All that #Jon said is right.
But if you just explained yourself wrong, and you do have DateTime object in your db, and you are looking to format it into 24 hr only when displaying - you can use "HH" in string format for 24 hour format.
For example, for myDateTime representing 16:00:
var hourPart = String.Format("{0:HH}", myDateTime)
Console.WriteLine(hourPart); // prints 16, and not 4PM.

How I can convert DateTime.now in C# to yyyy-mm-dd hh:mm:ss.sssssss?

I'm storing in my database using a store procedure the date time stamp using a function called sysdatetime() and a type of varchar(max) which stores in the database in this format yyyy-mm-dd hh:mm:ss.sssssss. When I'm creating a new post its fine but when I'm trying to update the record I have to send a parameter to the store procedure with the current datetime. I have tried this one
DateTime.Now.ToString(yyyy-mm-dd hh:mm:ss.sssssss)
but I'm getting an error. what i have to do?
P.s: see the image below with the error message
I suspect if you really need the string representation, you actually want:
string text = DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss.fffffff",
CultureInfo.InvariantCulture)
Note that:
Unless you really want the local time, use UtcNow instead of Now. For timestamps, you almost always want UTC.
I doubt that you want to use the time separator of the current culture, hence the specification of CultureInfo.InvariantCulture
"MM" means months whereas "mm" means minutes
"HH" means 24-hour clock whereas "hh" means 12-hour clock
"ff..." is used for fractions of a second
See MSDN for more details of custom date and time formatting.
However, I'd strongly recommend that you try to avoid string conversions wherever possible. Why can't your stored procedure just use the relevant DateTime type instead of a string representation? Then you can pass the value to the stored procedure as a DateTime (via a command parameter) and you can get rid of the error-prone string conversion clutter.
Use this code:
DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fffffff")
See this ref: http://msdn.microsoft.com/en-us/library/8kb3ddd4.aspx
Here a small sample:
DateTime date3 = new DateTime(2008, 1, 1, 0, 30, 45, 125);
Console.WriteLine("Date with milliseconds: {0:MM/dd/yyy hh:mm:ss.fff}",
date3);
// Displays the following output to the console:
// Date with milliseconds: 01/01/2008 12:30:45.125
Just put the appropriate number of "f"s into your command and you are done

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.

Categories