Unable to correctly parse a date from Excel cell - c#

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.

Related

Reading Time HH:mm:ss from excel cell in c#

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

DateTime conversion is not working while reading dates from excel where Day > 12

This is my first 5 rows in my XLSX file:
Note that the format for the ResLastCallDate column is CustomFormat->dd/mm/yyyy hh:mm:ss. Yet, Row 4 looks different than the others for some reason. This is not important a lot tho, the important part is that the XLSX file is being uploaded to my asp.net 4.5 web page where I read the data via EPPlus. However, when I am reading ResLastCallDate column, I am receiving an error. See the code below:
System.Globalization.CultureInfo provider = System.Globalization.CultureInfo.InvariantCulture;
if (!DateTime.TryParse(dr["ResLastCallDate"].ToString(),provider, System.Globalization.DateTimeStyles.AssumeLocal, out resLastCallDate))
{
Msg = Msg + string.Format("Row {0}: ResLastCallDate is not date ({1}).\n", r, dr["ResLastCallDate"].ToString());
}
...
txtDebug.Text = Msg;
I have tried not to use a provider, other DateTimeStyles, none of them worked, except Row 4 in the excel always been read correctly. See the output:
Row 0: ResLastCallDate is not date (20/03/2018 13:58)
Row 1: ResLastCallDate is not date (20/03/2018 13:58)
Row 3: ResLastCallDate is not date (15/03/2018 20:25)
So Row 2 (which equals ClientID=3621) works but others not for a reason. I've tried General and Date formats in the excel for those cells, still not working. What else I can do to handle this issue? Any help would be appreciated.
EDIT: When I convert it to dr["ResLastCallDate"].ToString() only (no provider I use), it works on my local machine, but when I publish to the server it does not work (same error message received)
It appears that CultureInfo.InvariantCulture does not like to receive strings in that particular format. I believe it's related to the fact that in the US date is written in MM/dd/yyyy order whereas in Europe it is written in dd/MM/yyyy (which includes the UK, and Australia).
If that's the case, 20/03/2010 13:58 would have been parsed as 3rd day of 20th month, 2010, which does not make any sense.
I believe using `new CultureInfo("en-gb") instead of CultureInfo.InvariantCulture would be better choice here.
Please use an appropriate culture.
var originalDate = "6/4/18 6:07 PM";
DateTime parsedDate;
var culture = System.Globalization.CultureInfo.CreateSpecificCulture("en-AU");
var styles = System.Globalization.DateTimeStyles.None;
if (!DateTime.TryParse(originalDate, culture, styles, out parsedDate))
{
Console.WriteLine(parsedDate);
}
Console.WriteLine($"Parse successfull: {parsedDate}");

Date format problem in C#? While retrieving data from Excel

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.

Webtest - Using Dates as Context Parameters

I've created a webtest and have a CSV data source that contains a column with a list of short dates (MM/dd/yyyy)
I need to manipulate the parameter due to part of the web page I'm testing has a form parameter that needs it to be formatted as yyyyMMdd
When the date that is captured from the data source (ex: 02/12/2016), I noticed in the Context tab of my test run that the format to "2/12/2016 12:00:00 AM"
I've created a Request plug-in and added the following code:
public override void PreRequest(object sender, PreRequestEventArgs e)
{
base.PreRequest(sender e)
string CSVDate = e.WebTest.Context["<datasource date column>"].ToString();
DateTime dt = DateTime.ParseExact(CSVDate, "MM/dd/yyyy HH:mm:ss", System.Globalization.CultureInfo.InvariantCulture);
e.WebTest.Context.Add("NewDate", dt.ToString("yyyyMMdd"));
}
This generates a String was not recognized as a valid DateTime error. I tried changing the format to MM/dd/yyyy, but I encountered the same error.
Does anyone know how the correct DateTime format I should be using?
The date-time as shown in the context is 2/12/2016 12:00:00 AM. This has only one digit for the month whereas the format specifier has MM which wants two digits. The date-time also contains the letters AM that are not matched by the format.
Modifying the format to be M/dd/yyyy HH:mm:ss matches the date-time 2/12/2016 12:00:00, but does not match the AM part. In theory the tt format specifier should match this, but it did not work for me.
Rather than using ParseExact you can use Parse and it works out the correct format. Using the following worked on the date-time string provided:
DateTime dt1 = DateTime.Parse(CSVDate, new System.Globalization.CultureInfo("en-US"));
The CultureInfo is needed because the input date has the month and the days the wrong way around.
However, the real problem is in the way CSV files are handled by the web test. It appears to read them using the same logic as Microsoft Excel uses when reading CSVs. Namely, if it looks like a date then convert it to a date. So any string matching dd/dd/dddd (where d is a digit) might be connverted to a date. (E.g. 15/15/2017 will not be converted because 15 is not a month number.) I recommend rewriting the CSV to format the input date differently, use something that Excel would not treat as a date. One option is to have the date in three columns of the CSV, so have explicit day,monthandyearcolumns. Another option is to add non-date characters to the string and format it correctly, eg asz20160212and then remove thezwithin the web test. Generally, I would advise to avoid the conversion of string toDateTime` then another conversion to a different string.

