I am trying to create a time card solution in C# and having an issue with totaling hours worked for a week. From a drop down, the user would select the number of hours they worked in a day (ex. 5:30 - the 5:30 is the total hours worked, not the actual time 5:30). The user would select the hours each work day and the application would then total the hours for the week. The application I have written totals the hours, but I have two issues: if I use .Hours to add the hours up, I run into an issue when the total goes over 24; when I use .TotalHours, it calculates over 24 ok, but somehow it adds an hour randomly when I select :30 increments. Here is the code I have to calculate and display the totals:
using .Hours does not allow the total number of hours to go over 24. Instead it converts the 24 to 1 day and starts the adding the hours again, losing the original 24:
lblWorkgroupOneTotalTime.Text = (totalWeekOneHours.Hours).ToString("00") +
":" + (totalWeekOneHours.Minutes).ToString("00");
//using .TotalHours causes the calculation to randomly add an hour to the total:
lblWorkgroupTwoTotalTime.Text =
(totalWeekTwoHours.TotalHours).ToString("00").TrimStart('0') +
":" + (totalWeekTwoHours.Minutes).ToString("00");
I feel like I am very close to having everything work correctly, but I can't figure this part out.
How about this:
Initialize an example for 30 hours and 30 minutes:
TimeSpan totalWeekThreeHours = new TimeSpan(30, 30, 0);
(Timespan works better than DateTime here I feel.)
Then:
var hours = (int)totalWeekThreeHours.TotalMinutes / 60;
var mins = totalWeekThreeHours.TotalMinutes % 60;
Output:
var example1 = hours + ":" + mins;
var example2 = String.Format("{0} hours {1} mins", hours, mins);
Console.WriteLine("Example 1: " + example1);
Console.WriteLine("Example 2: " + example2);
//Output:
//Example 1: 30:30
//Example2: 30 hours 30 minutes
it adds an hour randomly
Nothing in programming happens "randomly". So when debugging, your first step should always be to look for patterns in your bug. As long as you believe the bug happens "randomly", you will have a mental block getting in the way of finding the bug.
As for your specific issue…
For any of the Total... properties of TimeSpan, this will be a double value that represents the entire time span in the units you're retrieving, including any fractional amounts.
For example, if the TimeSpan value represents 1 hour and 45 minutes, the TotalHours value will be 1.75. At the same time, you are telling the ToString() method that you want the value rounded to the nearest integer value. So, any time that the fractional part of your time span in hours is greater than one-half, the value is rounded up to the next hour value.
If you don't want that behavior, you should just truncate the value yourself before formatting it as a string:
lblWorkgroupTwoTotalTime.Text = string.Format("{0:0}:{1:00}",
(int)totalWeekTwoHours.TotalHours, totalWeekTwoHours.Minutes);
I also don't see why you used the format string "00" only to strip off the leading 0 after the fact. Easier to just not format the string that way in the first place.
Finally, note alternative syntax for formatting strings. Your approach (calling ToString() explicitly) is fine, but I find it wordy. The above is more concise, and does a better job separating the format from the input values.
The problem with displaying TotalHours with a format string of "00" is that it's going to round up. You have a couple of choices if you don't want to show days:
Use Hours + Days * 24 for the hours
Use TotalMinutes / 60 for hours
Convert TotalHours to an int, which will always round down
For example:
var totalHours = (totalWeekOneHours.Days * 24) + totalWeekOneHours.Hours;
// Or:
var totalHours = totalWeekOneHours.TotalMinutes / 60;
// Or:
var totalHours = (int)totalWeekOneHours.TotalHours;
Then you can output it:
lblWorkgroupOneTotalTime.Text = $"{totalHours:00}:{totalWeekOneHours.Minutes:00}";
Related
I'm new to C# and i need help on converting 3 int variables into 24 hour format. I look on other Stack Overflow questions but it mostly only convert 1 variable into DateTime meanwhile i need to convert 3 variables into to 24 hour format. Here's what the variable looks like
private int hours = 1;
private int minutes = 1;
private int seconds = 1;
my expected outcome is 01:01:01 but i don't know how to do that.
You can do it like this:
var dt= new DateTime(1, 1, 1, hours, minutes, seconds); // year, month, day, hours, minutes, seconds
If you want to cast to string after that, you can do:
dt.ToString("HH:mm:ss"); // 01:01:01 // 24 hour clock digits
dt.ToString("hh:mm:ss tt"); // 01:01:01 AM // 12 hour clock
I already found a answer that works for me since i can't insert the variables like the previous 2 answers. So i just use
hours.ToString("00")
minutes.ToString("00")
seconds.ToString("00")
this makes it into a string in 2 digit number like my expected outcome.
First of all you should now im new in Programming, and english is not my mother language, im from germany.
I`m trying to write a programm, which says me how many Days, Hours and Minutes have passed, concluding to the user input. For the User input i have the double variable (time) and the integer (day), in this example i typed in 14.40 (its like 2.40pm, in germany we write it 14.40) and 2 (for tuesday).
Now i want to programm to Write the following sentence:
"Since Monday 1 Day, 14 Hours and 40 minutes have passed!"
Insted of that he prints out "Since Monday 1 Day, 1440 Hours and 0 minutes have passed!"
To split the double i used Math.Truncate to get the full hours (14), and then i subtract that from the the user input (14.40), to get the Minutes (40).
I can't find a solution in the Internet for that Problem, i hope you guys can help me with that.
class Program
{
static void Main(string[] args)
{
int day;
double time;
int VDays;
double VHours;
double VMinutes;
Console.Write("Which day do we have? (1=Monday, 2=Tuesday, ...):\n");
day = Convert.ToInt32(Console.ReadLine());
Console.Write("Which time is it?\n");
time = Convert.ToDouble(Console.ReadLine());
VDays = day - 1;
VHours = Math.Truncate(time);
VMinutes = time - VHours;
Console.WriteLine("Since Monday" + VDays + " Day, " + VHours + " Hours and " + VMinutes + " minutes have passed!");
Console.ReadLine();
}
}
Having tested it I can confirm this is a locale issue as Klaus Gütter mentioned.
Since Convert.ToDouble uses your German locale settings and commas are the decimal separators in German, it ignores the dot and interprets 14.40 as 1440.
You can recreate the problem with:
time = Convert.ToDouble(Console.ReadLine(), CultureInfo.GetCultureInfo("de-DE").NumberFormat);.
You can specify the locale to be used to fix the problem, here with InvariantCulture:
time = Convert.ToDouble(Console.ReadLine(), CultureInfo.InvariantCulture);
You also need to multiply VMinutes by 100 for it to work, since substracting the integer value from the time will leave you with a number between 0 and 1 (i.e 14.40 - 14 = 0.40, 0.40 * 100 = 40 minutes have passed).
I want to subtract minutes and get the difference. below is my code
double diff = currBlock.EndTime.Subtract(currBlock.StartTime).TotalMinutes;
In given code (currBlock.StartTime = 23:30:00) and (currBlock.EndTime= 00:20:00)
here starttime is time of today i.e.(09/26/2016 23:30:00), night time which will be consider as 11:30 PM and endtime is time of tomorrow i.e.(09/27/2016 00:20:00), morning time which will be consider as 12:20 Am. In my code i am getting values in minus which is -1390 and it is incorrect. So please help me to solve this.
Here i have attach image of data for further reference.
please explain me properly, how do i use it? it is just a time block for different shift so there is no date include in it
There is a date included in it. You're telling us that EndTime is something like 09/27/2016 00:20:00, while StartTime is something like 09/26/2016 23:30:00. The problem is that that knowledge is in your head and not in your code. If you subtract the values as TimeSpans, then you're literally saying: what is 30 minutes minus 23 hours and 30 minutes. The answer, of course is -23 hours. To get the real difference, you must include the dates, which means utilizing a DateTime or DateTimeOffset type for both StartTime and EndTime, so you can encode that whole date and time. Then, when you do the subtraction, it will return the right value.
Below Code works for me. Thanks friends for your support and help.
string strCurrDate = (DateTime.Now.Date + currBlock.EndTime).ToString();
DateTime dtYourDate = DateTime.Parse((DateTime.Now.AddDays(-1).Date + currBlock.StartTime).ToString());
string strYourDate = dtYourDate.ToShortDateString() + " " + dtYourDate.ToLongTimeString();
string strTotalMinsElapsed = TotalMinutesElapsed(dtYourDate).ToString();
private long TotalMinutesElapsed(DateTime dtYourDate)
{
long lTotalMinutesElapsed = 0;
//Find Current Date and Time
DateTime dtCurrent = DateTime.Now;
//Find Time Difference details between current date and your given date
TimeSpan tsDiff = dtCurrent.Subtract(dtYourDate);
//Add Total Minutes for Days difference
lTotalMinutesElapsed = lTotalMinutesElapsed + tsDiff.Days * (24 * 60);
//Add Total Minutes for Hour difference
lTotalMinutesElapsed = lTotalMinutesElapsed + tsDiff.Hours * 60;
//Add Minutes
lTotalMinutesElapsed = lTotalMinutesElapsed + tsDiff.Minutes;
return lTotalMinutesElapsed;
}
I want to store time 11:22:33 in table, but the time is stored like this 112233. How to insert : between the string
String text = "txtucrtime.Text,HH:MM:SS";
var split = Regex.Split(text, #"(?<=[:::])");
See this question: Best way to store time (hh:mm) in a database
Assuming you want to store the time of day, store as an integer which represents the smallest precision you want. If you want to store time in seconds:
hours * 60 * 60
+ minutes * 60
+ seconds
If you want to store to the millisecond, multiple each of the values by 1000 prior to adding them, then also add the milliseconds portion of your time value.
String text = hrs + ":" + mins + ":"secs;
try these thanks
I want to save the user's hours worked in a database varchar column, but by default, the formatted value includes days if the number of hours is more than 24. I just want the total number of hours.
For example: if a user works 10:00:00 hours today, then 13:00:00 hours tomorrow, and 3:30:00 hours the day after tomorrow then the formatted total I want is 26:30:00. Instead, I am seeing 1.2:30:00.
How can I get the formatting I want?
Also, when I save the value 40:00:00 in the database manually, and try to read it into a TimeSpan later, I get a bug.
How can I save the hours in the database the way I want, and still be able to read it back into a TimeSpan later?
You could do something like:
TimeSpan time = ...;
string timeForDisplay = (int)time.TotalHours + time.ToString(#"\:mm\:ss");
Try TimeSpan.TotalHours
String timeStamp = "40:00:00";
var segments = timeStamp.Split(':');
TimeSpan t = new TimeSpan(0, Convert.ToInt32(segments[0]),
Convert.ToInt32(segments[1]), Convert.ToInt32(segments[2]));
string time = string.Format("{0}:{1}:{2}",
((int) t.TotalHours), t.Minutes, t.Seconds);