Edit timer number format - c#

I have a code like this:
private IEnumerator RunTimer(float time, int kind_of_function)
{
var seconds = (int) time;
while (time > 0)
{
yield return null;
time -= Time.deltaTime;
if ((int) time != seconds)
{
// Update the text
seconds = (int) time;
timerText.text = string.Format("{0:00}:{1:00}", seconds / 60, seconds % 60);
}
if (seconds == 0)
{
}
}
}
How to change this output format: 0:00 In such a way that if the number of seconds was two-digit then it would look like 00, and if it was one-digit then 0?

As said use one of
#0 where
0 means: I definitely want this digit always
# means: I want this digit only if it is not 0 or is a significant 0
see Custom Numeric Format Strings
D
which basically means: Only show significant decimals digits.
Since you have int you could even also use N which usually includes digits after the comma
see Standard Numeric Format strings
Simply do not define a special format at all.
What you describe is what happens by default anyway if you simply used
string.Format("{0}:{1}", seconds / 60, seconds % 60)
Then I would prefer $ string interpolation which in my opinion is more flexible and better maintainable
timeText.text = $"{seconds / 60}:{seconds % 60}";
or with the formatter
timeText.text = $"{seconds / 60:#0}:{seconds % 60:#0}";
Though in my humble opinion you should stick to what you had. Doesn't it look way better?
Okey apparently what you actually wanted is not displaying the minutes at all if there are only seconds
var minutes = seconds / 60;
if(minutes > 0)
{
timeText.text = $"{minutes}:{seconds % 60:#0}";
}
else
{
timeText.text = $"{seconds:#0}";
}

