string.substring fails on my strings - c#

I have the below piece of code:
string date = dtxt.Substring(5, 2) + #"/" + dtxt.Substring(7, 2) + #"/" + dtxt.Substring(0, 4);
The text I'm trying to parse with it is yyyyMMdd. So from 20150309 I need 03/09/2015. I don't use dateTime format as both the input and output are strings.
The issue is I get ArgumentOutOfRangeException. string.Substring(X, Y) should get the substring from the X index for Y length, shouldn't it?

Don't use string operations in such a case.
Parse it to DateTime and format it with .ToString() method like;
string s = "20150309";
DateTime dt;
if(DateTime.TryParseExact(s, "yyyyMMdd", CultureInfo.InvariantCulture,
DateTimeStyles.None, out dt))
{
dt.ToString("MM/dd/yyyy", CultureInfo.InvariantCulture).Dump(); //03/09/2015
}

You can convert this to DateTime and then back to any string represantaion with the help of ToString(string format, IFormatProvider provider) overload:
var result = DateTime.ParseExact(dtxt, "yyyyMMdd", CultureInfo.InvariantCulture, DateTimeStyles.None)
.ToString("MM/dd/yyyy", CultureInfo.InvariantCulture);
And don't forget to pass CultureInfo.InvariantCulture as input while parsing. Not all cultures use the same format for dates and decimal currency values. Invariant culture is a special culture that you can always use in any .NET application.
By the way, the reason of exception in your code is you have not found the starting indices of month and day properly. You can change your code as:
string date = dtxt.Substring(4, 2) + #"/" + dtxt.Substring(6, 2) + #"/" + dtxt.Substring(0, 4);
But, of course it is not recommended to use operations on strings like this.

Related

Convert english Date with parse exact

I try to convert a english date to an german, but my format is not good.
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
DateTime currentCultureDate = DateTime.Now;
string format = "dd.MM.yyyy HH:mm:ss";
Console.WriteLine("Format: " + format);
Console.WriteLine("Original Date: " + currentCultureDate);
DateTime convertedDate = DateTime.ParseExact(currentCultureDate.ToString(), format, new CultureInfo("de-DE"));
Console.WriteLine("Converted Date: " + convertedDate);
FormatException.....
DateTime.ParseExact is used to create a DateTime from a string. You can pass a DateTimeFormat or CultureInfo which will be used to convert that string to DateTime.
The method does not convert it to a string in another CultureInfo, say de-DE. Therefore you can use DateTime.ToString:
string germanFormat = DateTime.Now.ToString("dd.MM.yyyy HH:mm:ss", new CultureInfo("de-DE"));
You are not doing what you say: Your code actually tries to parse the date in German format:
// This is German format
string format = "dd.MM.yyyy HH:mm:ss";
// This takes a date and parses it using the ABOVE FORMAT - which is German
DateTime convertedDate = DateTime.ParseExact(currentCultureDate.ToString(), format, new CultureInfo("de-DE"));
If you already have a DateTime you want to output in German format, you don't need ParseExact, but ToString:
string german = DateTime.Now.ToString(format, new CultureInfo("de-DE"));
A DateTime itself doesn't have any culture formatting attached. It is just a date and a time. Only when you output a DateTime, it somehow needs to be converted into a string and to do so, culture information is required. So the rule of thumb is:
If you get a string that represents a date and time value, you need to parse it into a DateTime, either using a fixed format and ParseExact or relying on the framework, passing the source culture information to Parse or TryParse.
If you have a DateTime and want to output it, you need to format it using ToString, providing either a fixed format string and culture information, or use ToString only for the current thread's culture.

Convert a specific format dateTime string to DateTime in C#

I have a formatted datetime string and I want to convert it back to DateTime but when I parse or convert that string to DateTime it throws exceptio that string is not a valid dateTime.
Here is how DateTime string is created
string temp = dt.Year.ToString("D4") +
dt.Month.ToString("D2") +
dt.Day.ToString("D2") +
dt.Hour.ToString("D2") +
dt.Minute.ToString("D2") +
dt.Second.ToString("D2");
and here is how i am parsing it back to DateTime
DateTime dtchk = DateTime.Parse(temp);
Yes it is but this is happening in a different module.
I don't even understand what is that mean. I think you just need;
DateTime dtchk = dt;
Nothing more. But anyway.. I try to explain;
Since "D" format specifier generates string representation with leading zeros if your string length is less than precision specifier, your temp will be the combination of these wider formats of months, day, hour etc..
And DateTime.Parse parses your string successfully if this string is a standard date and time format of your CurrentCulture. In your case, it is not.
You need to parse your string with ParseExact to specify your formats exactly.
DateTime dtchk = DateTime.ParseExact(temp, "yyyyMMddHHmmss", null);

