C# Datarow item DateTime format being ignored - c#

I am filling a DataTable using the results of a SQL SP. One of the columns is a DateTime type. When I try to format the DateTime value, it seems to be ignored.
For example:
foreach (DataRow row in sourceTable.Rows)
{
row["DateOfActivity"] = Convert.ToString(((DateTime)row["DateOfActivity"]).ToString("yyyy-MM-dd"));
Console.WriteLine(row["DateOfActivity"]);
}
Results in:
2/17/2016 12:00:00 AM
How can I make sure the DateTime format is retained?

In a databable, columns have specific types. When you assign back to row["DateOfActivity"], you're assigning to a DateTime value. Writing that back to the console will give you the default .ToString() call.
The solution is to wait to format the output until you actually show it to the user. Get rid of the first line inside the loop completely and have the second line just look like this:
Console.WriteLine(row["DateOfActivity"].ToString("yyyy-MM-dd"));

The type definition of the row["DateOfActivity"] column is not present in your question, however I am going to assume it is defined as a DateTime type. This type definition stores the raw date/time value, without a format.
From MSDN:
Internally, all DateTime values are represented as the number of ticks (the number of 100-nanosecond intervals) that have elapsed since 12:00:00 midnight, January 1, 0001. The actual DateTime value is independent of the way in which that value appears when displayed in a user interface element or when written to a file. The appearance of a DateTime value is the result of a formatting operation. Formatting is the process of converting a value to its string representation.
Because the appearance of date and time values is dependent on such factors as culture, international standards, application requirements, and personal preference, the DateTime structure offers a great deal of flexibility in formatting date and time values through the overloads of its ToString method. The default DateTime.ToString() method returns the string representation of a date and time value using the current culture's short date and long time pattern. The following example uses the default DateTime.ToString() method to display the date and time using the short date and long time pattern for the en-US culture, the current culture on the computer on which the example was run.
You should be formatting the value of a DateTime type when you output it. If you want to store a formatted version of this value in your DataTable you will need to define the column as a string and then store the formatted value.
For more information see this link on the DateTime type.

Related

How to check whether a Date parsed from Excel is in normal format (e.g. 01/01/2019) or in OA Date format?

I use OpenXml to fill my database with values. One of my generic functions converts each cell's value (string) to a proper type:
convertedValue = Convert.ChangeType(value, realType);
Everything works fine unless it's a date. Sometimes OpenXml reads a date cell like this: 01/01/2019 and conversion works fine. Sometimes it converts to a number like this: 43466. I know that this number represents how many days passed since 1900 but it breaks my function. It cannot convert this number to a DateTime.
I want to add a conversion for OA Dates like this:
convertedValue = DateTime.FromOADate(doubleValue);
The problem is how do I check that the value read from the cell is an OA Date?
I was thinking of checking the length of the value variable and verifing that all characters are numbers. Is there a better way to solve this problem?
Use TryParseExact to determine the format. If it doesn't parse exactly in the format provided, it will return false. Then we know we can use FromOADate method from DateTime
if(DateTime.TryParseExact(valueString, "mm/dd/yyyy", enUs, DateTimeStyles.None, out dateTime))
{
// Handle standard date format
}

Is this c# code enough to handle globalization?

