Using G / g Standard Patterns for or LocalDateTime values - c#

I'm trying to parse LocalDateTime values using Noda Time LocalDateTimePattern.Parse() method. I'm in the US. The following call to Parse() fails:
var localDateTimePattern = LocalDateTimePattern.Create("G", CultureInfo.InvariantCulture);
var parseResult = localDateTimePattern.Parse("4/10/2014 3:03:11 PM");
This fails as well
var localDateTimePattern = LocalDateTimePattern.Create("g", CultureInfo.InvariantCulture);
var parseResult = localDateTimePattern.Parse("4/10/2014 3:03:11 PM");
What am I doing wrong? My idea was to be able to parse DateTime string presented in a standard to a current culture format.
Using BCL like the following works:
DateTime dateTime;
var parseResult = DateTime.Parse("4/10/2014 3:03:11 PM");
(Related formatting question was asked here: http://goo.gl/Q8DYTB)

A few things:
Passing null to a IFormatProvider, or a CultureInfo parameter, will use the current culture, not the invariant culture. It's equivalent to passing CultureInfo.CurrentCulture.
For methods like DateTime.Parse or ToString that have overloads that omit the format provider, null is assumed - which again, maps to the current culture, not the invariant culture.
In the invariant culture, the "G" format is MM/dd/yyyy HH:mm:ss. You must pass two digits (using a leading zero if necessary) in all fields (except year, which is 4 of course), and you must pass time in 24 hour format. AM/PM indicators are not allowed.
If you wish to use "G" with the current culture, then pass CultureInfo.CurrentCulture, or if you know the culture you want, then pass that specific culture.
The "g" format is the same as "G", except it doesn't include seconds.
Noda Time is identical to the normal types in all of the above, except that it doesn't allow for null to be passed. I believe this is intentional, to avoid this sort of confusion.
So, your methods are failing because you are passing only one-digit for a month, and passing 12-hour time format, but the invariant culture doesn't allow that. Try instead:
var pattern = LocalDateTimePattern.Create("G", CultureInfo.InvariantCulture);
var parseResult = pattern.Parse("04/10/2014 15:03:11");
Or perhaps:
var pattern = LocalDateTimePattern.Create("G", CultureInfo.CurrentCulture);
var parseResult = pattern.Parse("4/10/2014 3:03:11 PM");
Or if your current culture is not in that format, then use a specific culture:
var culture = CultureInfo.CreateSpecificCulture("en-US");
var pattern = LocalDateTimePattern.Create("G", culture);
var parseResult = pattern.Parse("4/10/2014 3:03:11 PM");

Related

DateTime formating

I'm using CultureInfo() to get format of DateTime
CultureInfo culture = new CultureInfo(CultureInfo.CurrentCulture.Name);
someDateTime.ToString("d", culture));
How to get custom formats and not to lose separator which comes with CultureInfo()?
According to the documentation for DateTimeFormatInfo.DateSeparator:
If a custom format string includes the "/" format specifier, the DateTime.ToString method displays the value of DateSeparator in place of the "/" in the result string.
So just use a custom date/time format string with slashes, and they will be replaced automatically.
Example:
var someDateTime = new DateTime(1900, 12, 21);
Console.WriteLine(someDateTime.ToString("d/M", new CultureInfo("en-US")));
Console.WriteLine(someDateTime.ToString("d/M", new CultureInfo("nl")));
Console.WriteLine(someDateTime.ToString("yyy/M", new CultureInfo("en-US")));
Console.WriteLine(someDateTime.ToString("yyy/M", new CultureInfo("nl")));
Output:
21/12
21-12
1900/12
1900-12
Just be aware that this probably isn't a great idea. The separator is not the only meaningful difference between cultures' date representations. 5/6 means May 6 to Americans, but it means June 5 to most Europeans (even those which use the same date separator).
You can provide a format when you call ToString on DateTime objects.
e.g.:
someDateTime.ToString("MM-yyyy"); // produces a formatted date like 12-1900
Formatting Info: https://www.c-sharpcorner.com/blogs/date-and-time-format-in-c-sharp-programming1
You can also specify the separator property of the DateTimeFormatInfo object, like so:
DateTime someDateTime = DateTime.Now;
CultureInfo culture = new CultureInfo("en-US");
DateTimeFormatInfo dtfi = culture.DateTimeFormat;
dtfi.DateSeparator = "-";
someDateTime.ToString("d", culture);

How to Convert date into String format to Date format in C#?

