What is an elegant way to pull out common formats (e.g. datetime) for string.format into accessible constants?
Ideally I would like to do something like the following, but I get the below error when I try to use this code.
var now = DateTime.Now;
var format = "yyyy-MM-dd";
Console.WriteLine(string.Format("The date is {1:{0}}", format, now));
[System.FormatException: Input string was not in a correct format.]
at Program.Main(): line 9
The reasoning behind this is that certain API's require a specific datetime format. I would like to be able to reference a single place to get that format, such that all or none of the calls will work.
I realize that the following will work, but it doesn't seem very elegant.
Console.WriteLine(string.Format("The date is {1:" + format + "}", format, now));
You could go an app constant route - a static class that holds your format strings.
namespace App.Framework {
public static class AppConstant {
public static readonly string DisplayDateShort = "MM/dd/yyyy";
}
}
As far as your example goes, it's kind of flawed; you want to call ToString() on your DateTime value.
Console.WriteLine(now.ToString(AppConstant.DisplayDateShort));
You can find all the used format strings under DateTimeFormatInfo.CurrentInfo.GetAllDateTimePatterns().
Afterwards you can individually try to parse your input data with each value and see which on returns true (see: DateTime.TryParseExact()).
Console.WriteLine (DateTimeFormatInfo.CurrentInfo.GetAllDateTimePatterns());
Sample code:
void Main()
{
var now = DateTime.Now.ToString();
foreach(var format in DateTimeFormatInfo.CurrentInfo.GetAllDateTimePatterns()){
DateTime result;
if(DateTime.TryParseExact(now, format, CultureInfo.CurrentCulture, DateTimeStyles.None, out result)){
Console.WriteLine(string.Format("The date is {0}, the format is: {1}", result, format));
}
}
}
You could consider pushing the format into an extension method that could be consumed as needed, i.e.:
public static class DateExt
{
public static string FormatAsSomething( this DateTime dt )
{
string format = "yyyy-MM-dd";
string result = dt.ToString( format );
return result;
}
}
And then:
var now = DateTime.Now;
Console.WriteLine( "The date is {0}", now.FormatAsSomething() );
Whenever the format needs to be updated, simply update the extension method.
You can use custom format provider for DateTime values:
static void Main(string[] args)
{
var now = DateTime.Now;
var str = string.Format(new MyDateFormatter(), "The date is {0}", now);
Console.WriteLine(str);
MyDateFormatter.DefaultDateFormat = "dd-MM-yyyy HH:mm";
str = string.Format(new MyDateFormatter(), "The date is {0}", now);
Console.WriteLine(str);
}
public class MyDateFormatter: IFormatProvider, ICustomFormatter
{
public static string DefaultDateFormat = "yyyy-MM-dd";
public object GetFormat(Type formatType)
{
if (formatType == typeof(ICustomFormatter))
return this;
return null;
}
public string Format(string format, object arg, IFormatProvider formatProvider)
{
// Check whether this is an appropriate callback
if (!this.Equals(formatProvider))
return null;
var argFormat = "{0:" + (arg is DateTime ? DefaultDateFormat : string.Empty) + "}";
return string.Format(argFormat, arg);
}
}
Related
I am reading an input from a device on a comm port, that is a date in the following format "dd/MM/yyyy hh:mm" to a string value. I am trying to format the date to show "ddMMyyyy hh:mm:ss". I have tried the following but get the error below code:
(input value is "31/08/2018 02:32")
public string ParseLine(string Line)
{
var input = Line.Split(',');
var dateTime = DateTime.Parse (input[0]);
var Action = input[1] == "1" ? "ONL" : "OFL";
var readerAddr = input[1] == "1" ? "S" : "T";
var TagType = input[2];
var TagNum = input[3].Substring(TagType.Length);
return $"{Action},{TagNum},{readerAddr},{dateTime:ddMMyyyy hh:mm:ss}";
}
Any advise will be appreciated?
Use DateTime.TryParseExact to check if 'input[0]' has a valid datetime value. Example:
public string ParseLine(string Line)
{
...
if(!DateTime.TryParseExact(input[0], "ddMMyyyy hh:mm:ss", CultureInfo.CurrentCulture, DateTimeStyles.None, out var result))
{
//Is not a valid date :C
}
Console.WriteLine("Valid date: " + result);
}
In case date time would be in some weird format, you will need to use DateTime.ParseExact(..) method like this:
var dateTime = DateTime.ParseExact(input[0], "dd/MM/yyyy hh:mm");
However, your format is one of the accepted ISO formats, so it should work like you wrote down. The best reason why is does not work is that the value of input[0] is not what you expect, so at first check what this variable actually contains.
Thanks to everyone's comments and advise I managed to get it right by using these two methods:
var dateTime = DateTime.ParseExact(input[0], "dd/MM/yyyy HH:mm", CultureInfo.InvariantCulture);
and
return $"{Action},{TagNum},{readerAddr},{dateTime:ddMMyyyy HH:mm:ss}";
I am working on a calendar. And here I want to check if the users input is a date and if it's not showing an error. I heard about DateTime.TryParse. How can I use this here properly? Can maybe anyone explain it in simple words?
public void addMeeting()
{
string readAddMeeting;
var dateFormats = new[] {"dd.MM.yyyy", "dd-MM-yyyy", "dd/MM/yyyy"}; // I copied this
Console.WriteLine("Add a schedule for specific dates: ");
readAddMeeting = Console.ReadLine();
}
Use DateTime.TryParseExact in this way:
public void addMeeting()
{
var dateFormats = new[] {"dd.MM.yyyy", "dd-MM-yyyy", "dd/MM/yyyy"};
Console.WriteLine("Add a schedule for specific dates: ");
string readAddMeeting = Console.ReadLine();
DateTime scheduleDate;
bool validDate = DateTime.TryParseExact(
readAddMeeting,
dateFormats,
DateTimeFormatInfo.InvariantInfo,
DateTimeStyles.None,
out scheduleDate);
if(validDate)
Console.WriteLine("That's a valid schedule-date: {0}", scheduleDate.ToShortDateString());
else
Console.WriteLine("Not a valid date: {0}", readAddMeeting);
}
The method returns a bool indicating whether it could be parsed or not and you pass a DateTime variable as out parameter which will be initialized if the date was valid.
Note that i'm using DateTimeFormatInfo.InvariantInfo because you don't want to use the local DateTime format but one that works in any culture. Otherwise the / in dd/MM/yyyy would be replaced with your current culture's date separators. Read
Even if it sounds a bit brutal, but it seems ike you should do some readup on arrays/lists, foreach loops and DateTime.TryParse.
That aside you have different possible date formats and want to see if one of them is valid. If we take the example from the msdn homepage for tryparse https://msdn.microsoft.com/en-us/library/ch92fbc1(v=vs.110).aspx and use foreach it becomes quite easy:
public void addMeeting()
{
string readAddMeeting;
var dateFormats = new[] {"dd.MM.yyyy", "dd-MM-yyyy", "dd/MM/yyyy"}; // I copied this
bool isDateOk = false;
Console.WriteLine("Add a schedule for specific dates: ");
readAddMeeting = Console.ReadLine();
foreach (string myDateFormat in dateFormats)
{
DateTime dateValue;
if (DateTime.TryParse(readAddMeeting, dateValue))
{
isDateOk = true;
}
}
if (isDateOk == false)
{
Console.Writeline("Sorry this is not a valid date");
}
}
I'm using "yyyy-MM-dd" several time in the code for date formatting
For example :
var targetdate = Date.ToString("yyyy-MM-dd");
Is it possible to declare the format as constant, so that use of the code again and again can be avoided
Use an extension method without declare any format again and again like this:
public static class DateExtension
{
public static string ToStandardString(this DateTime value)
{
return value.ToString(
"yyyy-MM-dd",
System.Globalization.CultureInfo.InvariantCulture);
}
}
So you use it in this way
var targetdate = Date.ToStandardString();
Use this as
const string dateFormat = "yyyy-MM-dd";
//Use
var targetdate = Date.ToString(dateFormat);
OR
//for public scope
public static readonly string DateFormat = "yyyy-MM-dd";
//Use
var targetdate = Date.ToString(DateFormat);
//from outside the class, you have to use in this way
var targetdate = Date.ToString(ClassName.DateFormat);
Another option that you can do is use the DateTimeFormatInfo overload on .ToString(...) rather than the string overload.
public static readonly System.Globalization.DateTimeFormatInfo MyDateTimeFormatInfo
= new System.Globalization.DateTimeFormatInfo()
{
ShortDatePattern = "yyyy-MM-dd",
LongTimePattern = "",
};
Now you can do var targetdate = DateTime.Now.ToString(MyDateTimeFormatInfo); which is much the same as using string, but you have a lot more control over many other formatting properties.
How to Format a date pass as a parameter to a function and return data is a string with "yyyy/mm/dd" format ?
for example if I would want to format a string retrieved from textbox and I want a special function to format it and return as a string format.
string myDate = txtJoiningDate.Text,
my function should be :
public string GetFormattedDate(string myDate)
{
//Formating should happen here.
return myDate;
}
public string GetFormattedDate(String MyDateTime)
{
//Formating should happen here.
DateTime dt = DateTime.Parse(MyDateTime);
return dt.ToString("yyyy/MM/dd");
}
also can be done with this
string dt = DateTime.Parse(txtDate.Text.Trim()).ToString("yyyy/MM/dd", CultureInfo.InvariantCulture);
you need to parse the string to a DateTime object however you need to make sure that the format you are going to parse will work.
take a look at DateTime.Parse (or TryParse):
http://msdn.microsoft.com/en-us/library/1k1skd40.aspx
then you simply do:
// lets say you are creating your datetime:
DateTime dt = new DateTime(2013, 11, 1);
return dt.ToString("dd/MM/yyyy");
the above will return 01/11/2013
more information:
http://msdn.microsoft.com/en-us/library/zdtaw1bw(v=vs.110).aspx
http://msdn.microsoft.com/en-us/library/az4se3k1(v=vs.110).aspx
Hurrey.I got the answer.Working 100%. Hope will be helpful for others.
public string FormatPostingDate(object obj)
{
if (obj != null && obj.ToString() != string.Empty)
{
DateTime postingDate = Convert.ToDateTime(obj);
return string.Format("{0:yyyy/MM/dd}", postingDate);
}
return string.Empty;
}
also can be done with this
using System.Globalization;
string dt = DateTime.Parse(txtDate.Text.Trim()).ToString("yyyy/MM/dd", CultureInfo.InvariantCulture);
in my code i can get 2 types of string that represents dateTime:
1."2013-09-05T15:55"
2."09-05T19:10"
How do i convert it to a valid DateTime?
i tried the following code but it throws an exception for the second format:
String departureDateStr = "09-05T19:10";
DateTime dt = Convert.ToDateTime(departureDateStr);
how do i convert the second type of string to a valid DateTime ?
do i need some kind of string manipulation?
thx,
Amir
DateTime.TryParseExact has an overload that allows you to pass multiple formats as an array. Each date string is then compared with the various formats within the array so you don't need to know ahead of time which format to look for.
string d1 = "2013-09-05T15:55";
string d2 = "09-05T19:10";
string[] formats = new string[] { "yyyy-MM-ddTHH:mm", "MM-ddTHH:mm" };
List<string> dates = new List<string>() { d1, d2 };
foreach (string date in dates)
{
DateTime dt;
if (DateTime.TryParseExact(date, formats, CultureInfo.InvariantCulture, DateTimeStyles.None, out dt))
{
//dt successfully parsed
}
}
TryParseExact also returns false instead of throwing an exception if none of the formats in the array matched the input.
Use DateTime.ParseExact method with custom datetime format string:
string departureDateStr = "09-05T19:10";
string departureDateStr2 = "2013-09-05T19:10";
var dt = DateTime.ParseExact(departureDateStr, "MM-ddTHH:mm", System.Globalization.CultureInfo.InvariantCulture);
var dt2 = DateTime.ParseExact(departureDateStr2, "yyyy-MM-ddTHH:mm", System.Globalization.CultureInfo.InvariantCulture);
or universal call for both formats:
var dt = DateTime.ParseExact(departureDateStr, new[] { "MM-ddTHH:mm", "yyyy-MM-ddTHH:mm" }, System.Globalization.CultureInfo.InvariantCulture);
You can use DatetIme.ParseExact() method for this. It converts the specified string representation of a date and time to its DateTime equivalent using the specified format and culture-specific format information. The format of the string representation must match the specified format exactly.
String departureDateStr = "09-05T19:10";
IFormatProvider provider = System.Globalization.CultureInfo.InvariantCulture;
string format = "MM-ddTHH:mm";
DateTime parsedDate = DateTime.ParseExact(departureDateStr, format, provider);
If you need this conversion a lot of times, then you can even make it an extension method as below:
public static class StringExtensions
{
public static DateTime ToDate(this string str)
{
IFormatProvider provider = System.Globalization.CultureInfo.InvariantCulture;
string format = "MM-ddTHH:mm";
return DateTime.ParseExact(str, format, provider);
}
}