Timespan in milliseconds to minutes and seconds only - c#

I have a Timespan that is always in milliseconds, but I need to show the date in minutes and seconds only so that it's always "mm:ss". Even if there are hours in the timespan, the output string should contain only minutes and seconds.
For example, if there is a timespan of 02:40:30, it should get converted to 160:30.
Is there a way to achieve this?

Reed's answer is ALMOST correct, but not quite. For example, if timespan is 00:01:59, Reed's solution outputs "2:59" due to rounding by the F0 numeric format. Here's the correct implementation:
string output = string.Format("{0}:{1:00}",
(int)timespan.TotalMinutes, // <== Note the casting to int.
timespan.Seconds);
In C# 6, you can use string interpolation to reduce code:
var output = $"{(int)timespan.TotalMinutes}:{timespan.Seconds:00}";

You can format this yourself using the standard numeric format strings:
string output = string.Format("{0}:{1}", (int)timespan.TotalMinutes, timespan.Seconds);

I do it this way
timespan.ToString("mm\\:ss");

That is a pretty basic math problem.
Divide by 1000 to get total number of seconds.
Divide by 60 to get number of minutes.
Total seconds - (minutes * 60) = remaining seconds.

Related

Issue when converting microseconds to datatimeoffset c#

I am trying to convert microseconds to DateTime. Please find the code below,
long microSecs = 1632489907280; // Working
long microSecs = 1650391805000000 // Not working -- It has nanoseconds also.
DateTimeOffset utc = DateTimeOffset.FromUnixTimeMilliseconds(microSecs).UtcDateTime;
return utc.ToString("yyyy-MM-ddTHH:mm:ss.fffZ");
Anyone help me to resolve the issue?
Try using the following format:
yyyy-MM-ddTHH:mm:ss.ffffffZ
The format .fff is for milliseconds. Your example 1632489907280 is also in milliseconds, so it works fine. But the other case, instead of milliseconds is in microseconds, so the former format does not work anymore. You need 6 f symbols to deal with microseconds.
why first input is working and second input is not working?
There is no built-in method from DateTime class to process epoc microseconds
In your first example, 1632489907280 is within the milliseconds range, so DateTimeOffset.FromUnixTimeMilliseconds() considering 1632489907280 as milliseconds not microseconds.
In your second case, 1650391805000000 is greater than the max range of milliseconds.
From MSDN Documentation, DateTime.FromUnixTimeMilliseconds(milliseconds) throws an ArgumentOutOfRangeException if the
milliseconds is less than -62,135,596,800,000.
-or-
milliseconds is greater than 253,402,300,799,999.
To fix the error, convert your microseconds to milliseconds and then pass it to DateTime.FromUnixTimeMilliseconds(milliseconds).
Try below code,
public static string ProcessEpocTime(long microSecs)
{
//Convert microseconds to Milliseconds.
long milliSecs = (long)microSecs / 1000;
DateTimeOffset utc = DateTimeOffset.FromUnixTimeMilliseconds(milliSecs).UtcDateTime;
return utc.ToString("yyyy-MM-ddTHH:mm:ss.fffZ");
}
Note: This solution will work for valid microseconds value.
Try online

Difference between two times follow up (Convert to decimal)

I asked a question like this earlier and got a great answer but I made a mistake and wanted the output to be a decimal rather than a time. So here's the question.
I have two textboxes that allow a user to enter a start time and an end time in this format (h:mm). I want it to return the difference in a label. For example, if a user enters 1:35 in the first textbox and 3:30 in the second textbox and press the 'Calculate' button, it will return the decimal 1.92.
Any ideas or resources for this? I only want to calculate decimal difference of the time entered, date and seconds doesn't matter at all. Below is the code for getting an output in the format of (h:mm).
TimeSpan ts1 = TimeSpan.Parse(textBox1.Text); //"1:35"
TimeSpan ts2 = TimeSpan.Parse(textBox2.Text); //"3:30"
label.Text = (ts2 - ts1).ToString(); //"1:55:00"
It sounds like you want the total number of hours, in that 1.92 hours is 115 minutes (ish).
In that case you want:
double hours = (ts2 - ts1).TotalHours;
... you can then format that how you wish (e.g. to 2 decimal places).
For example:
TimeSpan ts1 = TimeSpan.Parse("1:35");
TimeSpan ts2 = TimeSpan.Parse("3:30");
double hours = (ts2 - ts1).TotalHours;
Console.WriteLine(hours.ToString("f2")); // Prints 1.92
Of course I'd personally use Noda Time and parse the strings as LocalTime values instead of TimeSpan values, given that that's what they're meant to be (times of day), but that's a minor quibble ;)
(ts2 - ts1).TotalHours.ToString();

Getting minutes from two DateTimes on different dates

