Date Formatting C# - c#

I am having an issue converting this date format into another format. I was hoping that somebody on here would be able to help me out.
Here is my code:
string fromFormat = "ddd, dd MM yyyy HH:mm:ss zzz";
string toFormat = "yyyy-MM-dd";
DateTime newDate = DateTime.ParseExact("Mon, 25 03 2013 00:00:00 GMT", fromFormat, null);
Console.WriteLine(newDate.ToString(toFormat));
-------EDIT--------
I was able to get rid of my errors by changing the day from 22 to 25. My new issue is trying to get the timezone to convert from GMT to EST. Would anyone have any ideas?
-------EDIT #2-------
Here is my current code as it stands. I am still having issues with a timezone conversion.
var date = "Mon, 25 03 2013 00:00:00 GMT";
// Cuts off "GMT" portion of string
string newdate = date.Substring(0, 24);
// Switches the output of date
string fromFormat = "ddd, dd MM yyyy HH:mm:ss";
string toFormat = "yyyy-MM-dd";
DateTime newDate = DateTime.ParseExact(newdate, fromFormat, null);
string finaldate = newDate.ToString(toFormat);
// Output final date
Console.WriteLine(finaldate);
-------EDIT #3-------
The code:
var input = "Mon, 25 03 2013 00:00:00 GMT";
var inner = input.Substring(0, 24);
var format = "ddd, dd MM yyyy HH:mm:ss";
var zoneId = "Eastern Standard Time";
var parsed = DateTime.ParseExact(inner, format, CultureInfo.InvariantCulture);
var utcDateTime = DateTime.SpecifyKind(parsed, DateTimeKind.Utc);
var eastern = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(utcDateTime, zoneId);
Console.WriteLine(eastern);
The error:
Unhandled Exception: System.TimeZoneNotFoundException: Exception of type
'System.TimeZoneNotFoundException' was thrown.
at System.TimeZoneInfo.FindSystemTimeZoneByFileName (System.String id, System.String
filepath) [0x00000] in :0
at System.TimeZoneInfo.FindSystemTimeZoneById (System.String id) [0x00000] in :0
at System.TimeZoneInfo.ConvertTimeBySystemTimeZoneId (DateTime dateTime, System.String
destinationTimeZoneId) [0x00000] in :0
at Program.Main () [0x00000] in :0
Any help would be much appreciated! Thanks!
-------FINAL EDIT-------
This is what ended up changing the timezone and converting to the format that I needed. Special thanks to #MattJohnson for all of his help!
// Cuts off 'GMT' portion of string
var newdate = date.Substring(0, 24);
var fromFormat = "ddd, dd MM yyyy HH:mm:ss";
var toFormat = "yyyy-MM-dd";
var zoneId = "Eastern Standard Time";
var parsed = DateTime.ParseExact(newdate, fromFormat, CultureInfo.InvariantCulture);
// Specifies UTC time and converts it to EST timezone
var utcDateTime = DateTime.SpecifyKind(parsed, DateTimeKind.Utc);
var eastern = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(utcDateTime, zoneId);
// Converts date to final format needed
var finaldate = eastern.ToString(toFormat);

string fromFormat = "ddd, dd MM yyyy HH:mm:ss zzz";
The error is your zzz, it is expecting the numerical representation of the timezone, not the abbreviation of the timezone.
So a acceptable version would be
DateTime newDate = DateTime.ParseExact("Mon, 22 03 2013 00:00:00 +0:00", fromFormat, null);
but that would throw a different FormatExecption with the message "String was not recognized as a valid DateTime because the day of week was incorrect." If you make the Monday to Friday correction the parse works
DateTime newDate = DateTime.ParseExact("Fri, 22 03 2013 00:00:00 +0:00", fromFormat, null);
I don't think there is a format specifier that can take in the textual abbreviation version of the timezone.

