I am currently working on a dotnet core 3.0 app that needs to parse different datetime strings into a System.DateTime. My development environment is VS2019 on Windows 10 but the application will run on Raspbian (debian-arm) later.
Let’s look into this example code:
// input string
const string testdate = "Jan. 1 01:05:26";
var dateFormats = new[] { "MMM. d HH:mm:ss", "MMM. dd HH:mm:ss" };
var dateTime = DateTime.ParseExact(testdate, dateFormats, CultureInfo.CurrentCulture, DateTimeStyles.AssumeLocal);
// output should be: 01.01.2020 01:05:26
Console.WriteLine($"Date: {dateTime.ToString("dd.MM.yyyy HH:mm:ss")}");
While this works as expected in development under windows 10, it will throw an exception on raspbian:
System.FormatException: String 'Jan. 1 01:05:26' was not recognized as a valid DateTime.
I already checked the CultureInfo but both of the systems are set to the same one. Is there something i am missing here? How can i ensure that these DateTimes are parsed correctly on raspbian?
Update:
I just noticed the year part of the date is missing. Is this the reason for that exception? but why is it working on windows and assuming the current year?
Solution:
As nl-x suggested, i tried printing the current datetime formated as my input dateformats. and there it was:
DateTime.Now.ToString("MMM. d HH:mm:ss")
// Windows output: Jan. 2 16:29:45
// Raspbian output: Jan.. 2 16:29:45
Apparently raspbian already includes the trailing dot in “MMM” format while windows does not. Changing my date formats to:
var dateFormats = new[] { "MMM. d HH:mm:ss", "MMM. dd HH:mm:ss", "MMM d HH:mm:ss", "MMM dd HH:mm:ss" };
now works both in windows and linux. thank you!
2
Answers
Try using invariant culture, or set the culture explicitly.
Your local system might be running in a different language than your Linux system.
What “Jan” is on your local system, might be different on the Linux system.
Try printing a date with the current format from your linux, and see if it uses something else for “Jan” EG
dateTime.Now.ToString("MMM. d HH:mm:ss", "MMM. dd HH:mm:ss")
The problem that you run into with your code is that windows and linux display dateTime in different ways. You’ve worked around that by using the var[] dateFormats. Then as a next argument you passed the CultureInfo.CurrentCulture which takes the variability of your dateFormats if I get that right. Looking ath the .NET forums I don’t really know why the invariant culture does not work at this point. I suggest that you implement a method “parseLinux(var dateTime)”, and a boolean parseToLinux that you set to true or false in the beginning of your program depending on the platform the programm runs on. The function takes the windows format and by .Split() you can now “Hardcode” the differences in format yourself. After you set your dateTime you can call the function like this
dateTime = parseToLinux(dateTime).
If you keep this function call in an if-statement your program should be flexible and independent again. I know this is not the way you intended the problem to be solved but right now it seems to be the easiest to change the arrangement manually.
Some webpages that seem promissing:
https://blogs.msdn.microsoft.com/mikekelly/2009/01/17/unix-time-and-windows-time/
https://social.msdn.microsoft.com/Forums/en-US/55dd74ed-6538-44a1-a843-0b7000c312f4/how-to-convert-windows-date-time-to-unix-date-time?forum=netfxbcl
I hope I could help you
~one friendly programmer