I am trying to convert this ("2019-09-09"(yyyy-MM-dd)) string into date format. I am using DateTime.ParseExact method, but it is not giving me the expected output.
string transactionDateFrom = "2019-09-09";
var provider = CultureInfo.InvariantCulture;
var c = DateTime.ParseExact(transactionDateFrom, "yyyy-MM-dd", provider);
But it shows output as (09/09/2019 12:12Am) I just need format like (yyyy-MM-dd) and it must be date format not string.
You should also provide format for ToString or whenever you use that, since right now you only use it for parsing.
You may also just edit the culture the following way:
CultureInfo culture = (CultureInfo) CultureInfo.CurrentCulture.Clone();
culture.DateTimeFormat.ShortDatePattern = "yyyy-MM-dd";
culture.DateTimeFormat.LongTimePattern = "yyyy-MM-dd";
You should either use DateTime.TryParseExact or use DateTime.TryParse specifying the appropriate CultureInfo.
(For E.g., the culture of the user.)
You can use DateTime.ParseExact method overloads and you can specify exact format and proper (that uses / as a DateSeparator) culture information.
Also be aware that the Difference between M and MM specifiers.
For single digit month numbers, MM specifier will generate month number with leading zero (like 09) but M specifier won't.
string strDate = "2019-09-28";
DateTime date = DateTime.ParseExact(strDate, "yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture);
string Format = date.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture);
OR
string strDate = "2019-9-28";
DateTime date = DateTime.ParseExact(strDate, "yyyy-M-dd", System.Globalization.CultureInfo.InvariantCulture);
string Format = date.ToString("yyyy-M-dd", CultureInfo.InvariantCulture);

Parsing non standard date strings in C#

How would you handle the following string value that needs to be converted to a DateTime object?
"2015/01/22 12:08:51 (GMT+09:00)"
Would like to include this as a recognized DateTime pattern. As I encounter other formats, I would like to just implement a new pattern.
Here a piece of code that will successfully parse the given string (notice DateTimeOffset rather than DateTime):
var str = "2015/01/22 12:08:51 (GMT+09:00)";
var dt = DateTimeOffset.ParseExact
(str,
"yyyy/MM/dd HH:mm:ss (\\G\\M\\TK)",
System.Globalization.CultureInfo.InvariantCulture
);
//dt now has +9:00 offset - that's correct only if GMT is provided as UTC.
More info at The Difference Between GMT and UTC
This code takes a string and converts it into a DateTime object
DateTime myDate = DateTime.Parse("2017-08-28 14:20:52,001", "yyyy-MM-dd HH:mm:ss,fff", System.Globalization.CultureInfo.InvariantCulture);
All you need to do is create a format that matches your input. This link helps:
https://learn.microsoft.com/en-us/dotnet/standard/base-types/custom-date-and-time-format-strings
For more details read this: https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/strings/how-to-convert-a-string-to-a-datetime
Here there is the official documentation of DateTime.Parse with some examples. It covers also the case of other formats
https://msdn.microsoft.com/it-it/library/system.datetime.parse(v=vs.110).aspx
Using DateTime.ParseExact is probably your best bet. It takes in an input string and an expected format string that the input should match. It will return true if the conversion was successful, and the out parameter will be the result of the conversion (result in the example below).
I was unable to get it to work without forcibly removing the "GMT" portion, but if that's acceptable to you, the code below should work.
This example takes the original input and converts it to UTC time (i.e. it adjusts the time based on your GMT value, which is to subtract 9 hours in your example):
var input = "2015/01/22 12:08:51 (GMT-08:00)";
var format = "yyyy/MM/dd H:mm:ss (zzz)";
DateTime result;
// Remove the "GMT" portion of the input
input = input.Replace("GMT", "");
if (DateTime.TryParseExact(input, format, CultureInfo.InvariantCulture,
DateTimeStyles.AdjustToUniversal, out result))
{
Console.WriteLine($"'{input}' converts to {result} UTC time.");
}
else
{
Console.WriteLine($"'{input}' is not in the correct format.");
}
This example is modified from the ones on the DateTime.TryParseExact documentation.

Convert(change) current DateTime as per culture in c#

