C#: doing math on weird formatted dateTimes - c#

I've got some Date-timestamps reading in from a log file, the problem is that the log file records these timestamps weirdly, for example:
"2020061515141112" is how its in the file, which represents "2020 06/15 15:14:11.12"
The issue I'm running into is that I've got loglines for start events and end events, and I need to parse out time period between them.
My question is:
in a C# application, how can I parse the strings (yyyyMMddHHmmssff) into a format that can be used by DateTime to perform a <DateTime.Subtract> between them? I'm not super familiar with Date-times and having a hard time getting Visual Studio to agree with the below:
DateTime aDT = DateTime.Parse(aLogDate,"yyyyMddHHmmssff",System.Globalization.DateTimeStyles.None);
which meets the expected format of (string,IFormatProvider,DateTimeStyle) but arguments are invalid (is it the format provider?)
EDIT: we were able to modify the format the Log prints (sort of) to retain leading zeros in their dateTimes, so this is no longer an issue, above still in question)

DateTime aDt = DateTime.ParseExact(aLogDate, "yyyyMMddHHmmssff", System.Globalization.CultureInfo.InvariantCulture);
Help from a friend came first. Heres what I wanted, people were getting to caught up on details, should have made question more concise to begin with

Related

Culture dependent NumberFormat for dates in C# VSTO Excel

I'm relatively new to C# and I'm still learning a lot. I also searched stackoverflow for similar problems but got to a point where I'm stuck.
In my VSTO Excel project I'd like to output dynamic data coming from a database with a predefined number format per column also coming from the database. The user can define his own layout of the report. Everything is working just fine, I have just problems formatting the date value.
When it's about to output a date column, the format should be automatically be determined by the program instead of predefining it in the database as well. The date value gets already inserted in the Excel sheet as the decimal number it should be. Everything okay here. When I manually format it in Excel itself, it is displayed correctly.
But I want to format the date with C# like it would be formatted when I do it manually by clicking on the short date format in Excel. And it should work in every country, regardless in which language the office package was installed.
I'm working with a German installation and I expect the format to be "TT.MM.JJJJ". When formatting the column with this fixed string, it works perfectly (at least in Germany I guess).
It makes no difference if formatting it with
CurrentWorksheet.Columns[queryColumn.Position].NumberFormat = "TT.MM.JJJJ";
or
CurrentWorksheet.Columns[queryColumn.Position].NumberFormatLocal = "TT.MM.JJJJ";
Both end up in the same (correct) result. That the first line is working as well is the first thing which was unexpected for me, but that's not the main point. I tried to format it dynamically by replacing "TT.MM.JJJJ" with the following lines:
// Leads to dd.MM.yyyy
System.Globalization.DateTimeFormatInfo.CurrentInfo.ShortDatePattern;
// Fixed German culture still leads to dd.MM.yyyy
CultureInfo.CreateSpecificCulture("de-DE").DateTimeFormat.ShortDatePattern;
// MM/dd/yyyy - also not helpful
CultureInfo.InvariantCulture.DateTimeFormat.ShortDatePattern;
When using the first or second ShortDatePattern the date 27.08.2014 is shown as "dd.08.yyyy". Excel simply doesn't unterstand "dd" or "yyyy". I thought at least when using NumberFormat instead of NumberFormatLocal it would work, because it's the global format, but it doesn't. It feels like Microsoft has implemented the date formatting more complicated that it could be.
How would I determine the correct date pattern here?
The answer (it still is a kind of workaround) is pretty much found in another question:
How to set localized short-date format for a cell in Excel with C#?
There's just a very small difference I had to make in the method for constructing the ShortDatePattern (the Application parameter for DateFormatComponentCodes).
public static string ConstructExcelShortDatePattern()
{
var systemDateComponentCodes = new DateFormatComponentCodes();
var excelDateComponentCodes = new DateFormatComponentCodes(Globals.ThisAddIn.Application);
string systemShortDatePattern = CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern;
string excelShortDatePattern = systemShortDatePattern.Replace(systemDateComponentCodes.Year, excelDateComponentCodes.Year).Replace(systemDateComponentCodes.Month, excelDateComponentCodes.Month).Replace(systemDateComponentCodes.Day, excelDateComponentCodes.Day);
return excelShortDatePattern;
}
Thanks to Heinzi for finding a great answer and Jordan for providing such a useful class!

Parsing Date Time string produces unexpected results

I'm trying to convert a string which is in the correct format into a date of exactly the same format for a linq query to work against a SQL date.
I've tried several conversion methods but all have failed. The example below shows the issue:
var test = DateTime.ParseExact("2019-04-09 13:15:00", "yyyy-MM-dd HH:mm:ss", null);
produces
{09/04/2019 13:15:00}
I have no idea why the date comes out like this but I would like to come out like:
2019-04-09 13:15:00
I tried with culture info but no luck. Not sure why this happening?
You have a fundamental misunderstanding of how DateTime values work. They do not have any human-readable format. Rather, they are stored as a binary value that is not human readable. The format you're seeing is something provided as a convenience by your debugger.
If you need a different specific format for anything other than use in SQL*, you can call ToString() with the appropriate format string. Just remember when you do that you are no longer working with a DateTime value, but are back to using a string again, and the best practice is to wait as long as possible before going back to strings.
*For SQL, you should be using parameterized queries, where there is a placeholder in the query and your datetime value is assigned directly to the parameter value without converting to a string first.
You parse the date in the correct format, so that's fine. The DateTime-object contains the correct value, so you can use it for your database.
If you want to see it in your prefered format you also need to output it using the same format, otherwise the default format of your user account (or in case of a web request the preferred language of the calling browser) will be used for displaying it.
Console.WriteLine(test.ToString("yyyy-MM-dd HH:mm:ss"));
If you are using Visual Studio, you can execute this command in the "Immediate Window" while running the debugger:
test.ToString("yyyy-MM-dd HH:mm:ss")
In other windows the debugger will use the default output format like described above.

