i have a file which states duration for a particular event in format MMMMMMSS.Does any one know what kind of format is this for time duration and how to convert it into seconds.I'm using C# language
If the format is really M...MSS (supplied as an integer value), converting it to seconds is quite easy:
var seconds = (value / 100) * 60 + (value % 100);
Why does it work?
value / 100 removes the last two digits (integer division), thus returning MMMMMM, and
value % 100 returns the last two digits (modulo), i.e., SS.
The remainder of the formula is MMMMMM * 60 + SS, which should be pretty self-explanatory.
My guess based on the format is that it could hold a maximum value of 99999959, which would mean 999999 minutes and 59 seconds. But that is pure conjecture, and some sample data would help to bolster this idea. You may never know for certain though.
You should at least be able to determine whether the SS part ever exceeds 59 or not, which would be very important to know.
var input = "02345612";
int minutes = int.Parse(input.Substring(0, 6));
int seconds = int.Parse(input.Substring(6, 2));
int totalSeconds = minutes * 60 + seconds;
Related
Let's say I have 21875 as totalQuantityNumber.
I need to split the totalQuantityNumber on multiple days in a for loop ex. first day 20000 and the second day 1875.
Inside my for loop at the end I do a sum of the splitted quantity so I can verify later if the splitting is correct ex. totalSplittedQuantity += splittedQuantity.
At the end of my splitting I verify if the total sum of my splitted products number is the same with the initial planned total products number ex. totalQuantityNumber== totalSplittedQuantity which it should be 21875 == 21875 but I am always off by one number when the number is odd ex. 21875 == 21874. I tried to make the division decimal and round it up at the end but the problem still persists and some of the times the result is over by one as well ex. 21875 == 21876.
This is my division inside the loop:
splittedQuantity = splittedDiffDuration * totalQuantityNumber/ totalDuration;
totalDuration and splittedDiffDuration are in minutes ex. totalDuration = 120; splittedDiffDuration = 60;
Basically I loop through each day from a DateTime interval (startDate, endDate) ex. Monday to Tuesday - splitting the quantity for each day for the duration they were planned ex. let's say on Monday its planned 60 minutes to produce X quantity and on Tuesday the same, 60 minutes to produce the rest of the quantity.
I am new to programming and not so good at math. What am I doing wrong with my division?
Regardless of numbers type (integer, decimal, floating point) there will be an error due to rounding or number representation.
To achieve what you want, you need to calculate the last proportion as the difference between total and the sum of all previous proportions.
E.g., given this total and this percentage:
Total: 100
Day 1: 30%
Day 2: 17&
Day 3: 53%
proportions will be:
Day 1: 100 * 30% = 30
Day 2: 100 * 17% = 17
Day 3: Total - (Day1 + Day2) = 100 - (30 + 17) = 53.
This, of course, gives you approximate result for the last one, but it's the only way to get this expression to be always true:
(Day 1 + Day2 + Day3) = Total
var timeSpan = new TimeSpan(10,130,10);
after the execution of above line, normally the value of timeSpan is formatted as 12:10:10
Is there any chance can I get value as 10:130:10 (i.e., without formatting)? I need it for a critical situation.
I don't believe there is a way you get 10:130:10 after you define your TimeSpan constructor. And there is no reason to keep them becuase 10 hours + 130 minutes + 10 seconds is equal to 12:10:10 as we all know. It is a time interval, not keeps time components separately.
From TimeSpan(Int32, Int32, Int32) constructor;
The specified hours, minutes, and seconds are converted to ticks, and
that value initializes this instance.
Let's look at how this contructor defined;
public TimeSpan(int hours, int minutes, int seconds)
{
_ticks = TimeToTicks(hours, minutes, seconds);
}
And this is how TimeToTicks methods implemented;
internal static long TimeToTicks(int hour, int minute, int second)
{
long totalSeconds = (long)hour * 3600 + (long)minute * 60 + (long)second;
if (totalSeconds > MaxSeconds || totalSeconds < MinSeconds)
throw new ArgumentOutOfRangeException(null, Environment.GetResourceString("Overflow_TimeSpanTooLong"));
return totalSeconds * TicksPerSecond;
}
As you can see, this method doesn't keep constructor parameters (hours, minute or second). It just calculate totalseconds from hours * 3600 + minute * 60 + second value.
TimeSpan doesn't work like that. It represents an elapsed duration of time, not individual time components. See Soner's excellent answer for further details.
If you are looking to keep "10 hours, 130 minutes, 10 seconds" as separate information, then you should consider the ISO-8601 duration format. As a string, that value would look like "PT10H130M10S".
In .NET, you can use the Period type from the Noda Time library to work with these sort of values.
To create a single part period, you can take advantage of simple factory methods like Period.FromMonths(3). But to create a multi-part period, you will need to do one of the following approaches:
You can use a PeriodBuilder to build a period from individual variables:
PeriodBuilder builder = new PeriodBuilder();
builder.Hours = 10;
builder.Minutes = 130;
builder.Seconds = 10;
Period period = builder.Build();
string s = period.ToString();
Debug.WriteLine(s); // "PT10H130M10S"
You can parse a period from an ISO-8601 duration string, using a PeriodPattern. In particular, the RoundtripPattern shown below will retain the parts exactly as they were originally supplied:
string s = "PT10H130M10S";
PeriodPattern pattern = PeriodPattern.RoundtripPattern;
ParseResult<Period> result = pattern.Parse(s);
if (result.Success)
{
Period p = result.Value;
Debug.WriteLine(p.Hours); // 10
Debug.WriteLine(p.Minutes); // 130
Debug.WriteLine(p.Seconds); // 10
}
Basically I am setting a limit of hours a user can use. Now every time a button is press, whatever time that person accrued gets taken away from this total value.
However because a limit would be represented as say 156 hours, and the datetime representation of 5 minutes would be 00.05 the result would be 155.95, rather than 155.55 .
I work this out like so
string date2 = TotalMonthlyHours.ToString("HH.mm");
double date = double.Parse(date2);
RunningTotal = date + RunningTotal;
Total = limit - RunningTotal;
Any ideas?
I think you are trying to represent 5 minutes as 0.05. The way to do that is to first of all obtain the minutes as an integer. And then simply convert to double.
double floatmins = minutes/100.0;
And you convert in the other direction like this:
int minutes = (int) (floatmins*100.0);
However, I urge you not to go any further with this. You cannot expect to perform arithmetic on a quantity like that. What is the result of 2.20-1.50? You and I know it's 30 minutes, but the computer says 0.70 which is no use at all.
Store the hours using a true fractional representation. So 5 minutes is 5/60.0. Or store the total minutes in an integer. Or total seconds in an integer. Or a TimeSpan.
The key is that you can write your own helper routines to convert from a sane storage format to a value that is human readable. But you must store the raw data in a representation that will admit arithmetic operations.
I think I worked it out by doing something like this
string[] times = date.ToString().Split('.');
if (date != 0.0)
{
string minutesString = times[1];
string hoursString = times[0];
double minutes = Convert.ToDouble(minutesString);
double hours = Convert.ToDouble(hoursString);
// end of splitting
TimeSpan Limit = TimeSpan.FromHours(limit);
TimeSpan Hours = TimeSpan.FromHours((int)hours);
TimeSpan Minutes = TimeSpan.FromMinutes((int)minutes);
TimeSpan SubTotal = Hours + Minutes;
Time = Limit - SubTotal;
}
Edit: Glad you came up with the same as me,Just read your reply David, let's hope it works
I would convert it to minutes first than add as minutes to the date
var min = Convert.ToDouble(Convert.ToDecimal(textbox.Text) * 60);
DateTimePickerEnd.DbSelectedDate = e.NewDate.Value.AddMinutes(min);
Q:
If i have two periods in the following format .ToString("H:m"); and i wanna to firstly subtract the end period from the first period ,then round the result .like the following example:
13:00 ---->First period.
13.45 ---->Last period.
the result 45 ----> round to 60
if the result = 75 for example then round to 120
Something like this
var t1 = TimeSpan.Parse("13:00").TotalMinutes;
var t2 = TimeSpan.Parse("13:45").TotalMinutes;
var round = (1 + ((int)(t2 - t1) / 60)) * 60; //Assuming t2 is always greater than t1
Hope this is what your looking for.
You can use datetime.parse to get two datetime objects for first and last period
then subtract them using lastperiod.subtract(firstperiod)
this will return u a timespan object
you can then round it as you want
Hey! I am trying to change a number of seconds in to a proper time stamp format.
Like I do this to change 180 to 03:00
private void writeTime(int tempo)
{
TimeSpan otempo = new TimeSpan(0, 0, tempo);
string minutos = ((otempo.Minutes <= 9) ? "0" : "") + otempo.Minutes.ToString();
string segundos = ((otempo.Seconds <= 9) ? "0" : "") + otempo.Seconds.ToString();
label1.Text = minutos + ":" + segundos;
centrarLabel();
}
This does give me 180 into a proper format. I just want to know if there is a simpler way.
This function might be called many many times and I don't want to create a new instance of TimeSpan every single time as I think this might pose a problem with memory etc. I tried using the DateTime class but... I just simply don't see how I can pass it the seconds and it gives me the proper format :(
I am not that great with c#. I am really trying to learn :)
Thanks
use
label.Text = string.Format("{0:d2}:{1:d2}", otempo.Minutes, otempo.Seconds);
You can use oTempo.TotalMinutes if your minute count can grow bigger that 60...
And don't forget to specify a culture also.
TimeSpan t = TimeSpan.FromSeconds(180);
string s = String.Format("{0:00}:{1:00}", t.Hours, t.Seconds);
int tempo = 180;
TimeSpan time = TimeSpan.FromSeconds(tempo);
string txt = string.Format(
"{0:00}:{1:00}", time.Minutes, time.Seconds);
(edit) As has already been observed - there are no immediate memory concerns with TimeSpan, since it is a struct. However, if you want to be paranoid:
int tempo = 180;
string txt = new StringBuilder(5)
.Append((tempo / 60).ToString().PadLeft(2, '0')).Append(':')
.Append((tempo % 60).ToString().PadLeft(2, '0')).ToString();
TimeSpan is a struct, it is (in this case) allocated on the stack so the cost it negligible, especially considering that you have to make at least one string allocation anyway which is the expensive part.
TimeSpan.FromSeconds(tempo).ToString();
should be sufficient for your needs so long as 180 seconds -> "00:03:00" is acceptable
Like others have mentioned, there's probably no need to worry about creating a new TimeSpan to do the conversion, but the simplest way to format it without creating any temporary objects is this:
String.Format("{0:00}:{1:00}", tempo / 60, tempo % 60)