Below is the image of my code please have a look on it.
I am trying to retrieve data from excel sheet and storing it into database table through SQL bulkcopy.
Error:
The date format is 05-01-2019; it is inserted as 2019-05-01 (database) incorrectly - correct date is 2019-01-05.
When date is greater than 12 it stores in correct format.
2019-12-25 (database) correct
Excel : 25-12-2019
convert your string to a date first with
DateTime.ParseExact("25-12-1986", "dd-MM-yyyy", NULL)
then format it into your date
you can also consider TryParseExact to check for wrong format
your problem is that 05-01-2019 tends to mean 'May 1st 2019' in US style date formats, therefore you need to be very careful with formats. The policy of automatically making 25-12-1966 into 25th December (which is all it could be interpreted as) is not as helpful as it seems.
Related
I need to extract the time from an excel file. The time in excel is expressed in hours:minutes:seconds. The c# code i have that reads the time is:
DateTime dt = DateTime.Parse(worksheet.Cells[row, 3].Value.ToString());
string GetTime = String.Format("{0:t}", dt);
This code works perfect with one file but when i insert another similar file it does not reads the time. Does anyone know why this happens.
Excel table that DOES read the time:
Id
Date
Time
1
18/11/2022
11:51:00
Excel table that DOES NOT read the time:
Id
Date
Time
1
08/08/2022
06:54:00
Excel supports dates natively. Dates are stored in binary form (specifically a floating point number), not as text. They have no format. How they're displayed depends on the cell's numeric format and the end user's locale settings, but the actual value remains binary.
Even when you see a time text in a field, the underlying value is a DateTime whose numeric style shows only the time part. You can test that by changing the cell's numeric style to a full date time or number.
All Excel libraries will load Excel dates as .NET DateTime values. If the Excel sheet contains actual dates, Value is already a DateTime. To get its time part use the DateTime.TimeOfDay property.
For example :
TimeSpan time = ((DateTime)worksheet.Cells[row, 3].Value).TimeOfDay;
I found the solution you have to use FromOADate to get the correct format.
DateTime dt = DateTime.FromOADate((double)worksheet.Cells[row, 3].Value);
I'm importing Excel rows and one of the columns is a Date field. There are two scenarios in which I receive the date.
The first is I receive the date correctly as a Double. For this scenario a simple DateTime.FromOADate(parsedDouble) works.
The second scenario is for whatever reason, the client has not properly formatted the cell or the value in the cell has not been recognised correctly although is a valid date. For example the date will be 1/12/2016 which in the UK format is 1st December 2016. Excel also passes format information for the cell, so in this case it passes through the cell format "dd/mm/yyyy". This is the correct day/month/year format in excel however I need to be able to parse it in c# and I'm unable to because lower case mm is minutes and not months.
So the following won't work.
var x = DateTime.ParseExact("12/12/2016", "dd/mm/yyyy", System.Globalization.CultureInfo.InvariantCulture);
It will output 12/01/2016 00:12:00
I've had a look around and can't seem to find anyone else having the same issue and I'm not quite sure how to deal with this.
An obvious (undesirable) solution would be to hack it and map the excel format of dd/mm/yyyy to dd/MM/yyyy.
I get some data from a PICK/UniVerse database that includes dates in a 4 or 5 character numeric format. Here are some examples .. I grabbed the date values from the database, and compared it to the date being shown in an application:
9832 12/1/1994
10027 6/14/1995
10594 1/1/1997
Is it possible to convert these into something that can be put into Access as a Date/Time value?
As A test, I put 9832 in Excel as a General format and then change it to Short Date, it comes up as 12/1/1926. So it's off by exactly 68 years. This was true for 10027 and 10594 as well.
In C# you can use DateTime.FromOADate
DateTime dt = DateTime.FromOADate(41481);
Returns a DateTime equivalent to the specified OLE Automation Date.
That will give you:
dt = {26/07/2013 12:00:00 AM}
Later on you can insert that Date in your Access database.
Access Date/Time values are actually double precision floats. The whole number portion represents the day and the integer portion represents the time of day.
It looks like those Pick date numbers correspond directly to the date portions of Access Date/Time values. So you can use CDate to transform them.
? CDate(41481)
7/26/2013
Experiment some more to get a feel for this:
? Date()
7/26/2013
? CDbl(Date())
41481
Note, although your question is tagged with c#, you don't need that to do these conversions. You can do them with an Access query and ask the db engine to apply those functions.
Since it turned out those date numbers are consistently offset by 68 years, you can still do the conversion in an Access query.
? DateAdd("yyyy", 68, CDate(9832))
12/1/1994
? DateAdd("yyyy", 68, CDate(10027))
6/14/1995
? DateAdd("yyyy", 68, CDate(10594))
1/1/1997
Or ...
? CDate(9832 + CLng(24837))
12/1/1994
? CDate(10027 + CLng(24837))
6/14/1995
? CDate(10594 + CLng(24837))
1/1/1997
A little late to this thread but I'll post some more detail: The Pick / MultiValue DBMS stores dates as an integer with date 0 = 12/31/1967. So as I write this on Jan 16, 2014 the internal Pick date is 16818. If you use the following you'll get that magic number 24837:
DateTime.Parse("12/31/1967").Subtract( DateTime.FromOADate(0)).Days
So add that to your Pick Date to get the OADate.
If you're using any of the common MV DBMS libraries for extracting data (UniObjects, U2.NET, mv.NET ...) you shouldn't need to convert the date like this. A typical function might look like:
string date = OConv( record["PurchaseDate"], "d2/" ); // "01/16/14"
Or rather than extracting the data in the internal DBMS format, you really should be getting it in external format to start. Ask the DBMS developer who provided the data to do this for you. It's real easy on their side to return " date'd2/' " rather than just "date".
Feel free to contact me directly if you need more info in this area.
All multivalue database dates (this includes UniVerse and UniData) are based on a base date of 31st December 1967. You can resolve this to an external data in a number of ways.
The favourite - e.g. if using SQL or one of the internal database tools is to create a data dictionary entry for the field concerned with a date conversion field, For example:
'D2' for a 2-digit year
'D4' for a 4-digit year
'D4/' for a 4-digit year with slash separators
'D4/E' for a 4-digit year with slash separators and explicitly in European format (DD/MM/YYYY) as compared to US format (MM/DD/YYYY).
If no explicit formatting is given then the format will default to environmental settings. There are other formatting options as well and many can be used in combination (as with the above).
As previously advised, the alternative is to adjust the raw date with a formula. The date is in days since 31st December 1967 - The base data for all multivalue databases.
I am trying to parse a date that is coming from a source as "02/11/2013"
In my application, I set the user's culture to either en-CA or en-FR, with their date format's being "dd/MM/yyyy" or "M/d/yyyy"
If I parse the date, and pass in the format, will this work or does it depend on which format I saved to the database?
if (DateTime.TryParseExact(dateString, Thread.CurrentThread.CurrentCulture.DateTimeFormat.ShortDatePattern, null, System.Globalization.DateTimeStyles.None, out dtResult))
{
dt = dtResult;
}
I can think properly right now so I need some clarification.
Me passing in the format of "dd/MM/yyyy" or "M/d/yyyy", does this format the date no matter what format the source is in, or is it me telling the datetime parse that the source will be in this format so use this?
What I am weary of is that someone is saving to the db in one format, and then a french person wants to read the date and their own format (yes I should be storing in utc).
ADO.NET is strongly typed; there are well known types for storing most data. In the case of dates, that would be DateTime in .NET and datetime in most database systems. If you ever need to worry about culture, then you're already doing it wrong, because you are passing the data around as a string rather than as a DateTime / datetime.
This then renders your concern here redundant:
What I am weary of is that someone is saving to the db in one format, and then a french person wants to read the date and their own format (yes I should be storing in utc).
because a DateTime / datetime has no notion of format - it is simply a date/time value. Any UI presentation / parsing of string data should be completely isolated and specific to the UI. Beyond the UI code you should (when talking about dates/times) be using DateTime / datetime exclusively.
Similarly, when storing an integer you should be using int.
If the date is stored only as "02/11/2013" without any other culture identifying information there is no way for you to know how to properly interpret it! You are absolutely right being worried that somebody with a en-FR culture might save a date to the database as "02/11/2013" meaning the 2nd of November and then somebody with an en-US culture might read that date and interpret it as the 11th of February.
You should only pass the current culture if you know that is relevant, meaning that you know the date string was generated using that culture.
A better approach is to NOT store dates like that in the first place. It's best to store the date in a format that includes timezone as well as format information such as the Internet Date/Time RFC 3339 format.
Or, if you can't, at least make sure to take the date and always convert it to say en-US culture before storing in the database and than pass that culture to the DateTime.Parse when reading from the database.
The .NET XML serialization code for dates can come in handy when serializing/deserializing dates in RFC 3339 format. See this SO post for more info..
In my SQL Server I have this date format: dd-mm-yyyy, and I have some dates matches to this format. But when I use a datagridview in my application, it parses as mm-dd-yyyy but show dd-mm-yyyy. So if I have 05.12.2012 in my database, it thinks that 05 is month so it shows as 12.05.2012.
I have tried to use
Application.CurrentCulture = new CultureInfo("tr-TR");
but it did not work.
I should change the parsing format of my application, not showing format. How can I do that?
Thank you.
You should refer to the 'SET DATEFORMAT' command to set the format of the date. However, I think you problem lies somewhere else. You should be able to access the date column as a datetime value in c#. Usually data is passed in it's native format and so you should not have problems like the one you describe.
You can also send your date in the same date format in sql from your application.
Convert your date to sql format using the culture.
This works for me as we are using different culture in one application.