How to parse default git date format in C# - c#

How do you parse the default git format to a DateTime in C#?
As per What is the format for --date parameter of git commit
The default date format from git looks like Mon Jul 3 17:18:43 2006 +0200.
Right now I don't have control over the output, this strings comes from another tool that printed the date and I need to parse it.

I wouldn't parse this to DateTime, I would parse it to DateTimeOffset since it has a UTC offset value inside of it.
Why? Because if you parse it to DateTime, you will get a DateTime as Local and it might generate different results for different machines since they can have timezone offsets of that time.
For example, I'm in Istanbul and we use Eastern European Time which use UTC+02:00. If I run the example of your code with ParseExact method, I will get the 07/03/2006 18:18:43 as a Local time.
Why? Because in 3 July 2006, my timezone was in a daylight saving time which is UTC+03:00. That's why it generates 1 hour forwarded result. That's the part makes it ambiguous when you parse it to DateTime.
string s = "Mon Jul 3 17:18:43 2006 +0200";
DateTimeOffset dto;
if (DateTimeOffset.TryParseExact(s, "ddd MMM d HH:mm:ss yyyy K",
CultureInfo.InvariantCulture,
DateTimeStyles.None, out dto))
{
Console.WriteLine(dto);
}
Now, you have a DateTimeOffset as 07/03/2006 17:18:43 +02:00. You can still get the DateTime part with it's .DateTime property but it's Kind will be Unspecified in that case.
But of course, I suggest to use Noda Time instead which can solve most of the DateTime weirdness.

So far the best format string I found is ddd MMM d HH:mm:ss yyyy K.
DateTime date;
DateTime.TryParseExact(
gitDateString,
"ddd MMM d HH:mm:ss yyyy K",
System.Globalization.CultureInfo.InvariantCulture,
System.Globalization.DateTimeStyles.None,
out date
);

Related

Parsing Twitter Created At Date as UTC

