How do I convert an integer into an ISO8601 TimeSpan? - c#

This is my input:
55
This is my desired output:
PT55H
Is there a built in class in C# that converts a timespan as: TimeSpan.TryParse(55) or as a string "55" with hours into an ISO8601 formatted string?

You can convert a number to a TimeSpan with the static TimeSpan.FromHours method. For example var ts = TimeSpan.FromHours(55.0);.
If you always want the time represented with hours only, in the ISO system, maybe you can simply say var isostring = String.Format("PT{0}H", ts.TotalHours);.

Coworker just found this for me:
TimeSpan start = new TimeSpan(int.Parse(txtStartHours.Text), 0, 0);
durationNode.Element("StartTime").Value = XmlConvert.ToString(start);
It seems to convert it to PT2D7H, but since I'm using XMLConvert.ToTimeSpan().TotalHours elsewhere, it shouldn't cause any problems!

Related

Timespan return wrong value

I have an application that has multiple languages. I'm having a problem that I convert the date from the USA standard to the one we use in Brazil, I'm using this.
DateTime dataCredito = DateTime.Parse(txtDtCredito.Text);
if (Culture == "English (United States)")
{
string dataConvertida = dataCredito.ToString("dd/MM/yyyy");
dataCredito = Convert.ToDateTime(dataConvertida);
}
But after I calculate a time span
TimeSpan ts = dataNota - dataCredito;
The dataNota is 09/10/2016
and dataCredito is 05/10/2016
It's a 4 day difference, but the timespan is calculating the method as the month is 05 and 09, the diferrence is about 123 days, using the USA standard.
How can I change this to get the time span correctly (4 days for this case)?
The problem is the way you convert text to a DateTime object. by not notifying the method, how you want it converted - you implicitly allowed the conversion to be done based on your own locale, when you should have explicitly stated the format this way:
DateTime dataCredito = DateTime.ParseExact("09/10/2016","dd/MM/yyyy",CultureInfo.InvariantCulture);
obviously you should replace "09/10/2016" with your text input, if you need support for single digits use "d/M/yyyy" formatting instead.
In order to parse a DateTime correctly, you need to use the DateTime.Parse(String, IFormatProvider) overload of DateTime.Parse().
The same applies when you are trying to parse any other data type with culture-specific representation.
I Managed to fix this.
I Just add this before the timespan,now the timespan is return the correct 4.
if (Culture == "English (United States)")
{
string dataAmericana = dataCredito.ToString("dd/MM/yyyy");
dataCredito = Convert.ToDateTime(dataAmericana);
string dataNotaNova = dataNota.ToString("dd/MM/yyyy");
dataNota = Convert.ToDateTime(dataNotaNova);
}
TimeSpan ts = dataNota - dataCredito;

How can I remove Milliseconds from the TimeSpan in C#? [duplicate]