I am getting Error as String was not recognized as a valid DateTime

private string format = "dd/MM/yyyy HH:mm:ss";
DateTime fromdate = DateTime.ParseExact(GetFromScanDateTextBox.Text, format, CultureInfo.InvariantCulture);
I am getting error when executing this line string was not recognized as a Valid Date Time.
I have tried this also but it not works
DateTime fromdate = DateTime.ParseExact(GetFromScanDateTextBox.Text, format,null);
Your format string must be "d/M/yyyy", take a look at this.
Basically
MM : The month, from 01 through 12.
while
M : The month, from 1 through 12.
The same for the day part.
You are telling DateTime.ParseExact that you are expecting a string with format dd/MM/yyyy HH:mm:ss but you are giving it a string with format d/M/yyyy.
You need to change your format to just d/M/yyyy.
Also I suggest using DateTime.TryParseExact to verify the validity of your string instead of using exceptions.
var okay = DateTime.TryParseExact(
input,
new[] { "dd/MM/yyyy HH:mm:ss", "d/M/yyyy" },
new CultureInfo("en-GB"),
DateTimeStyles.None,
out dateTime);
If your input string is liable to change, TryParseExact allows you to define multiple formats as shown above, or alternatively, if it is always going to be with your current culture, just do DateTime.TryParse and do away with defining the format.
var okay = DateTime.TryParse(input, out dateTime);
If your format is always month/date/year and particularly in this case(if your date is 3rd Sept 2013) you can use:
string format = "MM/dd/yyyy";
string dateTime = "9/3/2013";
dateTime = (dateTime.Split('/')[0].Length == 1 ? "0" + dateTime.Split('/')[0] : dateTime.Split('/')[0]) + "/" + (dateTime.Split('/')[1].Length == 1 ? "0" + dateTime.Split('/')[1] : dateTime.Split('/')[1]) + "/" + dateTime.Split('/')[2];
DateTime fromdate = DateTime.ParseExact(dateTime, format, CultureInfo.InvariantCulture);
Do not provide the HH:MM:SS part in the format part
string format = "dd/MM/yyyy";
DateTime fromdate = DateTime.ParseExact(test.Text, format, CultureInfo.InvariantCulture);

Formatting any string to string "yyyy/MM/dd" [duplicate]

