C# DateTime Formatting Names - c#

What is the name of this DateTime format:
Tue Apr 01 2014 00:00:00 GMT+0100 (GMT Daylight Time)
Is there anyway I could detect this format in code?
The reason I am asking is that I have a function with DateTime parameter, which comes in different formats, and I would like to detect the format type or name; so that I could convert them accorddingly to the simple format of dd/MM/yyyy hh:mm:ss.
The other second format I am getting is this: 2014-03-31T23:00:00.000Z.
Many thanks.
Edit
I wrote this function to convert from Tue Apr 01 2014 00:00:00 GMT+0100 (GMT Daylight Time) to dd/MM/yyyy hh:mm:ss. This function fails when the input is of type 2014-03-31T23:00:00.000Z.
I wonder how could possibly identify the type of parameter coming and convert accordingly?
public static DateTime ConvertDateObjectToDateTime(string dateToConvert)
{
var value = new DateTime();
if (!string.IsNullOrEmpty(dateToConvert))
{
int gmtIndex = dateToConvert.IndexOf("G", System.StringComparison.Ordinal);
string newDate = dateToConvert.Substring(0, gmtIndex).Trim();
value = DateTime.ParseExact(newDate, "ddd MMM dd yyyy HH:mm:ss", CultureInfo.InvariantCulture);
return value;
}
return value;
}

The second is definitely UTC, however, the first could be UTC + offset or it could be Local + offset (it looks like the latter the more I examine it). The best tool you have in your armoury for parsing specific dates is the ParseExact method.
Based on your edit, I am concerned about the fact you are ignoring the timezone information. You are assuming at this point that the date is already UTC (which it may not be) and just parsing/treating it as is...
However, to answer your particular question
I wonder how could possibly identify the type of parameter coming and convert accordingly?
You don't actually need to do that, ParseExact has an overload which allows you to specify multiple formats
value = DateTime.ParseExact(newDate,
new[] { "ddd MMM dd yyyy HH:mm:ss", "yyyy-MM-dd'T'HH:mm:ss.fff'Z'" },
CultureInfo.InvariantCulture,
DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal);

Related

Date format parser error [duplicate]