This question already has answers here:
How can I String.Format a TimeSpan object with a custom format in .NET?
(20 answers)
Closed 6 years ago.
I am new to c# and using windows forms. the result of this code is: 01:38:07.0093844 . Anyone knows how can I remove the millisecond part (0093844) from the result (ts) I want the result to look like this : 01:38:07 (H:mm:ss) without millisecond .
Please help .Thank you
string OldDateTime = "2016-03-02 13:00:00.597"; //old DateTime
DateTime CurrentDateTime = DateTime.Now;
TimeSpan ts = CurrentDateTime.Subtract(Convert.ToDateTime(OldDateTime)); //Difference
//result of ts = 01:38:07.0093844
Create an extension method:
public static class TimeExtensions
{
public static TimeSpan StripMilliseconds(this TimeSpan time)
{
return new TimeSpan(time.Days, time.Hours, time.Minutes, time.Seconds);
}
}
Usage:
string OldDateTime = "2016-03-02 13:00:00.597"; //old DateTime
DateTime CurrentDateTime = DateTime.Now;
TimeSpan ts = CurrentDateTime.Subtract(Convert.ToDateTime(OldDateTime)).StripMilliseconds();
To format (make into a string) without milliseconds use this:
string OldDateTime = "2016-03-02 13:00:00.597"; //old DateTime
DateTime CurrentDateTime = DateTime.Now;
TimeSpan ts = CurrentDateTime.Subtract(Convert.ToDateTime(OldDateTime));
string formatted = ts.ToString(#"dd\.hh\:mm\:ss");
You can round through a division and a multiplication by the number of Ticks per second:
ts = new TimeSpan(ts.Ticks / TimeSpan.TicksPerSecond * TimeSpan.TicksPerSecond);
Internally a TimeSpan is "simply" a number of Ticks. By doing an integer division and an integer multiplication you can "round" them.
What the object contains and what you want on the screen are separate concerns, do not mix the 2. If you want it formatted on the screen as hourse, minutes, seconds then use ToString() and include that in your format. Example:
var forScreen = ts.ToString("hh:mm:ss");
See all the formatting options available on MSDN Custom TimeSpan Format Strings.
Edit
As mentioned, you can make it whatever you want. Here is an example of ToString which builds out a human readable string. These formatters are meant to build a string that you can display so you do not have to actually make changes to the underlying data. This is your presentation logic.
dif.ToString("'Elapsed: 'dd' days, 'hh' hours, 'mm' minutes and 'ss' seconds'")
You can just format the time like below:
string NewDateTime = ts.ToString("yyyy-MM-dd hh:mm:ss");

Displaying a formatted TimeSpan as string

I'd like to display a TimeSpan value, formatted as mm:ss (minutes, seconds).
The code currently performs this like this:
var timeSpan = GetTimeUntilNextEvent();
var str = DateTime.MinValue.Add(timeSpan).ToString(#"mm\:ss");
I wonder whether that is correct code. I saw other samples that show this technique, but I am not really sure what is the reason for adding something to the MinValue of DateTime.
Why cannot this code be used ? It seems to product a valid result.
var str = DateTime.FromBinary(0).Add(timeSpan).ToString(#"mm\:ss");
You don't need DateTime to format a TimeSpan.
You could simply use the timespan ToString() method:
TimeSpan timeSpan = new TimeSpan(5, 12, 2);
String str = timeSpan.ToString(#"mm\:ss"));
Also see Link.

C# seconds in string format to TimeSpan

I'm having a bit of a issue with this.
What I want to do is take this string 27.0 and convert it to a timespan.
I tried every way I could think of in order to get it to work.
TimeSpan.Parse("27.0") I know it's a format issue but I'm not sure of the format to use.
I basically have 4 values
27.0
52.4
1:24.4
1:43.3
Is there a easy way to handle all these formats?
Thanks!
Sorry these are all seconds except the 1 is minute so 1 minute 24 seconds 4 milliseconds
You can use two different approaches. Use one of the TimeSpan.From...() methods. Those convert numbers to a TimeSpan. For example to convert the double 27 to a TimeSpan with 27 seconds you use
var ts = TimeSpan.FromSeconds(27)
The only problem you will face here is that it does not allow you to specify a string. So you could for example first parse your string as an double. If you do it naivly just like that, it can be you get what you wanted, or not.
var ts = TimeSpan.FromSeconds(double.Parse("27.0"))
But if you run this for example on a system with a German locale you will get a TimeSpan with 4 minutes and 30 seconds. The reason for that is that a dot in German is not a divider for a number, it is the thousand seperator. So that number is parsed as "270". So to be safe you should also provide a NumberFormat. A better way would be.
var culture = new CultureInfo("en-US");
var tsc = TimeSpan.FromSeconds(double.Parse("27.0", culture.NumberFormat));
Now you get your 27 seconds. But the problem is still that it only parses your two first strings correctly. Your other 3 strings will still not parse, because you can't convert them to numbers. But I still added this, to be aware of culture difference if you just go up and try to parse a number to an double und use TimeSpan.FromSeconds() and so on.
Now lets look further how you can parse every string. There exists TimeSpan.Parse() and TimeSpan.ParseExact().
Now you still must knew that TimeSpan.Parse() uses culture specific formatting. In a country where a time is not separated with colons a TimeSpan.Parse() will fail. On Top of that, TimeSpan assumes a format "hh:mm" at minimum. But the Colon in this format is culture-sensitive. You could use the "en-US" Culture once again, but it wouldn't solve the problem because he doesn't accept the format "27.0".
That is the reason why you must use the TimeSpan.ParseExact() method and and provide the formats that this method should be able to parse. It also allows you to specify formats that he should be able to parse. You now should end with something like this.
var culture = new CultureInfo("en-US");
var formats = new string[] {
#"s\.f",
#"ss\.f",
#"ss\.ff",
#"m\:ss\.f",
#"m\:ss\.ff",
#"mm\:ss\.ff"
};
foreach ( var str in new string[] { "27.0", "52.4", "1:24.4", "1:43.3" } ) {
var ts = TimeSpan.ParseExact(str, formats, culture.NumberFormat);
Console.WriteLine(ts.ToString());
}
Note that in this example I added a backslash to escape the dot and the colon. If you don't do this then the formatter itself treats this as a culture-sensitive separator. But what you want is exactly the colon or the dot.
The output of this code will be
00:00:27
00:00:52.4000000
00:01:24.4000000
00:01:43.3000000
try something like this:
var timeString = "1:24.4";
var timeComponents = timeString.Split(':', '.').Reverse().ToList();
var milliseconds = timeComponents.Any() ? int.Parse(timeComponents[0]) : 0;
var seconds = timeComponents.Count() > 1 ? int.Parse(timeComponents[1]) : 0;
var minutes = timeComponents.Count() > 2 ? int.Parse(timeComponents[2]) : 0;
var timeSpan = new TimeSpan(0, 0, minutes, seconds, milliseconds);
this will deal with the milliseconds literally. You may want to pad the string component of the milliseconds with '0's, as pointed out in the comments.

.NET Date Add Days

I have date in this format "1999-05-31T13:20:00.000-05:00" I want to add some hours or days to it . Can some one suggest how to do that with this format and AddDays or AddHours ? Result need to return same format.
Try using DateTimeOffset.Parse. Then use AddDays or AddHours.
It is important to use DateTimeOffset instead of DateTime if you want to preserve the same timezone offset that you parsed.
var dateTimeOffset = DateTimeOffset.Parse("1999-05-31T13:20:00.000-05:00");
var newDateTimeOffset = dateTimeOffset.AddHours(1);
var newDateTimeString = newDateTimeOffset.ToString("O");
if you don't like the way "O" formats, you can use this:
var newDateTimeString = newDateTimeOffset.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fffK")
This will 100% match to your format.
Example:
txt_del.Text = Calendar1.SelectedDate.ToString("MM/dd/yyyy");
/* for date picking textbox*/
double d2 = double.Parse(txt_till.Text);
/*second textbox for number of days to add*/
DateTime tom = Calendar1.SelectedDate.AddDays(d2);
/*for adding number of days to selected date*/
txt_total.Text = tom.ToString("MM/dd/yy")
Use DateTime.Parse(...) to create a DateTime object. Then you can add days and/or hours, and then ToString() to get the new string.
That looks like datetimeoffset. Perhaps from sql server? You should be able to use the datetimeoffset structure and the parse method. Once you have a datetimeoffset type you can use addhours or related methods.

Categories

Resources