Using a memory profile on my C# desktop app I have found that strings are not being released from memory causing a slow and gradual buildup.
I have this code:
var ToYYYMMDDHHMMSS = "YYYMMDDHHMMSS";
var toYR = ToYYYMMDDHHMMSS.Substring(0, 4);
var toMN = ToYYYMMDDHHMMSS.Substring(4, 2);
var toDY =ToYYYMMDDHHMMSS.Substring(6, 2);
var toHR = ToYYYMMDDHHMMSS.Substring(8, 2);
var toMI = ToYYYMMDDHHMMSS.Substring(10, 2);
var motionPath = string.Format("{0}\\Catalogues\\{1}\\{2}\\{3}\\{4}\\{5}\\{6}", Shared.MOTION_DIRECTORY, camIndex, toYR, toMN, toDY, toHR, toMI);
Is there an alternative to using the substring? Can I use String.Format someway to get my desired result?
NB
I am so sorry for my poor phrasing of my question..
var ToYYYMMDDHHMMSS = "YYYMMDDHHMMSS";
I should have added that "YYYMMDDHHMMSS" is a timestamp that always changes
{apologies)
My guess is that your real code has a value of something like 20150225071945 - so not actually the literal YYYYMMDDHHMMSS. If that's the case, I would parse the value as a DateTime rather than extracting substrings:
DateTime dateTime = DateTime.ParseExact(text, "yyyyMMddHHmmss",
CultureInfo.InvariantCulture);
var motionPath = string.Format(#"{0}\Catalogues\{1:yyyy\\MM\\dd\\HH\\mm\\ss}",
Shared.MOTION_DIRECTORY, dateTime);
Note that the format string itself is a verbatim string literal, so you don't need to escape backslashes - but I've got \\ in the format string for the DateTime because the DateTime formatting code will treat \ as an escape.
An alternative would be to format each part of the date separately:
var motionPath = string.Format(#"{0}\Catalogues\{1:yyyy}\{1:MM}\{1:dd}\{1:HH}\{1:mm}\{1:ss}",
Shared.MOTION_DIRECTORY, dateTime);
Or use Path.Combine:
var motionPath = Path.Combine(Shared.MOTION_DIRECTORY,
"Catalogues",
dateTime.ToString("yyyy"),
dateTime.ToString("MM"),
dateTime.ToString("dd"),
dateTime.ToString("HH"),
dateTime.ToString("mm"),
dateTime.ToString("ss"));
Related
I've see
this post. What if my string is string x = "Tomorrow 04-26-19 09:14AM sunrise.";, basically the datetime value is always in mm-dd-yy hh:mm<AM/PM> format. So I'd need to extract this value of 04-26-19 09:14AM and remember the starting position which = 9.
This works nicely for me:
string x = "Tomorrow 04-26-19 09:14AM sunrise.";
var regex = new Regex(#"\d{2}-\d{2}-\d{2} \d{2}:\d{2}(AM|PM)");
var match = regex.Match(x);
if (match.Success)
{
var prefix = x.Substring(0, match.Index);
var value = DateTime.ParseExact(match.Value, "MM-dd-yy hh:mmtt", System.Globalization.CultureInfo.CurrentCulture);
var suffix = x.Substring(match.Index + match.Length);
}
It's using Regex to find a potential DateTime string and then determines the prefix part of the string, the DateTime value, and the suffix part of the string.
It gives me:
"Tomorrow "
2019/04/26 09:14:00
" sunrise."
If "tomorrow" and "sunshine" aren't necessarily always going to be present in a string like x but the format of this string will be similar, I'd probably split these strings according to the space character like this.
x.Split(' ')
with indices
string strDate = x.Split(' ')[1];
string strTime = x.Split(' ')[2];
& then join those sets of strings
string dt = $"{strDate} {strTime}";
& then probably use the DateTime.ParseExact functionality to craft an actual DateTime object out of what I parsed.
DateTime.ParseExact(dt, "MM-dd-yy hh:mmtt", System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.AssumeLocal)
I generally use assumelocal so that I know the time won't be UTC.
"tt" is a placeholder for AM or PM.
If this is something you'll have to do iteratively, then I would probably create a method for this, and then simply call it routinely.
Is it possible to perform string formatting using c#'s string interpolation with a specific CultureInfo?
For example if you are in a en-US System and want the number to be formatted with pt-PT how to I achieve that with string interpolation?
You can use CultureInfo.CreateSpecificCulture for specifying the culture and the C formatter for converting the value into a string with a currency.
double amount = 50.5;
string str = $"{amount.ToString("C", CultureInfo.CreateSpecificCulture("pt-PT"))}";
Interpolated strings can be converted to FormattableStrings, which can be formatted with a IFormatProvider:
var formattableString = (FormattableString)$"{1.1:C}";
var result = formattableString.ToString(new CultureInfo("pt-PT"));
// "1,10 €"
How would I go about getting just the date from the following string?
"DateOfTest_01-30-2018-1_003"
This string is in position 8 in a CSV file, which I am looping through and parsing. What I have is:
while (!reader.EndOfStream) {
var splitLine = reader.ReadLine().SplitCommaSeparatedValues();
sample.RunDate = splitLine[8];
WriteLog("Run Date = " + sample.RunDate);}
So I need to extract characters from the string that fall between "_" and "-1" and convert the result to /mm/dd/yyyy format.
Thanks in advance for any assistance!
Better will be regular expression in this case: "(DateOfTest_)(\d{2}-\d{2}-\d{4})(-\d_\d{3})". Second group will be date. In c# you can use Regex.Match. MSDN
Use DateTime.ParseExact:
var culture = System.Globalization.CultureInfo.InvariantCulture;
var strToParse = splitLine[8].Substring(11, 10);
var date = DateTime.ParseExact(strToParse, "MM-dd-yyyy", culture);
var formattedStr = date.ToString("MM/dd/yyyy", culture);
You could use Regex matching to determine date string in the input.
var pattern = #"(?<=_)(.*?)(?=-1)";
var input = "DateOfTest_01-30-2018-1_003";
if (Regex.IsMatch(input, pattern))
{
var dateStr = Regex.Match(input, pattern);
var date = DateTime.ParseExact(dateStr.Value, "MM-dd-yyyy",null);
}
Unless you absolutely need the data at just that exact moment move your date parser outside of your reader.
After that, the answer really relies on whether or not the string in that field is always formatted the same way.
As others have pointed out, if the string is always of the same format you can substring the date out of the string. Then you can either do use one of the several built-in date format methods, or since it is formatted correctly, do a string.Replace("-", "//")
If the string format changes you'll need to try some regex to help you identify the substring to pull out.
My biggest point is that I think you should do this formatting of your field outside of your reader.
string TestString = "DateOfTest_01-30-2018-1_003";
Regex TestRegex = new Regex(#"(DateOfTest_)(\d{2}-\d{2}-20\d{2})(-\d_\d{3})");
string ExactDateFormat = "MM-dd-yyyy";
if (TestRegex.IsMatch(TestString))
{
Date = TestRegex.Match(TestString).Groups[2].ToString();
Date = DateTime.ParseExact(Date, ExactDateFormat, null).ToShortDateString();
}
I have a function which returns seconds since epoch:
public static string getEpochSeconds()
{
TimeSpan t = (DateTime.UtcNow - new DateTime(1970, 1, 1));
var timestamp = t.TotalSeconds;
return timestamp.ToString();
}
It outputs, for example: 1373689200.79987 but for the purposes of my application, I need it to output one more decimal place digit - for example 1373689200.799873. How is this possible?
Thanks!
Try using
return String.Format("{0}", timestamp.TotalSeconds);
and then you can use the format string. See this MSDN article for formatting information.
Edit 1:
Thanks #MortenMertner for the correct format.
Try using:
return String.Format("{0:N6}", timestamp.TotalSeconds);
to force 6 decimal places.
Edit 2:
You can lookup custom numeric format strings and standard numeric format strings to work out the best way to do this.
One way is to use F instead of N (both of which are standard numeric format strings). N will comma delimit the thousands where F will not.
return String.Format("{0:F6}", timestamp.TotalSeconds);
Edit 3:
As #sa_ddam213 points out in his answer, the standard ToString() method has an overload that accepts a formatting parameter. MSDN documents it here for a Double and you can clearly see that it accepts a standard numeric format string or a custom numeric format string so #sa_daam213's answer works out quite well too and is very similar to your original code but instead of N6 use F6 like in my Edit 2 above.
you can use timestamp.ToString("0.000000")
if you need result without rounding value
return t.TotalSeconds.ToString("F0")+"." +t.ToString("ffffff");
You should be able to add N6 (6 decimal places) to your ToString()
Example:
public static string getEpochSeconds()
{
TimeSpan t = (DateTime.UtcNow - new DateTime(1970, 1, 1));
var timestamp = t.TotalSeconds;
return timestamp.ToString("N6");
}
If the last digit is not significant you can use the ToString("N6") (just adds a 0 at the end in this case). But if you want the real last digit, due to some strange way of converting doubles to string by .NET you may need something like the following.
public static string getEpochSeconds()
{
TimeSpan t = (DateTime.UtcNow - new DateTime(1970, 1, 1));
//t {15901.03:57:53.6052183} System.TimeSpan
var timestamp1 = t.TotalSeconds;
//timestamp1 1373860673.6052184 double
var tstring1 = timestamp1.ToString("N6");
//tstring1 "1,373,860,673.605220" string
var timestamp = (long)(t.TotalSeconds * 1000000);
//timestamp 1373860673605218 long
string tstring =timestamp.ToString();
//tstring "1373860673605218" string
tstring = tstring.Substring(0, tstring.Length - 6) + "." + tstring.Substring(tstring.Length - 6);
//tstring "1373860673.605218" string
return tstring;
}
I have added the outputs also as a comment. Hope this helps.
I have an string like this
string strdate =#"5/2/2006";
Which is in a form of month/day/year.
I need to display it in a form of like this 02-05-2006.
How do i format the data like this?
If the value is like this: 12/28/2005, it should be displayed like this: 28-12-2010.
I know we should be splitting the data based on that we should do it.
I am not getting the syntax how to do it .
Any help would be great.
Parse the string into a DateTime and then use ToString with the right format to output it.
DateTime dt = DateTime.ParseExact(#"5/2/2006",
"MM/dd/yyyy",
CultureInfo.InvariantCulture);
string output = dt.ToString("dd-MM-yyyy");
I suggest reading up on custom and standard date and time format strings.
Read about how to parse DateTime string here: http://msdn.microsoft.com/en-us/library/1k1skd40.aspx
Then you read about how to print it here: http://msdn.microsoft.com/en-us/library/8tfzyc64.aspx
#Kevin
var datearray = strdate.split('/');
string date = datearray[0] + "-" + datearray[1] + "-" datearray[2]
Issue 1
This wont work from days from 10th to 31st... It will add leading zero to each day.
12-05-2010 is good, but for ex. 12-021-2010 is not good.
Issue 2
Wrong order of MM-dd
You can use string.replace as such:
string newString = oldString.Replace('/', '-');
This will replace each '/' with '-' and create a new string, it will not replace it within the old string as strings are immutable.