private IEnumerator RunTimer(float time)
{
var seconds = (int) time;
while (time > 0)
{
yield return null;
time -= Time.deltaTime;
bool moreThanTenSec = time / 10 > 1;
if ((int) time != seconds)
{
// Update the text
seconds = (int) time;
if (moreThanTenSec)
timerText.text = string.Format("{0:00}:{1:00}", seconds / 60, seconds % 60);
else
timerText.text = string.Format("{0:00}:{1:0}", seconds / 60, seconds % 60);
}
if (seconds == 0)
{
}
}

Related

How to Fix Time String in c#

I have a situation where in I have time strings like
10:20:70
11:65:40
I need to convert them into proper time in hh:mm:ss format using c# console.
For eg : 10:20:70 will be 10:21:10 after fixing
26:12:20 will be 02:12:10 as 26hours to be considered as 2 hours
How to achieve this? Please help me out.
Any help would be appreciated
Split the input and and either use a TimeSpan to get the real representation of the input.
Or use modulo operator % to fix the overflow.
var split = date.Split(":").Select(int.Parse).ToArray();
if(split.Count() != 3) {Console.WriteLine("bad format"); continue;}
/// public TimeSpan (int hours, int minutes, int seconds);
var realTimeSpanRepresentation = new TimeSpan(split[0],split[1],split[2]);
var correctedTimeSpanRepresentation = new TimeSpan(split[0]%24,split[1]%60,split[2]%60);
Console.WriteLine(date+" => "+realTimeSpanRepresentation+" / "+correctedTimeSpanRepresentation);
/// public DateTime (int year, int month, int day, int hour, int minute, int second);
//var realDateTimeRepresentation = new DateTime(1,1,1,split[0],split[1],split[2]); // Will go boom cause overflow
var correctedDateTimeRepresentation = new DateTime(1,1,1,split[0]%24,split[1]%60,split[2]%60);
Console.WriteLine(date+" => "+correctedDateTimeRepresentation);
Result:
10:20:70 => 10:21:10 / 10:20:10
10:20:70 => 01/01/0001 10:20:10
11:65:40 => 12:05:40 / 11:05:40
11:65:40 => 01/01/0001 11:05:40
99:99:99 => 4.04:40:39 / 03:39:39
99:99:99 => 01/01/0001 03:39:39
demo: https://dotnetfiddle.net/Uwb4zc
NB: I nammed it real representation, cause Imo "00:60:00" is one Hour not "00:00:00"
Here is a method that takes a total amount of seconds and gives proper values for how many years, days, hours, minutes and seconds in there.
public static void GetTimeFromSeconds(float secondsTotal, out int s, out int m, out int h, out int d, out int y)
{
s = m = h = d = y = 0;
s = (int)(secondsTotal % 60);
// substruct the seconds remainder from the total amount (75 - 15 = 60, 125 - 5 = 120).
secondsTotal -= s;
// if nothing left then it was less than 1 minute (45 - 0 = 45).
if (secondsTotal < 60)
return;
// secondsTotal / 60 => how many minutes total
// % 60 => how many minutes remain after splitting to whole hours
m = (int)(secondsTotal / 60 % 60);
// substruct the minutes remainder from the total amount (every minute takes 60 secs from the total)
secondsTotal -= m * 60;
// if there's not enough seconds remain in the total to get at least 1 whole hour (3600 secs)
// then it means there was less than 1 hour.
if (secondsTotal < 3600)
return;
// secondsTotal / 3600 => how many hours total
// % 24 => what will remain after splitting to whole days (24 hours)
h = (int)(secondsTotal / 3600 % 24);
// every whole hour takes 3600 secs from the total
secondsTotal -= h * 3600;
// 24 hours = 86400 seconds.
// If there's less remaining than it was less than 24 hours.
if (secondsTotal < 86400)
return;
// secondsTotal/ 86400 => how many days total
// % 365 => how many will remain after splitting to years
d = (int)(secondsTotal / 86400 % 365);
// substruct whole days
secondsTotal -= d * 86400;
// 1 year = 31536000 secs.
// is there enough secs remaining to get a whole year?
if (secondsTotal < 31536000)
return;
y = (int)(secondsTotal / 31536000);
}
So, you could parse your time into separate values
26:70:20 => hours=26, minutes=70, seconds=20
then count the total amount of seconds:
secondsTotal = hours * 3600 + minutes * 60 + seconds
and then use the method above:
int years, days, hours, mins, secs;
GetTimeFromSeconds(secondsTotal, out secs, out mins, out hours, out days, out years);
For 26 hours, 70 mins, 20 secs the results will be days: 1, hours: 3, minutes: 10, secs: 20.
Then format it into the format you need. For example:
TimeSpan properTime = new TimeSpan(hours, mins, secs);
properTime.ToString(#"hh\:mm\:ss");

How to make 5 minute countdown using TimeOfDay

Candlesticks on stock market charts are created every minute. I have created a count down timer to tell me how many seconds are left until next candlestick is to be created.
//logic for 1 min candlestick
const int MINUTE = 60;
int currentSecond = DateTime.UtcNow.Second;
int nextMin = MINUTE - currentSecond;
minuteLabel.Text = nextMin.ToString();
The chart can also display candlesticks every 5 minutes for a different perspective. So in this scenario a candlestick is created every 5 minutes. This is what I'm having trouble with. How do I create a count down timer to show me how much time is left until the next candlestick is to be created? This is what I have so far:
//inefficient logic for 5 min candlestick
int currentMinute = DateTime.UtcNow.Minute;
int nextFiveMin;
if (currentMinute >= 0 && currentMinute < 5) {
nextFiveMin = ((5 * MINUTE) - (currentMinute * MINUTE)) - currentSecond;
}
else if(currentMinute >= 5 && currentMinute < 10) {
nextFiveMin = ((10 * MINUTE) - (currentMinute * MINUTE)) - currentSecond;
}
else if (currentMinute >= 10 && currentMinute < 15) {
nextFiveMin = ((15 * MINUTE) - (currentMinute * MINUTE)) - currentSecond;
}
//etc all the way to currentMinute > 55
TimeSpan t = TimeSpan.FromSeconds(nextFiveMin);
fiverLabel.Text = t.ToString(#"mm\:ss");
Although this code works fine I think that there's probably a much easier way to implement this that I can't think of.
You can just do this:
int currentMinute = DateTime.UtcNow.Minute;
int diffMinutes = (currentMinute/5 +1) * 5;
int nextFiveMin = ((diffMinutes * MINUTE) - (currentMinute * MINUTE)) - currentSecond;
Another approach:
private void timer1_Tick(object sender, EventArgs e)
{
// from the current time, strip the seconds, then add one minute:
DateTime dt = DateTime.Today.Add(new TimeSpan(DateTime.Now.Hour, DateTime.Now.Minute, 0)).AddMinutes(1);
// keep adding minutes until it's a multiple of 5
while (dt.Minute % 5 != 0)
{
dt = dt.AddMinutes(1);
}
// display how much time until the next five minute mark:
TimeSpan t = dt.Subtract(DateTime.Now);
fiverLabel.Text = t.ToString(#"mm\:ss");
}

C#: Do not show result in comand line when result is 0

I'm having a task for school in C#. I'm having this issue with the following code (example)
static void Main()
{
do
{
Console.Write("Amount of centimeters?: ");
double centimeters = double.Parse(Console.ReadLine());
double meters = centimeters / 100;
Console.WriteLine($"Amount of meters: {meters}");
int wholeMeters = (int)meters;
Console.WriteLine($"Amount of whole meters: {wholeMeters}");
}while (true);
}
Result:
Amount of centimeters?: 350
Amount of meters: 3,5
Amount of whole meters: 3
Amount of centimeters?: 50
Amount of meters: 0,5
Amount of whole meters: 0
If the result gives 0 for "Amount of whole meters", I don't want to show the line "Amount of whole meters:" in the console.
Like this:
Amount of centimeters?: 50
Amount of meters: 0,5
How can I achieve that, only using the 'System' namespace?
You will pretty sure learn about control structures in the very near future.
Just check the value of your wholeMeters field and act on the result
if(wholeMeters != 0)
Console.WriteLine($"Amount of whole meters: {wholeMeters}");
Actually this was my exercise, and I found the result by going true the code again step by step (Took me 1 day !!! :) )
static void Main()
{
do
{
Console.Write("Timespan in seconds?: ");
int timeInSeconds;
if (int.TryParse(Console.ReadLine(), out timeInSeconds))
{
Console.WriteLine("This is:");
double amountOfDays = timeInSeconds / 86400;
if (amountOfDays != 0)
Console.WriteLine($"- {(int)amountOfDays} days");
double amountOfHours = timeInSeconds / 3600 - ((int)amountOfDays * 24);
if (amountOfHours != 0)
Console.WriteLine($"- {(int)amountOfHours} hours");
double amountOfMinuts = timeInSeconds / 60 - ((int)amountOfHours * 60) - ((int)amountOfDays * 24 * 60);
if (amountOfMinuts != 0)
Console.WriteLine($"- {(int)amountOfMinuts} minuts");
double amountOfSeconds = timeInSeconds - ((int)amountOfMinuts * 60) - ((int)amountOfHours * 60 * 60) - ((int)amountOfDays * 24 * 60 * 60);
if (amountOfSeconds != 0)
Console.WriteLine($"- {(int)amountOfSeconds} seconds");
}
else
{
Console.WriteLine("Please enter a positive integer!");
}
} while (true);
}
}
Timespan in seconds?: 34567788
This is:
400 days
2 hours
9 minuts
48 seconds
Timespan in seconds?: 34567
This is:
9 hours
36 minuts
7 seconds Timespan in seconds?: 2345 This is:
39 minuts
5 seconds
Timespan in seconds?: 45
This is:
45 seconds
Timespan in seconds?: twenty
Please enter a positive integer!
I knew I had to use the if statement, but I had my (double) variables declared at the start of the code instead of right before each calculation.
Thanks for the help anyway!

C# Console application, How to calculate Mobile Bill for any duration?

Lets say We have two billing period for our mobile call, if we call between 0-12, then call rate is 1$/Min & if we call between 12-24, then the rate is 2$/min. A call can starts at any time & lasts for any duration. I need to calculate the bill for the call duration. I'm getting it difficult to work with the datetime type. Also I need a better algorithm to calculate the bill. I'm trying something like this:
DateTime StartTime, EndTime;
decimal Bill = 0;
decimal RemainingDuration;
StartTime = DateTime.Now;
EndTime = DateTime.Now.AddHours(2.5);
var Duration = (EndTime.ToString("H:mm") - StartTime.ToString("H:mm"));
if (StartTime.Hour > 0 && StartTime.Hour < 12)
{
//var RemainingTime = 12.00 - StartTime;
//if (Duration < RemainingTime)
//{
// Bill = (Duration * 60) * 1;
// Console.WriteLine(Bill);
//}
//else
//{
// RemainingDuration = Duration - RemainingTime;
// Bill = ((RemainingTime * 60) * 1) + ((RemainingDuration * 60) * 2);
// Console.WriteLine(Bill);
//}
}
else if (StartTime.Hour > 12 && StartTime.Hour < 24)
{
//var RemainingTime = 24.00 - StartTime.Hour;
//if (Duration < RemainingTime)
//{
// Bill = (Duration * 60) * 2;
// Console.WriteLine(Bill);
//}
//else
//{
// RemainingDuration = Duration - RemainingTime;
// Bill = ((RemainingTime * 60) * 2) + ((RemainingDuration * 60) * 1);
// Console.WriteLine(Bill);
//}
}
Console.ReadLine();
There are some errors for type miss match. the errors are not my prime concern here, I wrote this code assuming the call duration can be maximum 24 hours. I need to write it for unlimited duration. Also Getting hard time to convert types. Code sample would really help. thanks
You're getting a type mismatch since you're converting the DateTime to strings before attempting arithmetic on them. As for the algorithm, well, of course there are thousands of ways you could do it, but here is a simple example that solves your 24 hour problem and perhaps gives you some more ideas.
decimal bill = 0;
DateTime startTime = DateTime.Now;
DateTime endTime = DateTime.Now.AddHours(2.5);
DateTime timeNow = startTime;
while (timeNow <= endTime)
{
decimal rate = (timeNow.Hour >= 12 && timeNow.Hour <= 24) ? 2 : 1;
bill = bill + rate;
Console.WriteLine("{0:HH:mm}, rate: ${1:#,0.00}, bill: ${2:#,0.00}", timeNow, rate, bill);
timeNow = timeNow.AddMinutes(1);
}
Console.WriteLine("Bill: {0:HH:mm} to {1:HH:mm}, {2:#,0} mins, ${3:#,0.00}", startTime, endTime, (endTime - startTime).TotalMinutes, bill);
Console.ReadLine();

Convert Degrees/Minutes/Seconds to Decimal Coordinates

In one part of my code I convert from decimal coordinates to degrees/minutes/seconds and I use this:
double coord = 59.345235;
int sec = (int)Math.Round(coord * 3600);
int deg = sec / 3600;
sec = Math.Abs(sec % 3600);
int min = sec / 60;
sec %= 60;
How would I convert back from degrees/minutes/seconds to decimal coordinates?
Try this:
public double ConvertDegreeAngleToDouble( double degrees, double minutes, double seconds )
{
//Decimal degrees =
// whole number of degrees,
// plus minutes divided by 60,
// plus seconds divided by 3600
return degrees + (minutes/60) + (seconds/3600);
}
Just to save others time, I wanted to add on to Byron's answer. If you have the point in string form (e.g. "17.21.18S"), you can use this method:
public double ConvertDegreeAngleToDouble(string point)
{
//Example: 17.21.18S
var multiplier = (point.Contains("S") || point.Contains("W")) ? -1 : 1; //handle south and west
point = Regex.Replace(point, "[^0-9.]", ""); //remove the characters
var pointArray = point.Split('.'); //split the string.
//Decimal degrees =
// whole number of degrees,
// plus minutes divided by 60,
// plus seconds divided by 3600
var degrees = Double.Parse(pointArray[0]);
var minutes = Double.Parse(pointArray[1]) / 60;
var seconds = Double.Parse(pointArray[2]) / 3600;
return (degrees + minutes + seconds) * multiplier;
}
Since degrees are each worth 1 coordinate total, and minutes are worth 1/60 of a coordinate total, and seconds are worth 1/3600 of a coordinate total, you should be able to put them back together with:
new_coord = deg + min/60 + sec/3600
Beware that it won't be the exact same as the original, though, due to floating-point rounding.
Often the western and southern hemispheres are expressed as negative degrees, and seconds contain decimals for accuracy: -86:44:52.892 Remember longitude is the X-coordinate and latitude is the Y-coordinate. This often gets mixed up because people often refer to them lat/lon and X/Y. I modified the code below for the above format.
private double ConvertDegreesToDecimal(string coordinate)
{
double decimalCoordinate;
string[] coordinateArray = coordinate.Split(':');
if (3 == coordinateArray.Length)
{
double degrees = Double.Parse(coordinateArray[0]);
double minutes = Double.Parse(coordinateArray[1]) / 60;
double seconds = Double.Parse(coordinateArray[2]) / 3600;
if (degrees > 0)
{
decimalCoordinate = (degrees + minutes + seconds);
}
else
{
decimalCoordinate = (degrees - minutes - seconds);
}
}
return decimalCoordinate;
}
CoordinateSharp is available as a Nuget package and can handle Coordinate conversions for you. It even does UTM/MGRS conversion and provides solar/lunar times relative to the input location. It's really easy to use!
Coordinate c = new Coordinate(40.465, -75.089);
//Display DMS Format
c.FormatOptions.Format = CoordinateFormatType.Degree_Minutes_Seconds;
c.ToString();//N 40º 27' 54" W 75º 5' 20.4"
c.Latitude.ToString();//N 40º 27' 54"
c.Latitude.ToDouble();//40.465
Coordinate properties are iObservable as as well. So if you change a latitude minute value for example, everything else will update.
The accepted answer to date is inaccurate and doesn't take into account what happens when you add negative numbers to positive numbers. The below code addresses the issue and will correctly convert.
public double ConvertDegreeAngleToDouble(double degrees, double minutes, double seconds)
{
var multiplier = (degrees < 0 ? -1 : 1);
var _deg = (double)Math.Abs(degrees);
var result = _deg + (minutes / 60) + (seconds / 3600);
return result * multiplier;
}
For those who prefer regular expression and to handle format like DDMMSS.dddS
This function could easily be updated to handle other format.
C#
Regex reg = new Regex(#"^((?<D>\d{1,2}(\.\d+)?)(?<W>[SN])|(?<D>\d{2})(?<M>\d{2}(\.\d+)?)(?<W>[SN])|(?<D>\d{2})(?<M>\d{2})(?<S>\d{2}(\.\d+)?)(?<W>[SN])|(?<D>\d{1,3}(\.\d+)?)(?<W>[WE])|(?<D>\d{3})(?<M>\d{2}(\.\d+)?)(?<W>[WE])|(?<D>\d{3})(?<M>\d{2})(?<S>\d{2}(\.\d+)?)(?<W>[WE]))$");
private double DMS2Decimal(string dms)
{
double result = double.NaN;
var match = reg.Match(dms);
if (match.Success)
{
var degrees = double.Parse("0" + match.Groups["D"]);
var minutes = double.Parse("0" + match.Groups["M"]);
var seconds = double.Parse("0" + match.Groups["S"]);
var direction = match.Groups["W"].ToString();
var dec = (Math.Abs(degrees) + minutes / 60d + seconds / 3600d) * (direction == "S" || direction == "W" ? -1 : 1);
var absDec = Math.Abs(dec);
if ((((direction == "W" || direction == "E") && degrees <= 180 & absDec <= 180) || (degrees <= 90 && absDec <= 90)) && minutes < 60 && seconds < 60)
{
result = dec;
}
}
return result;
}

Categories

Resources