Why can't it parse this:
DateTime.Parse("Tue, 1 Jan 2008 00:00:00 UTC")
It can't parse that string because "UTC" is not a valid time zone designator.
UTC time is denoted by adding a 'Z' to the end of the time string, so your parsing code should look like this:
DateTime.Parse("Tue, 1 Jan 2008 00:00:00Z");
From the Wikipedia article on ISO 8601
If the time is in UTC, add a 'Z'
directly after the time without a
space. 'Z' is the zone designator for
the zero UTC offset. "09:30 UTC" is
therefore represented as "09:30Z" or
"0930Z". "14:45:15 UTC" would be
"14:45:15Z" or "144515Z".
UTC time is also known as 'Zulu' time,
since 'Zulu' is the NATO phonetic
alphabet word for 'Z'.
Assuming you use the format "o" for your datetime so you have "2016-07-24T18:47:36Z", there is a very simple way to handle this.
Call DateTime.Parse("2016-07-24T18:47:36Z").ToUniversalTime().
What happens when you call DateTime.Parse("2016-07-24T18:47:36Z") is you get a DateTime set to the local timezone. So it converts it to the local time.
The ToUniversalTime() changes it to a UTC DateTime and converts it back to UTC time.
Just use that:
var myDateUtc = DateTime.SpecifyKind(DateTime.Parse("Tue, 1 Jan 2008 00:00:00"), DateTimeKind.Utc);
if (myDateUtc.Kind == DateTimeKind.Utc)
{
Console.WriteLine("Yes. I am UTC!");
}
You can test this code using the online c# compiler:
http://rextester.com/
I hope it helps.
or use the AdjustToUniversal DateTimeStyle in a call to
DateTime.ParseExact(String, String[], IFormatProvider, DateTimeStyles)
You need to specify the format:
DateTime date = DateTime.ParseExact(
"Tue, 1 Jan 2008 00:00:00 UTC",
"ddd, d MMM yyyy HH:mm:ss UTC",
CultureInfo.InvariantCulture);
To correctly parse the string given in the question without changing it, use the following:
using System.Globalization;
string dateString = "Tue, 1 Jan 2008 00:00:00 UTC";
DateTime parsedDate = DateTime.ParseExact(dateString, "ddd, d MMM yyyy hh:mm:ss UTC", CultureInfo.CurrentCulture, DateTimeStyles.AssumeUniversal);
This implementation uses a string to specify the exact format of the date string that is being parsed. The DateTimeStyles parameter is used to specify that the given string is a coordinated universal time string.
It's not a valid format, however "Tue, 1 Jan 2008 00:00:00 GMT" is.
The documentation says like this:
A string that includes time zone information and conforms to ISO 8601. For example, the first of the following two strings designates the Coordinated Universal Time (UTC); the second designates the time in a time zone seven hours earlier than UTC:
2008-11-01T19:35:00.0000000Z
A string that includes the GMT designator and conforms to the RFC 1123 time format. For example:
Sat, 01 Nov 2008 19:35:00 GMT
A string that includes the date and time along with time zone offset information. For example:
03/01/2009 05:42:00 -5:00
I've put together a utility method which employs all tips shown here plus some more:
static private readonly string[] MostCommonDateStringFormatsFromWeb = {
"yyyy'-'MM'-'dd'T'hh:mm:ssZ", // momentjs aka universal sortable with 'T' 2008-04-10T06:30:00Z this is default format employed by moment().utc().format()
"yyyy'-'MM'-'dd'T'hh:mm:ss.fffZ", // syncfusion 2008-04-10T06:30:00.000Z retarded string format for dates that syncfusion libs churn out when invoked by ejgrid for odata filtering and so on
"O", // iso8601 2008-04-10T06:30:00.0000000
"s", // sortable 2008-04-10T06:30:00
"u" // universal sortable 2008-04-10 06:30:00Z
};
static public bool TryParseWebDateStringExactToUTC(
out DateTime date,
string input,
string[] formats = null,
DateTimeStyles? styles = null,
IFormatProvider formatProvider = null
)
{
formats = formats ?? MostCommonDateStringFormatsFromWeb;
return TryParseDateStringExactToUTC(out date, input, formats, styles, formatProvider);
}
static public bool TryParseDateStringExactToUTC(
out DateTime date,
string input,
string[] formats = null,
DateTimeStyles? styles = null,
IFormatProvider formatProvider = null
)
{
styles = styles ?? DateTimeStyles.AllowWhiteSpaces | DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal; //0 utc
formatProvider = formatProvider ?? CultureInfo.InvariantCulture;
var verdict = DateTime.TryParseExact(input, result: out date, style: styles.Value, formats: formats, provider: formatProvider);
if (verdict && date.Kind == DateTimeKind.Local) //1
{
date = date.ToUniversalTime();
}
return verdict;
//0 employing adjusttouniversal is vital in order for the resulting date to be in utc when the 'Z' flag is employed at the end of the input string
// like for instance in 2008-04-10T06:30.000Z
//1 local should never happen with the default settings but it can happen when settings get overriden we want to forcibly return utc though
}
Notice the use of '-' and 'T' (single-quoted). This is done as a matter of best practice since regional settings interfere with the interpretation of chars such as '-' causing it to be interpreted as '/' or '.' or whatever your regional settings denote as date-components-separator. I have also included a second utility method which show-cases how to parse most commonly seen date-string formats fed to rest-api backends from web clients. Enjoy.
Just replace "UTC" with "GMT" -- simple and doesn't break correctly formatted dates:
DateTime.Parse("Tue, 1 Jan 2008 00:00:00 UTC".Replace("UTC", "GMT"))
Not sure why, but you can wrap DateTime.ToUniversalTime in a try / catch and achieve the same result in more code.
Good luck.

Excel datetime with offset to C# DateTime