DateTime problem when day <= 12

I've looked around a lot and short of writing a horrible chunk of code to manipulate the string, I'd like to ask if anyone knows a nice way of sorting it:
I have a bunch of date strings in cells that I'm pulling out such as:
03/05/2011
27/05/2011
31/05/2011
03/05/2011
09/05/2011
31/05/2011
etc.
While I'm reading any entires where the day can be construed as a month - i.e. entries 1, 4 and 5 above - it gets put in as a DateTime with the day and month swapped.
For example, 03/05/2011 gets read in as a DateTime "05/03/2011 00:00:00"
The others are all read and nicely provide me with a simple string of "27/05/2011".
I'm getting this info from Excel, using
((Excel.Range)worksheet.Cells[rowCount, 3]).Value.ToString()
If I try Value2 as with my other lines, it reads those odd dates as things like "40607" but again, will read the other dates normally.
If you use the DateTime.ParseExact function to convert a string to a DateTime object, you can specify the specific format used by your dates (which looks like "day/month/year") without having to do any string manipulation whatsoever.
Example:
var dateString = "03/05/2011";
var format = "dd/MM/yyyy";
var date = DateTime.ParseExact(dateString, format, CultureInfo.InvariantCulture);
More information on custom Date and Time format strings can be found here.
EDIT: Try using the DateTime.FromOADate method to convert the value returned by the Range.Value2 property to a DateTime object, e.g. something like this:
var dateTime = DateTime.FromOADate(((Excel.Range)worksheet.Cells[rowCount, 3]).Value2);
DateTime.ParseExact Method converts the specified string representation of a date and time to its DateTime equivalent using the specified format and culture-specific format information.
The format of the string representation must match the specified format exactly.
String dateString = "15/06/2008";
String format = "dd/MM/yyyy";
DateTime result =
DateTime.ParseExact(dateString, format, CultureInfo.InvariantCulture);
That sounds like a localization problem. Try setting your locale implicititly. For example in WPF application it's something like:
System.Threading.Thread.CurrentThread.CurrentCulture =
new System.Globalization.CultureInfo("en-US");
I have a bunch of date strings in cells that I'm pulling out such as:
No, you don't. You have a mix of strings that look like dates and dates that look like strings. This is an Excel issue, not a C# issue.
Not sure if you are creating the spreadsheet, or if you are getting it from somewhere else. But it the problem is that Excel attempt to parse text as it is entered in the cell. In this case, it is making some wrong decisions about the dates it finds.
If you enter a date like "03/05/2011", Excel will (incorrectly) parse it as March 5th, 2011, and store that as a numeric date code (40607). It then applies a date formatting to the cell (it uses m/d/yyyy on my machine).
If you enter a date like "31/05/2011", Excel can't parse it as a date, and it stores it as text.
To prove this, select the cells and go to Edit > Clear > Formats. All the "bad dates" will just show as numbers, all the rest will stay looking like dates.
You have a few choices:
Fix the data before its entered into Excel (prepend everything with a ' so its all entered as text, or make sure to create the spreadsheet on a machine that has the right date settings.)
Don't use the .Value.ToString() from Excel, just use .Text. This will ignore the bad parsing that Excel did, and should give you a consistent text value (from both types) that you can ParseExact with C#, per the other answers.
(2) is a lot easier, and if the spreadsheets already exist, may be your only choice.
The problem is because your Dates are being read as american culture or similar.
If you use the following you can specify the format you expect your dates to be in:use
DateTime result;
if(DateTime.TryParseExact("dd/MM/yyyy", out result))
{
// Got an English date
}

Categories

Resources