I realize there are many threads about parsing twitter dates, but I am having a peculiar issue, and haven't been able to find any threads specific to this.
I am retrieving this post: https://twitter.com/bodegamcallen/status/1033757489567805440
which has a created date of 8/26/2018 at 9:46 AM Central Time.
The created date in the api is this: "Sun Aug 26 16:46:06 +0000 2018"
Which makes sense as 16:46pm (2:46pm) UTC is 9:46 AM Central (-500).
However, I'm parsing this using this code:
statusModel.DatePosted = DateTime.ParseExact(
this.created_at, "ddd MMM dd HH:mm:ss zzzz yyyy",
CultureInfo.InvariantCulture.DateTimeFormat, DateTimeStyles.AssumeUniversal);
and instead of getting the desired UTC time shown above, I'm getting this: 8/26/2018 4:46:06 PM
If I change the DateTimeStyle to None or AssumeLocal, I get this: 8/26/2018 11:46:06 AM
Neither of which is correct!
I've tried different formats from other threads like:
"ddd MMM dd HH:mm:ss K yyyy"
"ddd MMM dd HH:mm:ss Z yyyy"
"ddd MMM dd HH:mm:ss zzz yyyy"
"ddd MMM dd HH:mm:ss +ffff yyyy"
I also tried using DateTimeOffset.Parse and changing the culture to mine (en-us)
they all give me the same results.
What am I doing wrong? How do I get the datetime to be the same UTC time as the date value I'm getting from the API?
Aha! It turns out that my twitter account settings were configured to be in Pacific Time, rather than Central Time, and that would account for the two hour difference.
I changed my time zone settings for my account as described here: https://help.twitter.com/en/managing-your-account/how-to-change-time-zone-settings
And after changing to Central Time, the API data is coming in correct!
hope this helps someone else. Time zones, amirite?
A few things:
zzzz is not a valid specifier. Always check these docs if you're uncertain.
K is the only time zone specifier that is appropriate for DateTime parsing. The others (z, zz, and zzz) are for DateTimeOffset parsing.
When there is any offset or time zone information in the input string (even if it's +0000 or Z), DateTime.Parse and DateTime.ParseExact will assume by default that you want the output kind to be DateTimeKind.Local and that you want the value adjusted to local whatever it is in the input string. Examine the output .Kind if you're not certain if it's working correctly. If you want UTC instead, you should pass DateTimeStyles.AdjustToUniversal.
You don't need to pass DateTimeStyles.AssumeUniversal, because there is time zone information present in the input string.
It's not invalid, but you don't need to pass CultureInfo.InvariantCulture.DateTimeFormat. It's sufficient, and more common, to pass CultureInfo.InvariantCulture.
Putting this all together, your code should be:
statusModel.DatePosted = DateTime.ParseExact(
this.created_at, "ddd MMM dd HH:mm:ss K yyyy",
CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal);
And of course, you'd save some hassle and confusion if you changed your DatePosted to be a DateTimeOffset type instead. It's superior for this sort of scenario, and then you don't have to worry about DateTimeKind or DateTimeStyles.

Convert timezone specific datetime string to datetime in C#

How can I convert Tue, 01 Nov 2016 02:00 PM EET datetime string to DateTime in C#? What is a good practice to do it?
Use DateTime.TryParseExact with a format string that represents a generic datetime.
If you can have multiple formats then use the DateTime.TryParseExact overload that takes an array of formats.
You can find all the format strings here:
Custom Date and Time Format Strings
For example, "Tue" is represented by "ddd", "Nov" by "MMM" etc.
NOTE: The string formats are case sensitive so while "M" represents the month number, "m" represents the minute number. Getting them mixed up will cause the parse to fail.
By replacing timezone abbreviation with zone offset you can convert using DateTime.ParseExact
string date = "Tue, 01 Nov 2016 02:00 PM EET";
DateTime dt = DateTime.ParseExact(date.Replace("EET", "+2"), "ddd, dd MMM yyyy hh:mm tt z", CultureInfo.InvariantCulture);
and if you want more safer way by checking exception then you can using DateTime.TryParseExact method
Use DateTime.TryParseExact where the format string is built using this table.
Custom date and time formats does not recognize timezone abbrevations. You need to escape them as a string literal delimiter.
var dt = DateTime.ParseExact("Tue, 01 Nov 2016 02:00 PM EET",
"ddd, dd MMM yyyy hh:mm tt 'EET'",
CultureInfo.InvariantCulture);
dt.Dump();

converting a string to date in the exact manner

I have a string "11 Jan 2011" which I want to convert to the datatype date (i.e 11 Jan 2011).
I have tried all resources about datetime.parse, datetime.parse exact but all these things gives me the same output 2011/01/11 12:00:00 AM. I really don't understand this behaviour. I tried the following:
1.DateTime date = DateTime.Parse("11 Jan 2011");
2.DateTime date = DateTime.ParseExact("11 Jan 2011" , #"dd MMM yyyy", System.Globalization.CultureInfo.InvariantCulture);
parsing and displaying are not the same thing
you parse the original string to a DateTime object but display results using Date/Time format strings
Both your calls are correct.
A DateTime structure preserves no information about formatting; it just represents the raw date and time.
What you need to do is ensure that when you display your date, you do so in the correct format - e.g. by calling string displayString = date.ToString("dd MMM yyyy");

Troubles parsing DateTime from string

I am currently trying to parse a string that is obtained from an xml that is downloaded from the web every few minutes. The string looks like this:
Thu Jul 12 08:39:56 GMT+0100 2012
At first I just did a string.split and took out everything after the time (GMT+0100 2012) and inserted 2012 after the date.
This worked great until the date changed to:
Thu Jul 12 08:39:56 GMT+0000 2012
So I would like to dynamically pasre the GMT+ whatever as they send me that string in c#.
Any advice would be appreciated.
You can use DateTime.ParseExact with a custom date and time format string:
DateTime.ParseExact("Thu Jul 12 08:39:56 GMT+0000 2012",
"ddd MMM dd hh:mm:ss 'GMT'K yyyy",
CultureInfo.InvariantCulture)
This will throw a format exception if the string and format string do not match exactly, so you may want to use DateTime.TryParseExact that will return a false if it fails.
Instead of DateTime you may want to use DateTimeOffset that preserved timezone information , as #Keith commented - this may be important to your application.
Two things you can do: First, you should be able to use a custom format string with a ParseExact method, either from DateTime or DateTimeOffset (I would use DateTimeOffset if the actual time zone of the stamp is important, and not just the equivalent time in UTC or your local time zone).
Have a look: DateTime custom format string
The format string would probably be something like #"ddd MMM dd HH:mm:ss 'GMT'zzzz yyyy".
However, there's one snag; the .NET time zone offset ("zzzz" or simply "K") always includes a colon between the hour and minute when expressed as a string, which your input strings do not have. There is no way I know of to specify that the time zone offset doesn't/shouldn't have this colon, and I'm pretty sure that trying to parse it without a colon would cause an error.
The simplest workaround is to remove that specific colon from the string prior to parsing it. The code for that given your input is simply to remove the last colon character in the string:
var updatedString = inputString.Remove(inputString.LastIndexOf(':'), 1);
Try DateTime.Parse method to parse your date.
This should work:
XmlConvert.ToDateTime(textBox1.Text, "ddd MMM dd HH:mm:ss 'GMT'zzzz yyyy");

Twitter time to local time c#

How do i convert the time of tweets made by the user to localtime? The created_at gives me the time of the tweet created and is based on the user's country, how to i change it to my localtime using c#. The format of the time is "Fri Jul 27 15:14:11 +0000 2012". What do they mean by utc_offset and how can it be used to change the timezone?
I am not really familiar with the timezone stuff, thank you for your help :)
You'll want to use the DateTimeOffset structure. This allows you to capture a date and a time as well as offset from UTC as well.
The format that you want to use for Twitter times is:
string twitterDate = "Fri Jul 27 15:14:11 +0000 2012";
DateTimeOffset dt = DateTimeOffset.ParseExact(twitterDate,
"ddd MMM dd HH:mm:ss zzz yyyy", CultureInfo.InvariantCulture);
Note that while not documented, zzzz does work as a custom date time format and succeeds in parsing the offset correctly. This means you should be careful in relying on it in the future (unless the documentation changes to reflect this functionality).
Once you have the DateTimeOffset, you know the offset from UTC. If you want to get it in your local time, you can call the ToLocalTime method on the DateTimeOffset that was parsed and it will return an instance that has an offset based on your local settings.
This should be it:
DateTime localDateTime = DateTime.ParseExact(dateString, "ddd MMM dd HH:mm:ss zzz yyyy", new CultureInfo("en-US"));
Unless you give a DateTimeKind in the constructor of a DateTime, the DateTime will be in the timezone the administrator of the workstation/server has selected for Windows.

Categories

Resources