DateTime.Parse can format unusual format strings?

I was looking at a code in an application (Someone else wrote it),on some cases it worked fine and on some cases it gave exceptions,it was actually converting strings in datetime,here is the code
//5000 is the year,but what about "1" is it month or day ?,if its month
//then what about the day ?
DateTime time = DateTime.Parse("1.5000");//1.5000 doesn't looks a date to me ?
time.ToString();//returns "1/1/5000 12:00:00 AM"
//where as if I give this string to DateTime.Parse();
time = DateTime.Parse("2341.70");
//FormatException was unhandled
//String was not recognized as a valid DateTime.
A Confusing thought
How does this string "3.5000" (it matches the 1.5000 pattern) evaluates , does this means 3-3-5000 or 1-3-5000 ,the format is ambiguous its unclear and confusing !
My questions are,
What kind of formats can DateTime.Parse expects ?
Whats happening in the code above ?
Suggestions to improve the code ?
Many people have commented on the possible reasons for the parse that you have seen being successful but your question seems to have several separate parts...
1. What kind of formats can DateTime.Parse expects ?
DateTime.Parse has been written to be as inclusive as possible. Pretty much anything that it can find someway to make into a DateTime it will do its best to do so which means in addition to the usual familiar yyyy-MM-dd type formats more strange ones like M.yyyy or yyyy.M and so on.
2. Whats happening in the code above ?
That is very complicated because the DateTime.Parse method is itself very complicated. You can probably fidn the source code out there somewhere but the complexity made it very hard for me to follow. Without being able to give precise details I'm going to answer this the same as above. What is happening is that the framework is trying its best to give you a date back and not throw an exception. The date it gives is the best guess as to what you meant.
3. Suggestions to improve the code ?
It sounds like if you are getting parse exceptions that you are passing dates in formats that are unexpected. Without knowing what those inputs are its hard to say. Two things could improve your code though. Making sure a single consistent date format is used and then using DateTime.ParseExact to ensure that it conforms to the right format. You will remove all ambiguity this way but you will sacrifice flexibility.
The second option is to use DateTime.TryParse. This will attempt to parse your date and then return a boolean saying whether it succeeded or not. If successful the date parse will be returned in a ref parameter. This won't make your code any better at recognising unknown date formats but will let your code know when such an unparsable format crops up and you can deal with it (eg by providing user feedback reporting the wrong format and suggesting a correct one, or just by logging it or something else).
What the best method is depends mostly on where your input is coming from. If it is user input then I'd go with the second option. If it is automated input then you probably want to make sure your input is standardized and then use the first option. Of course circumstances always vary so this is not a hard and fast rule. :)
In regards to "2. Whats happening in the code above ?":
In some cultures, the date separator is a dot instead of a slash. So for example 13.12.2013 is a valid date (2013-12-13) in the format "dd.MM.yyyy". Now by whatever design choice, the day part in this example is not mandatory and if left out, is automatically filled with 1. So parsing 12.2013 would result in 2013-12-01. And therefore it's easy to see how 1.5000 would become 5000-01-01. 2341.70 can not be parsed, because 2341 is not a valid month. - So in this case 1.5000 is a "valid" date in the format M.yyyy.

Update Path Automatically at date change ?

my program is watching a text file log - generated each day automatically.
now when the day change my program keep using the last day file path,
is there a way to do so without checking that the datetime.day each time and equal it to the day when the app launched at?
i saw SystemsEvent.TimeChanged but it only work when the user change the date manualy,
thanks.
The simple way to do this is make your path using a DateTime object. For example;
string fp = #".\subdir\otherSubdir\somefile-" + DateTime.Now.ToString("MM-dd-yyyy") + ".log";
Of course I don't know what the format of your date is. Docs on format specifiers for DateTime's ToString method can be found here; http://msdn.microsoft.com/en-us/library/8kb3ddd4.aspx
As pointed out in the comments you could also use a FileSystemWatcher however, that is quite a bit more complicated and likely unnecessary here. If you're looking for a more general solution (something that could work with files that use different naming conventions) that would be the way to go.

How to validate string is correct date time

I have some data picked up from an excel file.
I want to validate that the user has entered a valid date time string. I have tried to use DateTime.Parse method but found that certain values seem to be accepted.
For example,
If I submit 3.3 as a date time this is accepted by the DateTime.Parse method as a valid date time and outputs 03/03/2012 00:00:00
I want to want to block this. Only allowing the user to enter correctly formatted date times.
So for example a user could supply 03/03/2012 or 03/03/2012 12:30:00 but not values like 01022012 or 3.3.2012
Any Ideas?
You want to use DateTime.ParseExact or DateTime.TryParseExact
This allows you do parse from a date format string of your choice.
http://msdn.microsoft.com/en-us/library/system.datetime.tryparseexact.aspx
Examples here:-
http://msdn.microsoft.com/en-us/library/ms131044.aspx
You can use RegEx to to this. Something like this should help #"\d{2}/\d{2}/\d{4}(\s+\d{2}\:\d{2}\:\d{2})?"
You can handle it on the client side with various jquery plugin/functions like this or a simple Google search can return many other useful results.
if you want to handle it on the server side, (I am not sure on what project you are working) but depending over it you can write your own method/use Regex or Data Annotation MVC.
If you are still having trouble try adding few details about your project such as Language, Architecture etc. that would help more in providing the right solution.
Hope it helps. Thankyou

Categories