if (!IsPostBack && !Page.IsCallback)
{
double OffsetHrs = GetTimeZoneOffsetFromCookie();
string dateFormat = ServiceManager.LocalizationService.GetString("AppHeaderTop", "DateFormat", "g");
CultureSelected CultureSelected = GetCultureSelected();
ASPxLabelCurrentTime.Text = DateTime.Now.ToUniversalTime().AddHours(-OffsetHrs).ToString(dateFormat);
if (CultureSelected.CultureCode != "en-US")
{
DateTimeFormatInfo usDtfi = new CultureInfo("en-US", false).DateTimeFormat;
DateTimeFormatInfo currentDtfi = new CultureInfo(CultureSelected.CultureCode, false).DateTimeFormat;
ASPxLabelCurrentTime.Text = Convert.ToDateTime(ASPxLabelCurrentTime.Text, usDtfi).ToString(currentDtfi.ShortDatePattern); //what can i Use here ?
}
Let say Output of ASPxLabelCurrentTime.Text
for en-US culture is 11/2/2015 4:14 PM (70)
If I select specific culture I want this datetime 11/2/2015 4:14 PM (70) to appear in that specific culture format.
Your question seems unclear but I try to give a shot.
First of all, what is this (70) exactly? Where is this came from? en-US culture can't parse this string without using it in a string literal delimiter with ParseExact or TryParseExact methods. On the other hand, since you assing ASPxLabelCurrentTime.Text the result of the DateTime.Now.ToUniversalTime().AddHours(-OffsetHrs).ToString(dateFormat) code, I don't believe this (70) part is really an issue on this question.
Second, If I understand clearly, the problem seems the usage of DateTime.ToString(string) method.
ASPxLabelCurrentTime.Text = Convert.ToDateTime(ASPxLabelCurrentTime.Text, usDtfi)
.ToString(currentDtfi.ShortDatePattern);
// ^^^ Problem seems here
Okey let's say you successfully parse this ASPxLabelCurrentTime.Text with usDtfi culture (which is en-US), but with this .ToString(string) method, you are not using currentDtfi settings actually, you are using CurrentCulture settings when you generate formatted string representation of your DateTime.
From DateTime.ToString(String) doc;
Converts the value of the current DateTime object to its equivalent
string representation using the specified format and the formatting
conventions of the current culture.
Since we don't know what GetCultureSelected method returns exactly, it may or may not be the same culture with currentDtfi.
I strongly suspect, you can solve this problem to using that culture as a second parameter in ToString method as;
ASPxLabelCurrentTime.Text = Convert.ToDateTime(ASPxLabelCurrentTime.Text, usDtfi)
.ToString(currentDtfi.ShortDatePattern, currentDtfi);
IF this (70) is really part of on your string, you need to ParseExact or TryParseExact methods to supply exact format of it.
string s = "11/2/2015 4:14 PM (70)";
DateTime dt;
if(DateTime.TryParseExact(s, "MM/d/yyyy h:mm tt '(70)'", CultureInfo.GetCultureInfo("en-US"),
DateTimeStyles.None, out dt))
{
ASPxLabelCurrentTime.Text = dt.ToString(currentDtfi.ShortDatePattern, currentDtfi);
}

DateTime.TryParseExact only working in "One Way"

Scope:
I have been trying to develop a super-tolerant DateTime.Parse routine, so I decided to give most "widely-used" formats a try to better understand the format masks.
Problem:
I have defined a specific format (String) which I use as myDate.ToString(format), and it works wonders. The problem is, If I get this same String (result of the .ToString(format) operation), and feed it back to DateTime.TryParseExact (...) it fails.
Code / Test:
System.Globalization.CultureInfo provider = System.Globalization.CultureInfo.InvariantCulture;
// Defining Format and Testing it via "DateTime.ToString(format)"
string format = "MM/dd/yyyy HH:mm:ss tt";
string dtNow = DateTime.Now.ToString (format);
Console.WriteLine (dtNow);
// Trying to Parse DateTime on the same Format defined Above
DateTime time;
if (DateTime.TryParseExact (dtNow, format, provider, System.Globalization.DateTimeStyles.None, out time))
{
// If TryParseExact Worked
Console.WriteLine ("Result: " + time.ToString ());
}
else
{
// If TryParseExact Failed
Console.WriteLine ("Failed to Parse Date");
}
Output is : "Failed to Parse Date".
Question:
Why can I use the format string to format a certain date as text, but I can't use the same format to feed the string back to a date object ?
EDIT:
I have added part of my method to this example, and I would like to know why the "ParseDate" method fails to return a proper date, given that the "String" is in the right format.
Since you use DateTime.ToString() method without any IFormatProvider, this method will use your CurrentCulture settings.
That's why your
string dtNow = DateTime.Now.ToString (format);
line might generate a different string representation than MM/dd/yyyy HH:mm:ss tt format.
Three things can cause this issue;
Your CurrentCulture has a different DateSeparator than /
Your CurrentCulture has a different TimeSeparator than :
Your CurrentCulture has a different or empty string as a AMDesignator and/or PMDesignator
Since you try to parse your string with provider (which is InvariantCulture) on your DateTime.TryParseExact method, generate your string based on that provider as well.
string dtNow = DateTime.Now.ToString(format, provider);
You told your CurrentCulture is pt-BR and this culture has empty string "" as a AMDesignator and PMDesignator. That's why your dtNow string will not have any AM or PM designator on it's representation part.
Here a demonstration.

Categories

Resources