As others pointed out, the input value you have is self-inconsistent. It refers to a March 22 2013 as a Monday when it is actually a Friday. So you should go back to your source data and figure out why that happens. I'm sure you have heard the saying, "Garbage In, Garbage Out".
If you are sure you want to ignore the day of week, and you are certain that the time zone will always be GMT, then you can do this:
var input = "Mon, 22 03 2013 00:00:00 GMT";
var inner = input.Substring(5, 19);
var format = "dd MM yyyy HH:mm:ss";
var parsed = DateTime.ParseExact(inner, format, CultureInfo.InvariantCulture);
var utcDateTime = DateTime.SpecifyKind(parsed, DateTimeKind.Utc);
Note that I explicitly set the kind to UTC, because you are bringing in GMT values. GMT and UTC are identical for all practical purposes.
If it's possible that other time zone values will be passed, then please provide a sampling of different possible inputs and perhaps we can find a way to accommodate that.
As an aside - this string looks very similar to RFC822/RFC1123 formatted dates, except you are passing the month as a number instead of one of the three-letter abbreviations. Did you do this intentionally? If so, you have broken the spec for this format. If your intention was to remove potentially localizable strings from the data, then please use a format that is already designed for that, such as ISO8601/RFC3339.
On Time Zones
You said you want to convert to EST, You probably mean "US Eastern Time", which alternates between EST and EDT for daylight saving time. Despite this, the Windows Time Zone database uses the id of "Eastern Standard Time" to refer to both values - so try not to get confused on that point.
Once you have the date as a DateTime of Utc kind, as I showed above, you can convert that to Eastern Time with the following:
var zoneId = "Eastern Standard Time"; // don't get confused here! :)
var eastern = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(utcDateTime, zoneId);
Just be careful what you do with this value. If you are displaying it to an user, then you are ok. Just do this:
var s = eastern.ToString("g"); // or whatever format you want.
But if you do math with this, or store it as an recorded event time, you are potentially introducing errors into your results. This is due to daylight saving time transitions. One way to avoid this is to use a DateTimeOffset type instead:
var utcDateTimeOffset = new DateTimeOffset(utcDateTime, TimeSpan.Zero);
var eastern = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(utcDateTimeOffset, zoneId);
Now when you work with these values, any ambiguities are captured by the offset.
If this seems very confusing to you, don't worry - you're not alone. You might want to try using Noda Time instead. It will prevent you from shooting yourself in the foot.

To see what's wrong, print a DateTime using your fromString:
DateTime dt = new DateTime(2013, 3, 22);
string s = dt.ToString(fromFormat);
you'll see that the output is:
Fri, 22 03 2013 00:00:00 -04:00
so that is the format it would be expecting.
You might be able to get some help on the abbreviations from this article.

There are two issues:
1) The day selected was a Friday not a Monday
2) The 'zzz' wants a plus or minus 0:00
So, to get it to work would be:
string fromFormat = "ddd, dd MM yyyy HH:mm:ss zzz";
string toFormat = "yyyy-MM-dd";
DateTime newDate = DateTime.ParseExact("Fri, 22 03 2013 00:00:00 +0:00", fromFormat, null);
Console.WriteLine(newDate.ToString(toFormat));

There's no simple, built-in way to convert from a Time Zone abbreviation to an offset or proper name. This is discussed in this topic here:
Timezone Abbreviations
You'll either need to create a table of the abbreviations you want to use, mapped to an offset or proper name, or you'll need to change the format of your incoming date/time string to use offsets.

string fromFormat = "ddd, dd MM yyyy HH:mm:ss zzz";
string toFormat = "yyyy-MM-dd";
DateTime newDate = DateTime.ParseExact("Mon, 22 03 2013 00:00:00 +00:00", fromFormat, null);
Console.WriteLine(newDate.ToString(toFormat));

22 03 2013 00:00:00 GMT is not Monday it's Friday
try
string fromFormat = "ddd, dd MM yyyy HH:mm:ss zzz";
string toFormat = "yyyy-MM-dd";
Console.WriteLine(DateTime.ParseExact("Fri, 22 03 2013 00:00:00 +00:00", fromFormat,
CultureInfo.InvariantCulture).ToString(toFormat));

Related

How to convert datetime format in c#?

I want to convert the DateTime format using c#. This is my code
string date = "Thu May 20 2021 00:00:00 GMT-0700 (Pacific Daylight Time)";
var s = DateTime.ParseExact(date, "dd-MM-yyyy HH:mm:ss", null);
But this code not working the exception is 'System.FormatException: 'String was not recognized as a valid DateTime.'
The format you provide must match with the format used in the string. Hence the name ParseExact. After playing around a bit I was able to match these:
string date = "Thu May 20 2021 00:00:00 GMT-0700"
var s = DateTime.ParseExact(date, "ddd MMM dd yyyy HH:mm:ss \"GMT\"zzz", null);
You may need to manually truncate the (Pacific Daylight Time) or include it in the format as a literal (like I did with GMT here).
For more information you can work with DateTime format specifiers
Your format string means that the date value must be something like that:
string date = "20-05-2021 12:00:00";
var s = DateTime.ParseExact(date, "dd-MM-yyyy HH:mm:ss", null);
Try to use an other date value or change the date format string.
You can find a lot of good examples here:
https://learn.microsoft.com/en-us/dotnet/api/system.datetime.parseexact?view=net-5.0#System_DateTime_ParseExact_System_String_System_String_System_IFormatProvider_