I am comparing two DateTimes to see if there is 10 or fewer minutes between them. If I do DateTimeA - DateTimeB, and A is on 4/1/13 and B is on 4/3/13 I won't get the desired results.
I am only worried about minutes. So DateTimeA takes place at 8:00 am and DateTimeB takes place at 12:20 pm, I would want the result to be 260 minutes.
(DateTimeA - DateTimeB).TotalMinutes % 24*60
Get the total number of minutes modulo the number of minutes in a day. That way you'll get rid of the different-day problem.
You will need to use DateTime.TimeofDay() To get the actual time values and then do arithmatic on them.
or use DateTime.Minute DateTime.Hour DateTime.Second. Here is a full explanation on DateTime objects: http://msdn.microsoft.com/en-us/library/system.datetime.aspx
(A - B).TotalMinutes
A-B will yield a Timespan, for which the total minutes can then be produced.

Coverting INT to decimal following mm.ss format

I may be being really stupid here, but my brain's gone blank.
I've got a slider bar (which uses Int32 values) but I want to use it to select a position in a music song (mm.ss)
I also want to output the value that the slider is displaying in to a label above it, so it's easier to see what the slider is set to.
Anyone have any suggestions?
I thought of trying to convert the int value in to a decimal then dividing by 60.
I'm doing this in C# by the way.
What does the int value represent? If it's the number of seconds through the song, you should use:
TimeSpan time = TimeSpan.FromSeconds(seconds);
string text = time.ToString(#"mm\.ss");
Using a decimal would be a really bad idea - a format with a number of seconds isn't the same as a fractional number of minutes. For example, 10.50 minutes as a fractional number of minutes is 10 minutes and 30 seconds, not 10 minutes and 50 seconds, which is what you want as far as I can tell.
TimeSpan is the natural way of representing a time duration in .NET... which is why that's the type which supports formatting in minutes and seconds.
Converting it into decimal would not display it the way that you want it. For example four and an half minute would display as 4:50, not 4:30.
Divide the time into minutes and seconds, and format them:
int minutes = time / 60;
int seconds = time % 60;
string formatted = minutes.ToString() + ":" + seconds.ToString("00");
You should represent the length of the song internally as seconds (which can be saved in an int). To actually display it, you do song_length / 60 to get the minutes (this is called integer division, it returns the result and discards the fraction, e.g. 100/60 = 1).
After that, you can get the seconds by song_length % 60 (% is the modulo operator).
Edit: didn't see the c# tag. Jon Skeet's answer is more appropiate in c#.
Edit: I misunderstood the scope of the question, but I'll leave this in case it's helpful.
Store the total length of the track in seconds.
Calculate the position of the slider as a fraction of the maximum possible slider value.
Multiply the track length (in seconds) with fractional value obtained in 2). This gives the offset from the start of the track in seconds.
Format the value from 3) for display.
Here is a contrived example to illustrate the process:
int maxSliderValue = 100;
int sliderValue = 18;
int trackLengthInSeconds = 248;
float sliderFraction = ((float)sliderValue)/((float)maxSliderValue);
int offsetInSeconds = Convert.ToInt32(Math.Floor(trackLengthInSeconds * sliderFraction));
TimeSpan offset = TimeSpan.FromSeconds(offsetInSeconds);
string displayValue = offset.ToString(#"mm\.ss");

How to format a TimeSpan for hours not days

The following code
Console.WriteLine("{0:%h} hours {0:%m} minutes",
new TimeSpan(TimeSpan.TicksPerDay));
produces this output:
0 hours 0 minutes
What I would like is this output:
24 hours 0 minutes
What am I missing in this format string?
P.S. I know that I could manually bust up the TimeSpan into days and hours, and multiply the two but would rather use a custom format string, as these timespans are being displayed in a silverlight datagrid and people are expecting to see horus, not days.
According to MSDN, using %h will show you
The number of whole hours in the time interval that are not counted as part of days.
I think you will need to use the TotalHours property of the TimeSpan class like:
TimeSpan day= new TimeSpan(TimeSpan.TicksPerDay);
Console.WriteLine("{0} hours {1} minutes", (int)day.TotalHours, day.Minutes);
Update
If you absolutely need to be able to achieve the stated format by passing custom formatters to the ToString method, you will probably need to create your own CustomTimeSpan class. Unfortunately, you cannot inherit from a struct, so you will have to build it from the ground up.
There doesn't seem to be a format option for getting the total hours out of a TimeSpan. Your best bet would be to use the TotalHours property instead:
var mySpan = new TimeSpan(TimeSpan.TicksPerDay);
Console.WriteLine("{0} hours {1} minutes", (int)mySpan.TotalHours, mySpan.Minutes);
TotalHours returns a double as it includes the fractional hours so you need to truncate it to just the integer part.
Another possibility is:
TimeSpan day = new TimeSpan(2,1,20,0); // 2.01:20:00
Console.WriteLine("{0} hours {1} minutes", (int)day.TotalHours, day.Minutes);
Console will show:
49 hours 20 minutes

Categories