Unity countdown 7 days and reset - c#

I am trying to make a realtime 7 days countdown in Unity C# but am not sure how to do so?
I want to be able to get HH:MM:SS
So far I have this:
public UILabel timerLabel;
public float myTimer = 3000.0f;
void Update () {
if(myTimer>0) {
myTimer -= Time.deltaTime;
//int days = Mathf.FloorToInt(myTimer / 60F);
//int hours = Mathf.FloorToInt(myTimer / 60F);
int minutes = Mathf.FloorToInt(myTimer / 60F);
int seconds = Mathf.FloorToInt(myTimer - minutes * 60);
string niceTime = string.Format("{0:00}:{1:00}:{2:00}", minutes, minutes, seconds);
timerLabel.text= niceTime;
}
}
I would like to, when a user opens the game, get the current time (not device time but some kind of world time) and be able to set a standard time when it should reset, lets say each sunday # midnight.
Is this possible, and if yes... how?
Any help is appreciated and thanks in advance :-)
####### EDIT
OK, have tried Chris Mills-Price's Solution like this:
public UILabel timerLabel;
DateTime startTime = DateTime.UtcNow;
DateTime endTime = DateTime.UtcNow;
void Start(){
worldTime = DateTime.UtcNow;
startTime = Convert.ToDateTime("08/31/2015 00:00:01");
endTime = startTime.AddDays(7);
}
void Update () {
TimeSpan timeRemaining = endTime-startTime;
int hours = (int) timeRemaining.TotalHours; // truncate partial hours
int minutes = timeRemaining.Minutes;
int seconds = timeRemaining.Seconds;
string niceTime = string.Format("{0:00}:{1:00}:{2:00}", hours, minutes, seconds);
timerLabel.text= niceTime;
}
I can't make it do What i want. What i get is only this from timeRemaining: 7.00:00:00
My starttime seems to be OK and endTime also. What am I missing?
Hoping for help :-)

As theB suggested, DateTime.UtcNow is likely what you want.
DateTime also offers many methods to help do Date arithmetic, making this a pretty straightforward task.
In your case, assuming you had:
DateTime startTime = DateTime.UtcNow;
you could then compute the value a week later with:
DateTime endTime = startTime.AddDays(7);
To compute your HH:MM:SS values, subtract one from the other to get a TimeSpan and use the TimeSpanTotalHours/Minutes/Seconds properties.
TimeSpan timeRemaining = endTime-startTime;
int hours = (int) timeRemaining.TotalHours; // truncate partial hours
int minutes = timeRemaining.Minutes;
int seconds = timeRemaining.Seconds;

Try DateTime.UtcNow instead of starttime.
TimeSpan timeRemaining = endTime-DateTime.UtcNow;

Related

How can i convert seconds to minutes in PlayerPrefs

