Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Convert float to time (Minutes and seconds)

Discussion in 'Scripting' started by Laurenz_02, May 11, 2019.

  1. Laurenz_02

    Laurenz_02

    Joined:
    Oct 21, 2017
    Posts:
    52
    Hey, I have a game, in which you have to set the fastest time during some levels.

    Right now, my highscore time is being displayed like this:

    upload_2019-5-11_17-9-46.png

    The script for this is:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.UI;
    5.  
    6. public class SaveHighscore : MonoBehaviour
    7. {
    8.     public Text highscoreT;
    9.  
    10.     void Start()
    11.     {
    12.         highscoreT = GetComponent<Text>();
    13.         highscoreT.text = PlayerPrefs.GetFloat("Highscore", 0).ToString();
    14.     }
    15.  
    16.     public static void UpdateScore()
    17.     {
    18.         if(Timer.time < PlayerPrefs.GetFloat("Highscore", Timer.time))
    19.         {
    20.             PlayerPrefs.SetFloat("Highscore", Timer.time);
    21.         }
    22.     }
    23. }
    24.  
    In my level scene, I have goal with a script attached, and when you reach the goal, it calls the UpdateScore() function.

    How can I make it so, that I don't see my highscore time as a float, but like in this picture?

    upload_2019-5-11_17-12-11.png

    Thanks in advance!
     

    Attached Files:

  2. GroZZleR

    GroZZleR

    Joined:
    Feb 1, 2015
    Posts:
    3,201
  3. Laurenz_02

    Laurenz_02

    Joined:
    Oct 21, 2017
    Posts:
    52
    Okay, thanks for your reply.

    I don't have that much experience in unity, as I am a beginner.

    Could you make an example for me with my highscore script?

    That would be really appreciated!

    Thanks in advance!
     
  4. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,513
    Code (csharp):
    1. highscoreT.text = TimeSpan.FromSeconds(timeInSeconds).ToString("mm:ss");
    Uses the FromSeconds method GroZZler linked, and format string found here:
    https://docs.microsoft.com/en-us/dotnet/standard/base-types/custom-timespan-format-strings

    It's pretty straight forward, you should read through both pages to get an understanding.

    There are lots of formatting strings for numbers, timespan, datetime, and more.

    Note this is not actually a "unity" thing, it's a .net/mono/C# thing. And you can google around the internet in those context (rather than unity) for lots of help on it. C# is going on 20 years old, and was created by Microsoft one of the largest tech companies, there's LOTS of info about it.
     
    Last edited: May 11, 2019
  5. Laurenz_02

    Laurenz_02

    Joined:
    Oct 21, 2017
    Posts:
    52
    I am trying everything I can, but nothing works, I am getting alot of errors with everything I try. As a beginner in programming and game developer, this all is so confusing for me....

    highscoreT.text = TimeSpan.FromSeconds(timeInSeconds).ToString("mm:ss");

    If I put my "Timer.time" into the (timeInSeconds), it gives me the error: "Input string was not in the correct format". I can't find the solution to that error on the internet. Does anyone know how I can fix it...

    (I am working on this highscore system for 3 days now and I am getting more confused each day because I can't get it done, how hard I try :()

    Can anyone PLEASE make my code work....
     
  6. Are you putting this with quotes? If yes, have your tried without quotes?
     
    Laurenz_02 likes this.
  7. Laurenz_02

    Laurenz_02

    Joined:
    Oct 21, 2017
    Posts:
    52
    No, I am not putting it with quotes.

    Thanks for you reply anyway :)
     
  8. Laurenz_02 likes this.
  9. Laurenz_02

    Laurenz_02

    Joined:
    Oct 21, 2017
    Posts:
    52
    Then its saying: Unrecognized escape sequence.
     
  10. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,513
    Sorry, I've been in work mode all week at my day job... I'm in newest version of .net mode. Lots of OT as it's crunch time.

    I forgot that Unity uses an older version and that the ToString(string format) overload of ToString for TimeSpan doesn't exist.

    Instead you have to explicitly format the stupid thing (I bet if you put it in .net 4.x support mode my original post would work).

    Here's how you have to do it in .net 2.0 support mode:
    Code (csharp):
    1. var ts = TimeSpan.FromSeconds(timeInSeconds);
    2. highscoreT.text = string.Format("{0:00}:{1:00}", ts.Minutes, ts.Seconds);
    or

    Code (csharp):
    1. var ts = TimeSpan.FromSeconds(timeInSeconds);
    2. highscoreT.text = string.Format("{0:00}:{1:00}", ts.TotalMinutes, ts.Seconds);
    If you expect the minutes to go over 59 and you want to show them in long minute form. If you wanted it to show hours as well, well you'd expand on your formatting from there to get it.

    Note difference between Minutes and TotalMinutes (Seconds and TotalSeconds) is one is the minutes portion of the time, the other is the total minutes of the entire time.

    Think of it like 3 hours 45 minutes... Minutes is 45, but TotalMinutes is 225 (the 3 hours of 60 minutes each plus 45)
     
    homemacai, Ciyinei, Sun_Suite and 6 others like this.
  11. Laurenz_02

    Laurenz_02

    Joined:
    Oct 21, 2017
    Posts:
    52
    Dude,

    Thank you SO MUCH!!

    You are now officially declared as hero to me :)

    I got so frustrated that it didn't work, that I almost wanted to give up.

    THANKS FOR REPLYING AND HELPING!!
     
    Hiddensquid_ and Ryuuguu like this.
  12. Man, I hate that setting. I've missed the possibility above as well. :D
     
    Ryiah, Laurenz_02 and lordofduct like this.
  13. daivo12

    daivo12

    Joined:
    Jun 23, 2019
    Posts:
    2
    Oh god! it excally what I need
     
  14. Crisby

    Crisby

    Joined:
    Oct 1, 2019
    Posts:
    5
    Perfect thanks dude!
     
  15. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    11,847
    This is a rather trivial math + string operation to just do manually without use of TimeSpan or string.Format. Doing it this way may be more comfortable for some people.

    Code (csharp):
    1. int timeInSecondsInt = (int)timeInSeconds;  //We don't care about fractions of a second, so easy to drop them by just converting to an int
    2. int minutes = timeInSeconds / 60;  //Get total minutes
    3. int seconds = timeInSecondsInt - (minutes * 60);  //Get seconds for display alongside minutes
    4. highscoreT.text = minutes.ToString("D2") + ":" + seconds.ToString("D2");  //Create the string representation, where both seconds and minutes are at minimum 2 digits
     
    roymeredith, adikecapan and EDevJogos like this.
  16. FlippantMoniker

    FlippantMoniker

    Joined:
    Jul 6, 2017
    Posts:
    1
    This solution worked for me, but I noticed Unity was rounding my minutes up, until the actual timer ran down to below 30 seconds. so, I added the (int) cast:

    Code (csharp):
    1. highscoreT.text = string.Format("{0:00}:{1:00}", (int) ts.TotalMinutes, (int) ts.Seconds);
     
  17. deLord

    deLord

    Joined:
    Oct 11, 2014
    Posts:
    306
    Here's Joe's code extended if you want it with tenths of seconds. remainingTime is a float (e.g. Time.time - someValue)
    Code (CSharp):
    1. float millis = remainingTime - (minutes * 60 + seconds);
    2. string msString = "" + millis + "000";
    3. text.text = minutes.ToString("D1") + ":" + seconds.ToString("D2") + "'" + msString.Substring(2,1);
    the "000" is needed in case the msString is too short.
     
    Joe-Censored likes this.
  18. swedishfisk

    swedishfisk

    Joined:
    Oct 14, 2016
    Posts:
    57
    Beware that TimeSpan.ToString generates a lot more garbage than calculating the time strings manually.

    I just benchmarked it on device (albeit in a development build, not sure how that affects this) and I get about 10x more garbage using TimeSpan.ToString on Android ARM 64. This might not be a problem for you but we are using a milliseconds display updated each frame which TimeSpan.ToString generates 0.5kb of garbage to display versus 50B for the manual method.

    This can be quite unbearable depending on your target platform. Then again there are ways of pre-allocating a lot of stuff to get this to work with 0 garbage if it's a big issue and worth the investment.
     
    Last edited: Jan 22, 2021
  19. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,514
    Here's my solution for my Jetpack Kurt game, giving varying and human-friendly time outputs:

    Code (csharp):
    1.      public static string TimeFormatter( float seconds, bool forceHHMMSS = false)
    2.     {
    3.         float secondsRemainder = Mathf.Floor( (seconds % 60) * 100) / 100.0f;
    4.         int minutes = ((int)(seconds / 60)) % 60;
    5.         int hours = (int)(seconds / 3600);
    6.  
    7.         if (!forceHHMMSS)
    8.         {
    9.             if (hours == 0)
    10.             {
    11.                 return System.String.Format ("{0:00}:{1:00.00}", minutes, secondsRemainder);
    12.             }
    13.         }
    14.         return System.String.Format ("{0}:{1:00}:{2:00}", hours, minutes, secondsRemainder);
    15.     }
    And here's the one I use for distance:

    Code (csharp):
    1.     public static string DistanceFormatter( float meters)
    2.     {
    3.         if (meters < 1000)
    4.         {
    5.             return System.String.Format ("{0}m", (int)meters);
    6.         }
    7.         float kilometers = meters / 1000.0f;
    8.  
    9.         return System.String.Format ("{0:0.0}km", kilometers);
    10.     }
     
  20. Skeldal

    Skeldal

    Joined:
    Apr 30, 2019
    Posts:
    12
    Lurking Nija's answer was almost correct
    Code (CSharp):
    1. highscoreT.text = TimeSpan.FromSeconds(timeInSeconds).ToString(@"m\:ss");
     
    d2clon and Herbis like this.
  21. glgamesforfun

    glgamesforfun

    Joined:
    Apr 13, 2021
    Posts:
    149
    And from there on, you can change (@"hh\:mm\:ss"). And if you want to print it in days, you can add (@"dd\:hh\:mm\:ss")!
    This answer is just for everyone, who don't understand it right!
     
    Herbis likes this.
  22. d2clon

    d2clon

    Joined:
    Aug 19, 2017
    Posts:
    19
    Yes, it works on Unity 2020.3.24.

    Very esoteric for my taste the @ there :?.. C# things I asume
     
  23. glgamesforfun

    glgamesforfun

    Joined:
    Apr 13, 2021
    Posts:
    149
    There are some other options too, but @ is the "normal"...