This question already has answers here:
Date formatting yyyymmdd to yyyy-mm-dd
(9 answers)
Closed 5 years ago.
I have many strings like "20120117" and "20120321". I need to convert it in a new string with this format: "2012/01/17" and "2012/03/21". So, there is a way to do this?
I try:
string dateString = string.format("{0:d", "20120321");
and
string dateString = string.format("{0:yyyy/MM/dd", "20120321");
and
string dateString = int.Parse("20120321").ToString("yyyy/MM/dd");
I all cases i don't reach my goal. =/
So, i can i do this?
OBS: There is a way to do that without parse to datetime?
You have to parse those values in DateTime objects first.
Example :
DateTime dt = DateTime.ParseExact("20120321", "yyyyMMdd", System.Globalization.CultureInfo.InvariantCulture);
var result = dt.ToString("yyyy/MM/dd");
Edit after your comments on other answers:
if you don't like parsing because it may throw excepations, you can always use TryParse, like this:
DateTime dt;
bool success = DateTime.TryParseExact("20120321", "yyyyMMdd", System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.None, out dt);
if (success)
{
var result = dt.ToString("yyyy/MM/dd");
}
Edit 2: Using TryParseExact with multiple formats:
DateTime dt;
string[] formats = { "yyyyMMdd", "yyyy" };
bool success = DateTime.TryParseExact("20120321", formats, System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.None, out dt);
if (success)
{
var result = dt.ToString("yyyy/MM/dd");
Console.WriteLine(result);
}
It will produce 2012/03/21 when using "20120321" as input value, and 2012/01/01 when using 2012 as input value.
DateTime.ParseExact("20120321", "yyyyMMdd", CultureInfo.CurrentCulture).ToString("yyyy/MM/dd")
You could parse the string but this method gives you validation without any extra code. Imagine receiving "20120230", "20110229", or any other invalid date.
From your comments:
There is a way to do that without parse to datetime?
Yes, absolutely. If you really want to propagate bad data through your system rather than highlighting that it's incorrect, you could definitely use:
// Make sure we'll always be able to get a result whatever the input.
string paddedInput = input + "????????";
string mightBeBadWhoKnows = string.Format("{0}/{1}/{2}",
paddedInput.Substring(0, 4), // The year, if we're lucky
paddedInput.Substring(4, 2), // The month, if we're lucky
paddedInput.Substring(6, 2)); // The day, if we're lucky
But why wouldn't you want to spot the bad data?
You absolutely should parse the data. If you want to be able to continue after receiving bad data having taken appropriate action, use DateTime.TryParseExact. If you're happy for an exception to be thrown, use DateTime.ParseExact. I'd suggest using the invariant culture for both parsing and formatting, unless you really want a culture-sensitive output.
Use DateTime.ParseExact to convert to a DateTime, then use ToString on that instance to format as you desire.
DateTime.ParseExact(dateString, "yyyyMMdd").ToString("yyyy/MM/dd");
EDIT: using Insert:
EDIT2: Fixed bugs :-)
var newString = dateString.Insert(4, "/").Insert(7, "/");
Just use string operations to insert the slashes:
string input = "20120321";
string dateString =
input.Substring(0, 4) + "/" +
input.Substring(4, 2) + "/" +
input.Substring(6);
or
string dateString = input.Insert(6, "/").Insert(4, "/");
If it's a date, try this:
DateTime.ParseExact("20120321","yyyyMMdd", null).ToString("yyyy/MM/dd", System.Globalization.DateTimeFormatInfo.InvariantInfo)
try this;
string dateString = DateTime.ParseExact("20120321", "yyyyMMdd",
null).ToShortDateString();
If your data is always in the same format and if you don't need to validate it, you can use the following snippet to avoid parsing it with DateTime
var strWithInsert = input.Insert(4,"/").Insert(7,"/");

C# Parsing Dates and Times

I have some code in app along the lines of
DateTime activityDate = DateTime.Parse(tempDate + " " + tempTime);
Where tempDate is a string with values such as "2009-12-01" ( i.e. yyyy-mm-dd )
and tempTime is a string with values such as "23:12:10" ( i.e. hh:mm:ss )
Firstly, is there a better way to combine these to get a DateTime, and secondly is the code above safe to work in any region ( if not is there a way to handle this )
Hmm looking at the date more closely the concatenated date & time is actually in this format "2009-11-26T19:37:56+00:00" - what's the format string for the timezone part of the date/time?
If the format is guaranteed, ParseExact may be safer (sepcifying the pattern):
DateTime activityDate = DateTime.ParseExact(tempDate + " " + tempTime,
"yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture);
You can use ParseExact to specify the date and time format.
e.g.:
DateTime dateTime =
DateTime.ParseExact("2009-12-01 23:12:10", "yyyy-MM-dd HH:mm:ss", null);
Which yields:
Assert.That(dateTime, Is.EqualTo(new DateTime(2009, 12, 1, 23, 12, 10)));
You can also specify the culture that uses this format and parse using it the date and time while keeping the parsing safe from the processing OS culture.
From a quick look it seems that there is no culture with this exact predefined format, but in general many standard formats exists in the framework cultures.
Use ParseExact. It's been asked a few times on SO.. Link1, Link2
You can use ParseExact to specify a format for the parsing. That way there is no risk for it to be parsed in any other way:
DateTime activityDate = DateTime.ParseExact(tempDate + " " + tempTime, "yyyy'-'MM'-'dd HH':'mm':'ss", CultureInfo.InvariantCulture);
As if you cared, another option would be to do:
DateTime activityDateOnly =
DateTime.ParseExact(tempDate, "yyyy-MM-dd", CultureInfo.InvariantCulture);
TimeSpan activityTime =
TimeSpan.ParseExact(tempTime, "hh':'mm':'ss", CultureInfo.InvariantCulture);
DateTime activityDate = activityDateOnly + activityTime;
Just an option...

Categories

Resources