Convert float to time (Minutes and seconds)

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:

The script for this is:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class SaveHighscore : MonoBehaviour
{
    public Text highscoreT;

    void Start()
    {
        highscoreT = GetComponent<Text>();
        highscoreT.text = PlayerPrefs.GetFloat("Highscore", 0).ToString();
    }

    public static void UpdateScore()
    {
        if(Timer.time < PlayerPrefs.GetFloat("Highscore", Timer.time))
        {
            PlayerPrefs.SetFloat("Highscore", Timer.time);
        }
    }
}

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?

Thanks in advance!

Use TimeSpan from the .NET library: TimeSpan.FromSeconds Method (System) | Microsoft Learn

3 Likes

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!

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

Uses the FromSeconds method GroZZler linked, and format string found here:

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.

8 Likes

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…

Are you putting this with quotes? If yes, have your tried without quotes?

1 Like

No, I am not putting it with quotes.

Thanks for you reply anyway :slight_smile:

I’m not sure, but try this:

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

And DO read the documentation. https://docs.microsoft.com/en-us/dotnet/standard/base-types/custom-timespan-format-strings

1 Like

Then its saying: Unrecognized escape sequence.

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:

var ts = TimeSpan.FromSeconds(timeInSeconds);
highscoreT.text = string.Format("{0:00}:{1:00}", ts.Minutes, ts.Seconds);

or

var ts = TimeSpan.FromSeconds(timeInSeconds);
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)

11 Likes

Dude,

Thank you SO MUCH!!

You are now officially declared as hero to me :slight_smile:

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

THANKS FOR REPLYING AND HELPING!!

2 Likes

Man, I hate that setting. I’ve missed the possibility above as well. :smile:

3 Likes

Oh god! it excally what I need

Perfect thanks dude!

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.

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

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:

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

Here’s Joe’s code extended if you want it with tenths of seconds. remainingTime is a float (e.g. Time.time - someValue)

float millis = remainingTime - (minutes * 60 + seconds);
string msString = "" + millis + "000";
text.text = minutes.ToString("D1") + ":" + seconds.ToString("D2") + "'" + msString.Substring(2,1);

the “000” is needed in case the msString is too short.

1 Like

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.

Here’s my solution for my Jetpack Kurt game, giving varying and human-friendly time outputs:

     public static string TimeFormatter( float seconds, bool forceHHMMSS = false)
    {
        float secondsRemainder = Mathf.Floor( (seconds % 60) * 100) / 100.0f;
        int minutes = ((int)(seconds / 60)) % 60;
        int hours = (int)(seconds / 3600);

        if (!forceHHMMSS)
        {
            if (hours == 0)
            {
                return System.String.Format ("{0:00}:{1:00.00}", minutes, secondsRemainder);
            }
        }
        return System.String.Format ("{0}:{1:00}:{2:00}", hours, minutes, secondsRemainder);
    }

And here’s the one I use for distance:

    public static string DistanceFormatter( float meters)
    {
        if (meters < 1000)
        {
            return System.String.Format ("{0}m", (int)meters);
        }
        float kilometers = meters / 1000.0f;

        return System.String.Format ("{0:0.0}km", kilometers);
    }
4 Likes

Lurking Nija’s answer was almost correct

highscoreT.text = TimeSpan.FromSeconds(timeInSeconds).ToString(@"m\:ss");
3 Likes