I am trying to show the high time score on my game over screen, so i needed to use PlayerPrefs to store the high score. The problem is i can't convert seconds to minutes when i use PlayerPrefs.GetFloat().ToString() method. You know this ((#"mm:ss)) method works with TimeSpan but PlayerPrefs.GetFloat() is a float value so i can't use that method either.
I tried .ToString(string.Format("{0:00}:{1:00}", minutes, seconds)) but it shows uncorrently(01:41 instead of 02:21, i think it is about 141 seconds = 2 mins 21 sec). Please help me.
private DateTime startTime;
private TimeSpan gameLength;
private void Start()
{
startTime = DateTime.Now;
gameLength = DateTime.Now - startTime;
string minutes = gameLength.Minutes.ToString("00");
string seconds = gameLength.Seconds.ToString("00");
mostTimeSurvived.text =
PlayerPrefs.GetFloat("HighTime").ToString(string.Format("{0:00}:{1:00}", minutes, seconds));
}
public void Finish()
{
finished = true;
gameLength = DateTime.Now - startTime;
float gameTimer = (float)gameLength.TotalSeconds;
if (PlayerPrefs.GetFloat("HighTime") < gameTimer)
{
PlayerPrefs.SetFloat("HighTime", gameTimer);
mostTimeSurvived.text = gameLength.ToString(#"mm\:ss");
}
}
using System;
//...
TimeSpan time = TimeSpan.FromSeconds(PlayerPrefs.GetFloat("key"));
Debug.Log(time.Minutes + ":" + time.Seconds);

Timespan difference not calculating correctly

I am building a web form in C#. I have 3 drops downs for Start Time (Start Hour, Start Minute, and Start Time of Day (AM or PM) and 3 for finish time. My goal is to calculate the difference. Everything works fine until I choose noon or midnight. When I choose noon and debug, the value shows as 1. Here is my code.
var startHourDDL = ddlStartHour.SelectedValue;
var startMinuteDDL = ddlStartMinute.SelectedValue;
var startTOD = ddlStartTOD.SelectedValue;
int startHour = Convert.ToInt32(startHourDDL);
int startMinute = Convert.ToInt32(startMinuteDDL);
var finishHourDDL = ddlFinishHour.SelectedValue;
var finishMinuteDDL = ddlFinishMinute.SelectedValue;
var finishTOD = ddlFinishTOD.SelectedValue;
int finishHour = Convert.ToInt32(finishHourDDL);
int finishMinute = Convert.ToInt32(finishMinuteDDL);
if (startTOD == "PM")
{
startTime = new TimeSpan(startHour + 12, startMinute, 0);
}
else
{
startTime = new TimeSpan(startHour, startMinute, 0);
}
if (finishTOD == "PM")
{
finishTime = new TimeSpan(finishHour + 12, finishMinute, 0);
}
else
{
finishTime = new TimeSpan(finishHour, finishMinute, 0);
}
TimeSpan diff = finishTime - startTime;
string time = String.Format(diff.Hours + " Hours, " + diff.Minutes + " Minutes");
lblDurAmount.Text = time;
So if I choose 2:00 PM for start time and 4:00 PM for finish time, the label shows 2 hours. However, if I choose 12:00 PM for start time and 2:00 PM for finish time I get -10 hours.
This is what I get for start time when I debug at 12:00 PM.
{1.00:00:00}
Here is what I get when I choose 5:00 PM
{17:00:00}
I can't figure out why it won't set noon to 24. I even tried adding an if statement
if (startHour == 12 && startTOD)
{
startTime = new TimeSpan(24, startMinute, 0);
}
But that didn't work either. Value was still 1.00.
A TimeSpan is for storing a duration of time, not a time during the day.
As such, while you believe you are storing "12PM", what you are actually storing is a 24 hour time period. And "2PM" is a 14 hour time period.
Thus "2PM" - "12PM" = 14 hours - 24 hours (i.e. -10 hours).
To solve this, you need to store date/time in DateTime, not TimeSpan.
Your operations works only if the startTime is less than the finishTime otherwise all the results will come back as negatives. In your example 12 PM comes after 2 PM so when you subtract 2 PM - 12 PM you get then -10 hours.
You need to check if startTime is after finishTime and swap the two values if true
if (finishTime < startTime)
{
TimeSpan swap = finishTime;
finishTime = startTime;
startTime = swap;
}
TimeSpan diff = finishTime - startTime;
string time = String.Format(diff.TotalHours + " Hours, " + diff.Minutes + " Minutes");

Compare two DATE and get Days in c#

Count Number of days by comapaing two date, When you want to compare two date like due Date and return date of a book in library then you can get no of days in this manner
int TotalDay;
DateTime due = OldDate;
int day = due.Day;
int nday = DateTime.Now.Day;
int mnt = due.Month;
int nmnt = DateTime.Now.Month;
int yr = due.Year;
int nyr = DateTime.Now.Year;
if (nyr <= yr)
{
if (nmnt <= mnt)
{
if (nday > day)
{
TotalDay = nday - day;
}
}
else
{
TotalDay = nday - day;
m = nmnt - mnt;
TotalDay = d + (m * 30);
}
}
else
{
TotalDay = nday - day;
m = nmnt - mnt;
TotalDay = d + (m * 30);
int y = nyr - yr;
TotalDay = d + (y * 365);
}
Use TimeSpan
TimeSpan ts = dateTime1 - dateTime2;
ts.TotalDays will give you the difference in number of days.
In your case due is the due date and DateTime.Now is the current date. You may use:
TimeSpan ts = DateTime.Now - due;
or use the TimeSpan.TotalDays property:
TimeSpan ts = DateTime.Now.Subtract(due);
double NumberOfDays = ts.TotalDays;
You could use TimeSpan as shown in other answers - but you need to be careful about the time of day. Are you actually trying to think of these as dates or as dates with times? What about time zones? Are you using "local" DateTime values for both?
While DateTime can handle all of this, it leaves things unclear. I'd personally use Noda Time (which shouldn't surprise anyone as it's my own library...)
LocalDate startDate = ...;
LocalDate endDate = ...;
long days = Period.Between(startDate, endDate, PeriodUnits.Days).Days;
Note that finding "today's date" requires knowing the appropriate time zone, too. (DateTime.Now and DateTime.Today assume the system time zone where your code is running, but that may or may not be what you want.)
You need TimeSpan
Timespan t = ReturnDateTime - DateTime.Now;
Then use
t.Days
for calculating how many days are left.

create a time based on seconds in c#

If i have a seconds as a int like 70 80 or 2500 how do i show it as a time of format hh:mm:ss using the most easiest way. I know i can make a separate method for it and i did but i wanna check if there is any lib func already available for it.
THis is the method i created and it works.
private void MakeTime(int seconds)
{
int min = 0;
int sec = seconds;
int hrs = 0;
if (seconds > 59)
{
min = seconds / 60;
sec = seconds % 60;
}
if (min > 59)
{
hrs = min / 60;
min = min % 60;
}
string a = string.Format("{0:00}:{1:00}:{2:00}", hrs, min, sec);
}
This is the function i am using now. it works but still i have a feeling that a single line call will do this. Any one know of any?
You can use TimeSpan
TimeSpan t = TimeSpan.FromSeconds(seconds);
and
use t.Hours, t.Minutes and t.Seconds to format the string how ever you want.
TimeSpan.FromSeconds(seconds).ToString("hh:mm:ss")
Try this:
TimeSpan t = TimeSpan.FromSeconds(seconds);
string a = string.Format("{0:00}:{1:00}:{2:00}", t.Hours, t.Minutes, t.Seconds);
TimeSpan ts = TimeSpan.FromSeconds(666);
string time = ts.ToString();
Use a TimeSpan:
TimeSpan ts = TimeSpan.FromSeconds(70);
Any reason why you can't just use DateTime instead, like this?
DateTime t = new DateTime(0);
Console.WriteLine("Enter # of seconds");
string userSeconds = Console.ReadLine();
t = t.AddSeconds(Int32.Parse(userSeconds));
Console.WriteLine("As HH:MM:SS = {0}:{1}:{2}", t.Hour, t.Minute, t.Second);

How can I convert seconds into (Hour:Minutes:Seconds:Milliseconds) time?

How can I convert seconds into (Hour:Minutes:Seconds:Milliseconds) time?
Let's say I have 80 seconds; are there any specialized classes/techniques in .NET that would allow me to convert those 80 seconds into (00h:00m:00s:00ms) format like Convert.ToDateTime or something?
For .Net <= 4.0 Use the TimeSpan class.
TimeSpan t = TimeSpan.FromSeconds( secs );
string answer = string.Format("{0:D2}h:{1:D2}m:{2:D2}s:{3:D3}ms",
t.Hours,
t.Minutes,
t.Seconds,
t.Milliseconds);
(As noted by Inder Kumar Rathore) For .NET > 4.0 you can use
TimeSpan time = TimeSpan.FromSeconds(seconds);
//here backslash is must to tell that colon is
//not the part of format, it just a character that we want in output
string str = time .ToString(#"hh\:mm\:ss\:fff");
(From Nick Molyneux) Ensure that seconds is less than TimeSpan.MaxValue.TotalSeconds to avoid an exception.
For .NET > 4.0 you can use
TimeSpan time = TimeSpan.FromSeconds(seconds);
//here backslash is must to tell that colon is
//not the part of format, it just a character that we want in output
string str = time .ToString(#"hh\:mm\:ss\:fff");
or if you want date time format then you can also do this
TimeSpan time = TimeSpan.FromSeconds(seconds);
DateTime dateTime = DateTime.Today.Add(time);
string displayTime = dateTime.ToString("hh:mm:tt");
For more you can check Custom TimeSpan Format Strings
If you know you have a number of seconds, you can create a TimeSpan value by calling TimeSpan.FromSeconds:
TimeSpan ts = TimeSpan.FromSeconds(80);
You can then obtain the number of days, hours, minutes, or seconds. Or use one of the ToString overloads to output it in whatever manner you like.
I did some benchmarks to see what's the fastest way and these are my results and conclusions. I ran each method 10M times and added a comment with the average time per run.
If your input milliseconds are not limited to one day (your result may be 143:59:59.999), these are the options, from faster to slower:
// 0.86 ms
static string Method1(int millisecs)
{
int hours = millisecs / 3600000;
int mins = (millisecs % 3600000) / 60000;
// Make sure you use the appropriate decimal separator
return string.Format("{0:D2}:{1:D2}:{2:D2}.{3:D3}", hours, mins, millisecs % 60000 / 1000, millisecs % 1000);
}
// 0.89 ms
static string Method2(int millisecs)
{
double s = millisecs % 60000 / 1000.0;
millisecs /= 60000;
int mins = millisecs % 60;
int hours = millisecs / 60;
return string.Format("{0:D2}:{1:D2}:{2:00.000}", hours, mins, s);
}
// 0.95 ms
static string Method3(int millisecs)
{
TimeSpan t = TimeSpan.FromMilliseconds(millisecs);
// Make sure you use the appropriate decimal separator
return string.Format("{0:D2}:{1:D2}:{2:D2}.{3:D3}",
(int)t.TotalHours,
t.Minutes,
t.Seconds,
t.Milliseconds);
}
If your input milliseconds are limited to one day (your result will never be greater then 23:59:59.999), these are the options, from faster to slower:
// 0.58 ms
static string Method5(int millisecs)
{
// Fastest way to create a DateTime at midnight
// Make sure you use the appropriate decimal separator
return DateTime.FromBinary(599266080000000000).AddMilliseconds(millisecs).ToString("HH:mm:ss.fff");
}
// 0.59 ms
static string Method4(int millisecs)
{
// Make sure you use the appropriate decimal separator
return TimeSpan.FromMilliseconds(millisecs).ToString(#"hh\:mm\:ss\.fff");
}
// 0.93 ms
static string Method6(int millisecs)
{
TimeSpan t = TimeSpan.FromMilliseconds(millisecs);
// Make sure you use the appropriate decimal separator
return string.Format("{0:D2}:{1:D2}:{2:D2}.{3:D3}",
t.Hours,
t.Minutes,
t.Seconds,
t.Milliseconds);
}
In case your input is just seconds, the methods are slightly faster. Again, if your input seconds are not limited to one day (your result may be 143:59:59):
// 0.63 ms
static string Method1(int secs)
{
int hours = secs / 3600;
int mins = (secs % 3600) / 60;
secs = secs % 60;
return string.Format("{0:D2}:{1:D2}:{2:D2}", hours, mins, secs);
}
// 0.64 ms
static string Method2(int secs)
{
int s = secs % 60;
secs /= 60;
int mins = secs % 60;
int hours = secs / 60;
return string.Format("{0:D2}:{1:D2}:{2:D2}", hours, mins, s);
}
// 0.70 ms
static string Method3(int secs)
{
TimeSpan t = TimeSpan.FromSeconds(secs);
return string.Format("{0:D2}:{1:D2}:{2:D2}",
(int)t.TotalHours,
t.Minutes,
t.Seconds);
}
And if your input seconds are limited to one day (your result will never be greater then 23:59:59):
// 0.33 ms
static string Method5(int secs)
{
// Fastest way to create a DateTime at midnight
return DateTime.FromBinary(599266080000000000).AddSeconds(secs).ToString("HH:mm:ss");
}
// 0.34 ms
static string Method4(int secs)
{
return TimeSpan.FromSeconds(secs).ToString(#"hh\:mm\:ss");
}
// 0.70 ms
static string Method6(int secs)
{
TimeSpan t = TimeSpan.FromSeconds(secs);
return string.Format("{0:D2}:{1:D2}:{2:D2}",
t.Hours,
t.Minutes,
t.Seconds);
}
As a final comment, let me add that I noticed that string.Format is a bit faster if you use D2 instead of 00.
TimeSpan.FromSeconds(80);
http://msdn.microsoft.com/en-us/library/system.timespan.fromseconds.aspx
The TimeSpan constructor allows you to pass in seconds. Simply declare a variable of type TimeSpan amount of seconds. Ex:
TimeSpan span = new TimeSpan(0, 0, 500);
span.ToString();
I'd suggest you use the TimeSpan class for this.
public static void Main(string[] args)
{
TimeSpan t = TimeSpan.FromSeconds(80);
Console.WriteLine(t.ToString());
t = TimeSpan.FromSeconds(868693412);
Console.WriteLine(t.ToString());
}
Outputs:
00:01:20
10054.07:43:32
In VB.NET, but it's the same in C#:
Dim x As New TimeSpan(0, 0, 80)
debug.print(x.ToString())
' Will print 00:01:20
For .NET < 4.0 (e.x: Unity) you can write an extension method to have the TimeSpan.ToString(string format) behavior like .NET > 4.0
public static class TimeSpanExtensions
{
public static string ToString(this TimeSpan time, string format)
{
DateTime dateTime = DateTime.Today.Add(time);
return dateTime.ToString(format);
}
}
And from anywhere in your code you can use it like:
var time = TimeSpan.FromSeconds(timeElapsed);
string formattedDate = time.ToString("hh:mm:ss:fff");
This way you can format any TimeSpanobject by simply calling ToString from anywhere of your code.
Why do people need TimeSpan AND DateTime if we have DateTime.AddSeconds()?
var dt = new DateTime(2015, 1, 1).AddSeconds(totalSeconds);
The date is arbitrary.
totalSeconds can be greater than 59 and it is a double.
Then you can format your time as you want using DateTime.ToString():
dt.ToString("H:mm:ss");
This does not work if totalSeconds < 0 or > 59:
new DateTime(2015, 1, 1, 0, 0, totalSeconds)
to get total seconds
var i = TimeSpan.FromTicks(startDate.Ticks).TotalSeconds;
and to get datetime from seconds
var thatDateTime = new DateTime().AddSeconds(i)
This will return in hh:mm:ss format
public static string ConvertTime(long secs)
{
TimeSpan ts = TimeSpan.FromSeconds(secs);
string displayTime = $"{ts.Hours}:{ts.Minutes}:{ts.Seconds}";
return displayTime;
}
TimeSpan t = TimeSpan.FromSeconds(EnergyRestoreTimer.Instance.SecondsForRestore);
string sTime = EnergyRestoreTimer.Instance.SecondsForRestore < 3600
? $"{t.Hours:D2}:{t.Minutes:D2}:{t.Seconds:D2}"
: $"{t.Minutes:D2}:{t.Seconds:D2}";
time.text = sTime;
private string ConvertTime(double miliSeconds)
{
var timeSpan = TimeSpan.FromMilliseconds(totalMiliSeconds);
// Converts the total miliseconds to the human readable time format
return timeSpan.ToString(#"hh\:mm\:ss\:fff");
}
//Test
[TestCase(1002, "00:00:01:002")]
[TestCase(700011, "00:11:40:011")]
[TestCase(113879834, "07:37:59:834")]
public void ConvertTime_ResturnsCorrectString(double totalMiliSeconds, string expectedMessage)
{
// Arrange
var obj = new Class();;
// Act
var resultMessage = obj.ConvertTime(totalMiliSeconds);
// Assert
Assert.AreEqual(expectedMessage, resultMessage);
}

Categories