My C# winforms program will be used in following countries
United Kingdom : date format day-month-year , currency separator is '.'
United States : date format month-day-year , currency separator is '.'
Denmark : date format day-month-year , currency separator is ','
I want to make the program run properly irrespective of what regional settings are on users computer. My main concern is handling date format and currency fields
(Language translation is not a problem because the program will only show English text)
To do this I have decided that all dates in the database will be saved with yyyy-mm-dd format and all decimal fields will be saved with . as separator.
I created the database with Danish_Norwegian_CI_AS collation .
So I am assuming the data will be saved in the above datetime format & decimal format without me requiring to do anything special.
I have put the following code in my program
var cult = new CultureInfo("en-GB");
Thread.CurrentThread.CurrentCulture = cult;
Thread.CurrentThread.CurrentUICulture = cult;
CultureInfo.DefaultThreadCurrentCulture = cult;
CultureInfo.DefaultThreadCurrentUICulture = cult;
Please help me by telling from your experience if the above code is enough to make my program safe
Culture applies only in the following two scenarios:
Converting a string representation of a value to a native format, which is called "parsing".
Converting the native format of a value to a string representation, which is called "formatting".
When you store a datetime or a decimal or some other type into the database, it is stored in a native format. In a SQL database, this is usually some compact binary value that you will never work with directly.
Consider the following SQL:
declare #dt datetime
set #dt = '01/02/2015 12:34:56'
select #dt
In the first line, we declare a variable of type datetime. It's not a string, it's a specific data type that takes up 8 bytes of memory or disk.
In the second line, we assign a string value to the variable. SQL parses the string, converting it to a datetime so it can be stored in the #dt variable. The actual value stored has a hexadecimal representation of 0x0000A41400CF5940.
When it did the parsing, the current culture for the environment where the code was running was applied. Because I am in the USA, it interpreted the date as January 2nd. If I was in Europe, it would interpret the date as February 1st (changing the internal value to 0x0000A43200CF5940).
Using dates in yyyy-mm-dd format will avoid misinterpretation, but that does not mean that the actual value is stored as a string in that format. It's just that the format is unambiguous, so it will be parsed the same way regardless of culture.
In the third line of code above, we select the variable to include it in a result set. Though we are selecting it in its native form without any conversion, we ultimately see it in a string representation. If you are running the query in a tool such as SQL Server Management Studio, the output window will format the native values to strings so you can read them. When doing so, the current culture is again applied. SQL's default is to show dates in yyyy-mm-dd format, rather than the culture-specific format. But other values, such as decimals, will use the current culture's separator.
If instead of running this in SSMS you actually retrieved the results through your own code in a SqlDataReader (for example), then formatting never occurs. The reader maps SQL's binary native value directly to the appropriate .NET native type, using the mappings shown here. A SQL datetime gets natively mapped to a .NET DateTime.
DateTime dt = (DateTime) reader["dt"];
Now quite often, you see someone doing silly things like this:
DateTime dt = Convert.ToDateTime(reader["dt"].ToString());
This is wasteful because the value is already a DateTime, and this code would use the current culture to format the string, then use it again to parse the string. That's a lot of string manipulation for no reason whatsoever.
Ultimately, in your .NET code, you will end up using that DateTime value and converting it to a string somewhere for output. When you do, that's when you apply the current culture.
Likewise, when you receive an input string from your user (such as when filling out a form), you parse the value to a DateTime using the current culture again.
Native data types are not strings - and are thus not affected by culture.
Notes:
If you want to see the hexadecimal representation of the native binary form of any SQL data type, you can use something like: select convert(varbinary, #dt)
Be aware of whatever the native format is for anywhere you are working. If you're writing to an http stream, a text file, or a document database, etc., the string representation does indeed matter, because a string is the native format in those scenarios.
And just to prove this applies to more than dates, consider:
select 123, 123.45, convert(varbinary, 123), convert(varbinary, 123.45)
--results: 123 123.45 0x0000007B 0x0502000139300000

A Datetime without time without string.format

I have a DataTable coming from a stored procedure which I'm writing to an excel file. There's a column with a DateTime datatype, and looking at the values in there, they're just generic dates with the time stamp.
I've tried using the DateTime.Date property, but that still gives me a time stamp. Further, I've tried to create a new DateTime object using the year,month,day constructor but it still adds a time stamp:
DateTime newDate = DateTime(oldDate.Year, oldDate.Month, oldDate.Day);
I'm trying to keep the column datatype to DateTime but remove the time stamp, so this rules out ToString("") formatting. Is there another way?
A DateTime always contains a date and a time portion. If you use the Date property it returns a new DateTime where the time is 0:00:00 so midnight at the same day. You want a string representation of the datetime without the time.
You can use DateTime.ToString:
string result = oldDate.ToString("d"); // uses current culture's date format
or
string result = oldDate.ToShortDateString(); // same as above
or
string result = oldDate.ToString("MM-dd-yyyy"); // custom format
Edit: "so this rules out ToString("") formatting. Is there another way?"
No, because of the reason mentioned above.
It's important to separate the data from how it is displayed. If you need to display it without time use the code above, you can store the original DateTime variable for future processing, select it again from database or use DateTime.Parse/DateTime.ParseExcact to get a DateTime from the string.
The 'problem' is that there is no Date struct in .NET, you only have a DateTime struct. That will always contain both date and time. You can only format it as date.
Or, you could of course write your own struct containing only the date part, or give up and use string.Format to format it as a date (possibly using the short date string d).
If you mean time part with timestamp, a DateTime instance always have both date and time part. DateTime.Date property just sets the time value set to midnight.
You can get it's string representation if you want only it's Date part. You can get standard date and time format or custom date and time format with DateTime.ToString() method.
Usually, you can use ShortDatePattern to get only string representation of Date part which uses standard "d" format of your CurrentCulture.
DateTime.Now.ToString("d");
There is a proposal for System.Date and System.Time types for .NET Framework in dotnet/corefx on GitHub page by the way.
Proposal: System.Date type
You should use DateTime.Now.ToShortDateString();

Formatting DateTime value in C#

I have a datetime variable like this:
DateTime date1 = DateTime.Now; // has 9.4.2014 01:12:35
I want to assign this to another datetime or change its value like this:
2014-04-09 13:12:35
How can I do?
Thanks.
EDIT : I don't want string variable. I want it Datetime format.
try this :
date1.ToString("yyyy-MM-dd HH:mm:ss")
Also look at the table below here http://msdn.microsoft.com/en-us/library/8kb3ddd4(v=vs.110).aspx
edit :
As Jon said (and which I didn't mention) :
you should add InvariantCulture ( if you dont want it to be used with current thread culture ) :
CultureInfo heIL = new CultureInfo("he-IL");
heIL.DateTimeFormat.Calendar = new HebrewCalendar();
CultureInfo dft = Thread.CurrentThread.CurrentCulture;
Thread.CurrentThread.CurrentCulture = heIL;
Check these :
DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss",CultureInfo.InvariantCulture);
result ( I live in israel) :
תשע"ד-ח'-ט' 13:32:31
2014-04-09 13:32:31
The code you've written just assigns a value to a variable. It doesn't return anything, and it doesn't have any inherent string representation. A DateTime value is just a date/time. It can be displayed in whatever format you want, but that's not part of the value of the variable.
It sounds like you're wanting to convert it to a string in a particular format, which you should do with DateTime.ToString - but only when you really need to. Try to keep the value as a DateTime for as long as possible. Typically you only need to convert to a string in order to display the value to a user, or possibly to use it in something like JSON. (If you find yourself converting it to a string for database usage, you're doing it wrong - make sure your schema has an appropriate data type for the field, use a parameterized query, and set the parameter value to just the DateTime - nor formatting required.)
The format you've specified looks like it's meant to be a machine-readable one rather than a culture-specific one, so I'd suggest:
string text = date1.ToString("yyyy-MM-dd HH:mm:ss",
CultureInfo.InvariantCulture);
By specifying the invariant culture, we've said that the result shouldn't depend on the current culture (which otherwise it would) - this can make a big difference if the current culture uses a different calendar system, for example.
Something like the following, which is one of the constructors of the DateTime object:
d = new DateTime(2014, 5, 6, 5, 4, 30);
Which will set d to 06/05/2014 05:04:30. Its parameters are in descending size order, so Year, Month, Day, Hour, Minute then Seconds.
If you want to adjust the time by an amount, look at the add methods, or TimeSpans.
you can just use something like this to format the date:
date1.ToString("dd/MM/yyyy HH:mm:ss")
By using "HH" instead of "hh" you will get 24hour format on the hour.
Hope that helps.
Try this
DateTime date1 = DateTime.Now;
string datestring=date1.ToString("yyyy-MM-dd HH:mm:ss",CultureInfo.InvariantCulture)
http://msdn.microsoft.com/en-us/library/8kb3ddd4(v=vs.110).aspx
As a guess, the "returned" value of your DateTime object is seen by you, by hoovering over the variable in the IDE while debugging.
This is just another form of calling internally the default ToString() method of your DateTime object by the debugger. The value is the same.
See: system.datetime
DateTime Values and their string representations
Internally, all DateTime values are represented as the number of ticks (the number of 100-nanosecond intervals) that have elapsed since 12:00:00 midnight, January 1, 0001. The actual DateTime value is independent of the way in which that value appears when displayed in a user interface element or when written to a file. The appearance of a DateTime value is the result of a formatting operation. Formatting is the process of converting a value to its string representation.
Because the appearance of date and time values is dependent on such factors as culture, international standards, application requirements, and personal preference, the DateTime structure offers a great deal of flexibility in formatting date and time values through the overloads of its ToString method. The default DateTime.ToString() method returns the string representation of a date and time value using the current culture's short date and long time pattern.

Date type in MySql

I'm new to MySQL and C#.
I stored certain values in a column with data type Date. I did not want the time, only the date to be stored.
On viewing these values using phpMyAdmin or MySql command line, I see them in the format:
YYYY-MM-DD
However, when I retrieve these values in to my web application, they are displayed in the following format:
YYYY-MM-DD HH:MM (the time is specifically 12:00).
Why does this happen? And how can I prevent this from happening?
when you store in C# your date field, you use DateTime object. In this object when you don't specify the time part will be put a default value depends on Globalization.
You can study how DateTime works here
You can convert the date to the format you like when you fetch the data, using date_format():
select date_format(datecol, '%Y-%m-%d')
This returns the value as a string.
You shouldn't retrieve the value as a string from mysql. Why? Because if you ever need to do any operations on that value, such as adding a day, then you will need to parse it back into a DateTime again. String parsing can be slow, and when it comes to dates they are prone to errors like misinterpretation of mm/dd/yyyy and dd/mm/yyyy formatting.
The problem you have is that .NET does not have just a Date type. It only has a DateTime type. So loading a MySQL DATE type, is going to get a DateTime with the time portion set to midnight.
There's no direct problem with that, except on how are outputting the result. If you just call .ToString() without any parameters, or you implicitly use it as a string, then you are going to get a result with the full date and time. You simply need to provide a parameter to indicate what formatting you want.
Without any parameters, you are getting the General "G" format. This is explained in the documentation here.
In other words:
yourDateTime.ToString() == yourDateTime.ToString("G")
You can read about all of the other formats available, here and here.
In particular, if you just want the date, then you probably want to do this:
yourDateTime.ToString("d")
Based on your comments, you should be doing this instead:
MySQL Query:
SELECT Gbstartdate FROM TblGbDef
C#:
DateTime gb_start_date = (DateTime) datareader[0];

Categories