How to parse custom string to DateTime C#?

I need to parse to following Date Aug 20 11:38:43 2017 GMT
I'm trying to use DateTime.TryParseExact but can't find the correct format.
my latest format is MMM dd hh:mm:ss yyyy
my code :
string nextUpdate; //Next Update: Aug 20 11:38:43 2017 GMT
string dateTimeFormat = "MMM dd hh:mm:ss yyyy";
DateTime crldt;
DateTime.TryParseExact(nextUpdate.Split(':')[1].Trim(), dateTimeFormat, System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.None, out crldt);
when I run the code I get crldt ~ Date = {1/1/01 12:00:00 AM}
my question : what format should I use or what alternative way can I use to parse this string to DateTime
UPDATE
using suggestions from : #Sergey Berezovskiy
I've updated the code to :
string nextUpdate; // Next Update: Oct 7 06:16:18 2017 GMT
string dateTimeFormat = #"MMM dd HH:mm:ss yyyy \G\M\T";
Regex r =new Regex(".*Next Update:.*");
nextUpdate = r.Match(Crltext).Value;
DateTime crldt;
DateTime.TryParseExact(nextUpdate.Substring(nextUpdate.IndexOf(':')+1).Trim(),
dateTimeFormat, System.Globalization.CultureInfo.InvariantCulture,
System.Globalization.DateTimeStyles.AssumeUniversal, out crldt);
int intDTComp = DateTime.Compare(crldt, DT_now);
I've found a date that doesn't fit this format : Next Update: Oct 7 06:16:18 2017 GMT
what is the issue now ?
UPDATE 2
I've found the issue , but can't find a clean solution.
The issue is that the problematic date is Oct 7 ... ,
while the format is MMM dd ...
my workaround is adding another format MMM d hh:mm:ss yyyy and using it if date = {1/1/01 12:00:00 AM}
what other solution may I use in this scenario
First of all, don't forget that your string contains "GMT". You should either remove it from the string, or add to format pattern:
string nextUpdate = "Next Update: Aug 20 11:38:43 2017 GMT";
string format = #"MMM dd hh:mm:ss yyyy \G\M\T";
Next - don't split input string by : because there is another : symbols in the string. And you will get array with parts ["Next Update", " Aug 20 11", "38", "43 2017 GMT"]. Taking the second item from array gives you " Aug 20 11". Instead, you should just take substring after first : occurance:
string s = nextUpdate.Substring(nextUpdate.IndexOf(':') + 1).Trim();
And finally parse that string using your format:
IFormatProvider provider = CultureInfo.InvariantCulture;
DateTime date = DateTime.ParseExact(s, format, provider, DateTimeStyles.AssumeUniversal);
Output will depend on your time zone. E.g. for my time zone GMT+3 it will be:
8/20/2017 14:38:43
If this is your string:
"Next Update: Aug 20 11:38:43 2017 GMT"
Then when you do this:
nextUpdate.Split(':')[1].Trim()
You get this:
"Aug 20 11"
Which doesn't match your date format. I suspect you don't just want the second split value, but also all remaining split values. You can re-join them. Something like this:
string.Join(":", nextUpdate.Split(':').Skip(1)).Trim()
This would split them by the ":" character, skip the first one but keep all remaining ones, and re-join the remaining ones into another string with the ":" character again.
Note: You may also need to account for that time zone value. There are some helpful ideas on this question for how to do that.
If that's the input, I propose that you take the format exactly as the input
string nextUpdate = "Next Update: Aug 20 11:38:43 2017 GMT";
string dateTimeFormat = #"\N\e\x\t\ \U\p\d\a\t\e\:\ MMM dd hh:mm:ss yyyy\ \G\M\T";
DateTime crldt;
crldt = DateTime.ParseExact(nextUpdate, dateTimeFormat , System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.None);
This way, when reading the code it's very clear what the expected format is, and you don't have code with Split() or other items that need explanation.
Also note that if you leave the colons (:) like that, they may be replaced by .NET to match the hour separator. Use \: if you always require a literal colon.
As I wrote in the comments before, note that you're ignoring the time zone.
Use following code
CultureInfo provider = CultureInfo.InvariantCulture;
DateTime givenDate = DateTime.ParseExact("Aug 20 14:38:43 2017 GMT", "MMM dd HH:mm:ss yyyy GMT", provider); // here HH is for 24 hour format . use hh for 12 hour format
string expectedDate = givenDate.ToString("dd/MM/yy hh:mm:ss tt"); // tt is for AM or PM (no need to use tt if you use hour as HH I mean 24 hour format)
Your Output will be 20/08/17 11:38:43 AM