I have an excel sheet with a date I get out using some JavaScript or VBA (doesn't matter).
Then I end up having a date that looks like this: "Tue Feb 4 00:00:00 UTC+0100 2014"
Are there any build in versions to convert this to C# DateTime? As you can see then I don't use the time part, and thus also don't care about the UTC offset.
Are there any build in versions to convert this to C# DateTime?
Sure! You can use DateTime.TryParseExact or DateTime.ParseExact methods to parse your string.
string s = "Tue Feb 4 00:00:00 UTC+0100 2014";
DateTime dt;
if(DateTime.TryParseExact(s, "ddd MMM d HH:mm:ss 'UTC+0100' yyyy",
CultureInfo.InvariantCulture,
DateTimeStyles.None, out dt))
{
Console.WriteLine(dt);
}
But don't use this way when your string have offset values.
In Custom Date and Time Format Strings page; if your string has signed offset, using DateTimeOffset instead of DateTime is recommended.
With DateTime values, the "zzz" custom format specifier represents the
signed offset of the local operating system's time zone from UTC,
measured in hours and minutes. It does not reflect the value of an
instance's DateTime.Kind property. For this reason, the "zzz" format
specifier is not recommended for use with DateTime values.
With DateTimeOffset values, this format specifier represents the
DateTimeOffset value's offset from UTC in hours and minutes.
string s = "Tue Feb 4 00:00:00 UTC+0100 2014";
DateTimeOffset dto;
if(DateTimeOffset.TryParseExact(s, "ddd MMM d HH:mm:ss 'UTC'zzz yyyy",
CultureInfo.InvariantCulture,
DateTimeStyles.None, out dto))
{
Console.WriteLine(dto);
}
Then you can convert this DateTimeOffset to DateTime. Because a DateTime doesn't store any offset value. There is no such a thing like; "a DateTime with an offset as 1 hour"

Having problems with a datetime string

I have this method which shall return the day of the week (Wed):
protected string GetDayOfWeek(string dateTimeString)
{
DateTime result = DateTime.Parse(dateTimeString);
string dayOfWeek = Enum.GetName(typeof(DayOfWeek), result.DayOfWeek);
return dayOfWeek;
}
I have a breakpoint on the line DateTime result to check the incoming string which gives:
"Wed, 12 Mar 2014 00:00:00 GMT"
The above method is giving me error:
"FormatException not handled by the user code" String not recognised
as a valid dateTime.
What am I doing wrong? I cannot pick it up.
DateTime.Parse(string) uses the conventions of the current culture. So my guess is that "Wed, 12 Mar 2014 00:00:00 GMT" is not a valid date in your current culture.
You could try:
DateTime.Parse(dateTimeString, System.Globalization.CultureInfo.InvariantCulture.DateTimeFormat)
That should tell the parser to be culture independent.
You can use:
DateTime.Now.DayOfWeek;
And compare with DayOfWeekclass.
Try using the method DateTime.ParseExact and provide an exact format string for your input. In your case the call shall look like:
DateTime myDate = DateTime.ParseExact("Wed, 12 Mar 2014 00:00:00 GMT", "ddd, dd MMM yyyy HH:mm:ss 'GMT'K", System.Globalization.CultureInfo.InvariantCulture);
There's two things going on here:
Parse a string into a DateTime
Get the DayOfWeek from the provided DateTime
As Tor-Erik suggests you can use DateTime.Parse with the invariant culture to get a DateTime.
DateTime.Parse(
dateTimeString,
System.Globalization.CultureInfo.InvariantCulture.DateTimeFormat)
Then as Hevilávio Soares suggests you should use the built in functions of the DateTime object to obtain the Day of the week.
DateTime.Now.DayOfWeek;
It's better to separate the concerns and to reuse existing functionality than to write your own.

JSON date from tweeter to C# format

How to format a JSON date obtained from twitter to a C# DateTime ?
Here is the format of the date I receive :
"Tue, 19 Feb 2013 13:06:17 +0000"
Can I do it with JSON.NET ?
Solved with use of DateTime.ParseExact
-> http://blog.kevinyu.org/2012/07/handling-json-in-net.html
Link Update: the linked blog post is offline. It cached copy can still be referenced via the Way Back Machine Internet Archive.
The common .NET code copied from the blog post is:
public const string Const_TwitterDateTemplate = "ddd MMM dd HH:mm:ss +ffff yyyy";
DateTime createdAt = DateTime.ParseExact((string)jo["created_at"],
Const_TwitterDateTemplate, new System.Globalization.CultureInfo("en-US"));
where
variable jo is a JSON object representing the created_at date property, but effectively the Twitter date string goes into this parameter
Part of code from flow's answer.
public const string Const_TwitterDateTemplate = "ddd MMM dd HH:mm:ss +ffff yyyy";
DateTime createdAt = DateTime.ParseExact((string)jo["created_at"], Const_TwitterDateTemplate, new System.Globalization.CultureInfo("en-US"));
The answers above that use the ffff format specifier seem to return the correct result, but technically this is wrong. ffff is the format specifier for ten thousandths of a second, and the +0000 in a Twitter date indicates the hours and minutes offset from UTC. See the format below:
string twitterTime = "Wed Feb 22 15:49:01 +0000 2017";
string twitterTimeformat = "ddd MMM dd HH:mm:ss zzz yyyy";
DateTime dateTime = DateTime.ParseExact(twitterTime, twitterTimeformat,
CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal);
Console.WriteLine(dateTime);
Result: 2/22/2017 3:49:01 PM
You can edit the DateTimeStyles enumeration to return the local time instead of UTC if desired.
Custom Date and Time Format Strings
DateTimeStyles Enumeration
It's DateTimeOffset not DateTime. Following should work.
DateTimeOffset parsed = DateTimeOffset.Parse("Tue, 19 Feb 2013 13:06:17 +0000");
I needed a PowerShell variant of these answers and the following worked for me.
PS> $Created_At = 'Fri Jun 05 18:15:48 +0000 2020'
PS> [datetime]::ParseExact($Created_At,'ddd MMM dd HH:mm:ss zzz yyyy',(Get-Culture))
Friday, June 5, 2020 1:15:48 PM

Why can't DateTime.Parse parse UTC date

Why can't it parse this:
DateTime.Parse("Tue, 1 Jan 2008 00:00:00 UTC")
It can't parse that string because "UTC" is not a valid time zone designator.
UTC time is denoted by adding a 'Z' to the end of the time string, so your parsing code should look like this:
DateTime.Parse("Tue, 1 Jan 2008 00:00:00Z");
From the Wikipedia article on ISO 8601
If the time is in UTC, add a 'Z'
directly after the time without a
space. 'Z' is the zone designator for
the zero UTC offset. "09:30 UTC" is
therefore represented as "09:30Z" or
"0930Z". "14:45:15 UTC" would be
"14:45:15Z" or "144515Z".
UTC time is also known as 'Zulu' time,
since 'Zulu' is the NATO phonetic
alphabet word for 'Z'.
Assuming you use the format "o" for your datetime so you have "2016-07-24T18:47:36Z", there is a very simple way to handle this.
Call DateTime.Parse("2016-07-24T18:47:36Z").ToUniversalTime().
What happens when you call DateTime.Parse("2016-07-24T18:47:36Z") is you get a DateTime set to the local timezone. So it converts it to the local time.
The ToUniversalTime() changes it to a UTC DateTime and converts it back to UTC time.
Just use that:
var myDateUtc = DateTime.SpecifyKind(DateTime.Parse("Tue, 1 Jan 2008 00:00:00"), DateTimeKind.Utc);
if (myDateUtc.Kind == DateTimeKind.Utc)
{
Console.WriteLine("Yes. I am UTC!");
}
You can test this code using the online c# compiler:
http://rextester.com/
I hope it helps.
or use the AdjustToUniversal DateTimeStyle in a call to
DateTime.ParseExact(String, String[], IFormatProvider, DateTimeStyles)
You need to specify the format:
DateTime date = DateTime.ParseExact(
"Tue, 1 Jan 2008 00:00:00 UTC",
"ddd, d MMM yyyy HH:mm:ss UTC",
CultureInfo.InvariantCulture);
To correctly parse the string given in the question without changing it, use the following:
using System.Globalization;
string dateString = "Tue, 1 Jan 2008 00:00:00 UTC";
DateTime parsedDate = DateTime.ParseExact(dateString, "ddd, d MMM yyyy hh:mm:ss UTC", CultureInfo.CurrentCulture, DateTimeStyles.AssumeUniversal);
This implementation uses a string to specify the exact format of the date string that is being parsed. The DateTimeStyles parameter is used to specify that the given string is a coordinated universal time string.
It's not a valid format, however "Tue, 1 Jan 2008 00:00:00 GMT" is.
The documentation says like this:
A string that includes time zone information and conforms to ISO 8601. For example, the first of the following two strings designates the Coordinated Universal Time (UTC); the second designates the time in a time zone seven hours earlier than UTC:
2008-11-01T19:35:00.0000000Z
A string that includes the GMT designator and conforms to the RFC 1123 time format. For example:
Sat, 01 Nov 2008 19:35:00 GMT
A string that includes the date and time along with time zone offset information. For example:
03/01/2009 05:42:00 -5:00
I've put together a utility method which employs all tips shown here plus some more:
static private readonly string[] MostCommonDateStringFormatsFromWeb = {
"yyyy'-'MM'-'dd'T'hh:mm:ssZ", // momentjs aka universal sortable with 'T' 2008-04-10T06:30:00Z this is default format employed by moment().utc().format()
"yyyy'-'MM'-'dd'T'hh:mm:ss.fffZ", // syncfusion 2008-04-10T06:30:00.000Z retarded string format for dates that syncfusion libs churn out when invoked by ejgrid for odata filtering and so on
"O", // iso8601 2008-04-10T06:30:00.0000000
"s", // sortable 2008-04-10T06:30:00
"u" // universal sortable 2008-04-10 06:30:00Z
};
static public bool TryParseWebDateStringExactToUTC(
out DateTime date,
string input,
string[] formats = null,
DateTimeStyles? styles = null,
IFormatProvider formatProvider = null
)
{
formats = formats ?? MostCommonDateStringFormatsFromWeb;
return TryParseDateStringExactToUTC(out date, input, formats, styles, formatProvider);
}
static public bool TryParseDateStringExactToUTC(
out DateTime date,
string input,
string[] formats = null,
DateTimeStyles? styles = null,
IFormatProvider formatProvider = null
)
{
styles = styles ?? DateTimeStyles.AllowWhiteSpaces | DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal; //0 utc
formatProvider = formatProvider ?? CultureInfo.InvariantCulture;
var verdict = DateTime.TryParseExact(input, result: out date, style: styles.Value, formats: formats, provider: formatProvider);
if (verdict && date.Kind == DateTimeKind.Local) //1
{
date = date.ToUniversalTime();
}
return verdict;
//0 employing adjusttouniversal is vital in order for the resulting date to be in utc when the 'Z' flag is employed at the end of the input string
// like for instance in 2008-04-10T06:30.000Z
//1 local should never happen with the default settings but it can happen when settings get overriden we want to forcibly return utc though
}
Notice the use of '-' and 'T' (single-quoted). This is done as a matter of best practice since regional settings interfere with the interpretation of chars such as '-' causing it to be interpreted as '/' or '.' or whatever your regional settings denote as date-components-separator. I have also included a second utility method which show-cases how to parse most commonly seen date-string formats fed to rest-api backends from web clients. Enjoy.
Just replace "UTC" with "GMT" -- simple and doesn't break correctly formatted dates:
DateTime.Parse("Tue, 1 Jan 2008 00:00:00 UTC".Replace("UTC", "GMT"))
Not sure why, but you can wrap DateTime.ToUniversalTime in a try / catch and achieve the same result in more code.
Good luck.

Categories

Resources