Parse date and Convert W. Europe Standard Time to UTC

TL:DR: I have the following input string:
Thu Mar 09 2017 18:00:00 GMT+0100
And I am trying to convert it to a DateTime object using the format:
"ddd MMM dd yyyy HH:mm:ss"
This obviously doesn't work as I am ignoring the GMT+0100 part. How can I include this?
I don't manage to parse and convert following input to a correct UTC DateTime object:
input string selectedDate:
1,Thu Mar 09 2017 18:00:00 GMT+0100 (W. Europe Standard Time)
function:
var splittedValues = selectedDate.Split(',');
var selectDayOfWeek = (DayOfWeek)int.Parse(splittedValues[0]);
var selectedTime = DateTime.ParseExact(splittedValues[1].Substring(0, 24),
"ddd MMM d yyyy HH:mm:ss",
CultureInfo.InvariantCulture);
DateTime today = new DateTime(DateTime.Today.Ticks, DateTimeKind.Unspecified);
// The (... + 7) % 7 ensures we end up with a value in the range [0, 6]
int daysUntilNextTargetDay = ((int)selectDayOfWeek - (int)today.DayOfWeek + 7) % 7;
DateTime nextTargetDay = today.AddDays(daysUntilNextTargetDay).AddHours(selectedTime.Hour).AddMinutes(selectedTime.Minute);
return nextTargetDay.ToUniversalTime();
results time portion is always 18:00:00
should be 17:00 as the input was actually GMT +01
Whats the issue here?
update:
as others pointed out there were mistakes so I updated my code to:
var splittedValues = selectedDate.Split(',');
var selectDayOfWeek = (DayOfWeek)int.Parse(splittedValues[0]);
var selectedTime = DateTime.ParseExact(splittedValues[1].Substring(0, 33),
"ddd MMM dd yyyy HH:mm:ss",
CultureInfo.InvariantCulture).ToUniversalTime();
// The (... + 7) % 7 ensures we end up with a value in the range [0, 6]
int daysUntilNextTargetDay = ((int)selectDayOfWeek - (int)DateTime.Today.DayOfWeek + 7) % 7;
DateTime nextTargetDay = DateTime.Today.AddDays(daysUntilNextTargetDay).AddHours(selectedTime.Hour).AddMinutes(selectedTime.Minute);
return nextTargetDay;
but now the parsing fails as the substring does not match "ddd MMM dd yyyy HH:mm:ss"
how does the GMT+0100 has to be included here?
Use TimeZoneInfo when converting between specific time zones:
TimeZoneInfo westInfo =
TimeZoneInfo.FindSystemTimeZoneById("W. Europe Standard Time");
DateTime westTime = DateTime.Parse("2012.12.04T08:35:00");
DateTime utcTime = TimeZoneInfo.ConvertTimeToUtc(westTime, westInfo);
To address your confusion:
DateTime.Parse as used here makes no assumptions about the timezone of the given value. IT stores it with a DateTimeKind of Unspecified.
TimeZoneInfo.ConvertTimeToUtc as used here expects an Unspecified datetime, reads it as if it is in the explicitly specified time zone, and converts it to UTC.
Changing your code to this (adding ToUniversalTime() before adding days) fixed it for me.
DateTime nextTargetDay = today.ToUniversalTime().AddDays(daysUntilNextTargetDay).AddHours(selectedTime.Hour).AddMinutes(selectedTime.Minute);
Then of course you can just return nextTargetDay; at the end.
Looking into MSDN I can spot an initial problem with your code. This is that you are using d where you should be using dd as the day is 09 not 9.
d: The day of the month, from 1 through 31.
dd: The day of the month, from 01 through 31.
Secondly, the reason the +1 is "ignored" is that you exclude it in the substring, i.e.
splittedValues[1].Substring(0, 24) == "Thu Mar 09 2017 18:00:00";
So essentially you need to include that part of the string with the correct format specifier (I'm not sure which one). Or interrogate it yourself and subtract one hour off of the result as needed.
Side note: The following code is weird (in my opinion, there may be a reason for it):
DateTime today = new DateTime(DateTime.Today.Ticks, DateTimeKind.Unspecified);
You can either use DateTime.Today or DateTime.Now.Date.
As mentioned in the answer by #calypso you can use the TimeZoneInfo class. Their answer goes over a general approach of how to use it. But for your particular example you can do (code is untested but looks like it should work):
var selectedTime = DateTime.ParseExact(splittedValues[1].Substring(0, 24), "ddd MMM dd yyyy HH:mm:ss", CultureInfo.InvariantCulture);
TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById(splittedValues[1].Substring(splittedValues[1].IndexOf("(") + 1).TrimEnd(")"));
DateTime utcTime = TimeZoneInfo.ConvertTimeToUtc(selectedTime, timeZoneInfo);

C# Parsing a long date

I have the following text that I am trying to parse into a date, but I can't seem to get the time zone correct.
Ideas?
Fri May 29 2015 00:00:00 GMT-0700 (Pacific Daylight Time)
(I can't change the date structure)
Try this:
string str = "Fri May 29 2015 00:00:00 GMT-0700 (Pacific Daylight Time)";
DateTime dt = new DateTime();
bool b = DateTime.TryParseExact(str.Substring(0,33), "ddd MMMM dd yyyy hh:mm:ss 'GMT'zzz", null, DateTimeStyles.None, out dt);
This makes the assumption that the description of the time zone is irrelevant since the offset from GMT is given. Therefore, parsing the substring of the original date string only upto the timezone offset part should be sufficient.
Demo
there is a shortcut way that I sometimes use.
first split the string based on space like:
var dateString = 'Fri May 29 2015 00:00:00 GMT-0700 (Pacific Daylight Time)';
var dateArray = stdateString.Split(' ');
second we need time. for that
var timeString = dateArray[4];
var timeArray = timeString.Split(':');
third for timezone
var timezoneString = dateArray[5];
var timezoneSignPart = timezoneString.Substring(3,1)
var timezoneHourPart = timezoneString.Substring(4,2)
var timezoneMinPart = timezoneString.Substring(6,2)
After that you may use to construct the date however you want to like
This is very personal way for me when I don't have much time to investigate what is the problem ob the coming date strings.

Convert weird date format to short DateTime

I have a date string, returned from a ExtJS datetime picker, which looks like this:
Wed Apr 25 2012 00:00:00 GMT+0300 (GTB Daylight Time)
From this I would need to have it in this format : YYYY-mm-dd, using C# or JavaScript.
How could I do this? I've tried using DateTime.Parse and it cannot be parsed.
Any idea?
You don't seem to care about the time and timezone information so you can in fact use DateTime.ParseExact to parse the date. Assuming that the day of month part may be just a single digit (e.g. 2012-04-01 is Sun Apr 1 2012) the pattern you need to use is ddd MMM d yyyy.
The "hardest" part is really chopping of the time and timezone part. If the day of month is a single digit you have to take of substring of length 14; otherwise of length 15. Here is a way to get the index of the 4th space character in a string:
var str = "Wed Apr 25 2012 00:00:00 GMT+0300 (GTB Daylight Time)";
var index = -1;
for (var i = 0; i < 4; i += 1)
index = str.IndexOf(' ', index + 1);
You can then parse the date into a DateTime:
var date = DateTime
.ParseExact(str.Substring(0, index), "ddd MMM d yyyy", CultureInfo.InvariantCulture);
This can be formatted back into a string using whatever format and culture you need.
In .NET, where you have a string representation of a date that has a guaranteed format, you can use DateTime.ParseExact to parse it:
var input = "Wed Apr 25 2012 00:00:00 GMT+0300 (GTB Daylight Time)"
.Substring(0, 15);
var format = "ddd MMM dd YYYY";
var date = DateTime.ParseExact(input, format, CultureInfo.InvariantCulture);
// Now date is a DateTime holding the date
var output = date.ToString("yyyy-MM-dd");
// Now output is 2012-04-25
May be this can help you Click
try this using Javascript.
var d = new Date('Wed Apr 25 2012 00:00:00 GMT+0300 (GTB Daylight Time)');
var curr_day = d.getDate();
var curr_month = ('0'+(d.getMonth()+1)).slice(-2)
var curr_year = d.getFullYear();
var new_date = curr_year+"-"+curr_month+"-"+curr_day;
In JavaScript
new Date("Wed Apr 25 2012 00:00:00 GMT+0300 (GTB Daylight Time)")
Will give you a date object. You can then format it to your date format (or preferably ISO8601, or milliseconds from the epoc using .getTime()) by picking out the (UTC) year, month and day

Categories