Related
I am having a date with microseconds, it is calculated by adding ticks from 2000.1.1 basically it works and it looks like:
ulong timestampInTicks = ExtendedTimestamp * TimeSpan.TicksPerMillisecond / 10;
var startDate = new DateTime(2000, 1, 1, 0, 0, 0);
string dateWithMicroseconds = startDate.AddTicks((long)timestampInTicks).ToString("HH:mm:ss.ffffff");
Problem is with return format, it returns me something like 19:34:34:260100 so miliseconds and microseconds are combined when i try HH:mm:ss.fff:fff I am getting 19:34:34:260:260 so milliseconds are doubled. Is there a way, except for using splitting string, for doing this??
Simplest custom implementation I could think of..
ulong ExtendedTimestamp = 99;
ulong timeStampInTicks = ExtendedTimestamp * TimeSpan.TicksPerMillisecond / 10;
var startDate = DateTime.Now;
string dateWithMicroseconds = startDate.AddTicks((long)timeStampInTicks).ToString("HH:mm:ss.ffffff");
string dateHHmmss = dateWithMicroseconds.Split('.')[0];
string timeffffff = dateWithMicroseconds.Split('.')[1];
int precision = 3;
string milliSecs = timeffffff.Substring(0, precision);
string microSecs = timeffffff.Substring(precision, timeffffff.Length - precision);
string customFormat = string.Format("{0}:{1}:{2}", dateHHmmss, milliSecs, microSecs);
since the microsecond is millisecond/1000, so as in reference to this date the format will return 01.01.2008 00:30:45.125.125000. Milliseconds: 125, Microseconds:125000
DateTime dates = new DateTime(2000, 1, 1, 0, 30, 45, 125);
Console.WriteLine("Date with micro and milliseconds: {0:MM/dd/yyy HH:mm:ss.fff.ffffff}",dates);
I have to do the sum of more time spans in a DataTable to use the code below, but the total sum is wrong, what is due to this:
DataTable(dt) values:
09:21
08:28
08:46
04:23
Total hours: 30,97 //97 minutes is not correct
C# Code:
TimeSpan totaleOreMarcaTempo = TimeSpan.Zero;
int conta = 0;
foreach (DataRow dr in dt.Rows)
{
String OreMarcaTempo = tm.ConteggioOreGiornaliere(dr["Data"].ToString()); //This string contains at each cycle 09:21 08:28 08:46 04:23
TimeSpan oreMarcatempo = TimeSpan.Parse(OreMarcaTempo.ToString());
totaleOreMarcaTempo = totaleOreMarcaTempo + oreMarcatempo;
conta++;
}
labelTotaleOreMarcaTempoMod.Text = "" + (int)totaleOreMarcaTempo.TotalHours + ":" + totaleOreMarcaTempo.Minutes.ToString(); //30:58
30.97 is the correct number of hours. It does not mean "30 hours and 97 minutes".
30.97 hours is 30 hours and 58 minutes. 58 / 60 is roughly 0.97.
I think you just need to format your string properly. One way to format it is:
#"{(int)yourTimeSpan.TotalHours}:{yourTimeSpan.Minutes}"
Value 30.97 is correct (30.97 hours, where 0.97 is hour (60 minutes * 0.97 = 58 minutes),
you just need convert fraction of TotalHours to minutes.
var raw = "09:21 08:28 08:46 04:23";
var totalTimespan =
raw.Split(" ")
.Select(TimeSpan.Parse)
.Aggregate(TimeSpan.Zero, (total, span) => total += span);
// Use integer value of TotalHours
var hours = (int)totalTimespan.TotalHours;
// Use actual minutes
var minutes = totalTimespan.Minutes
var output = $"{hours}:{minutes}";
var expected = "30:58";
output.Should().Be(expected); // Pass Ok
You have to change the Format. 0,98 hours = 58,2 minutes
labelTotaleOreMarcaTempoMod.Text =string.Format ("{0:00}:{1:00}:{2:00}",
(int)totaleOreMarcaTempo.TotalHours,
totaleOreMarcaTempo.Minutes,
totaleOreMarcaTempo.Seconds);
To print out a TimeSpan "correctly", just use the correct formatting:
labelTotaleOreMarcaTempoMod.Text = totaleOreMarcaTempo.ToString("c");
or
labelTotaleOreMarcaTempoMod.Text = totaleOreMarcaTempo.ToString("hh':'mm");
EDIT Do note (thanks, Basin) that the second form ignores days.
Reference: Standard TimeSpan Format Strings and Custom TimeSpan Format Strings
30.97 is the correct value but not HH:mm format.
For me the correct solution is :
var total = Math.Floor( totaleOreMarcaTempo.TotalMinutes / 60).ToString() + ":" + Math.Floor( totaleOreMarcaTempo.TotalMinutes % 60).ToString();
How do I convert a TimeSpan to a float , taking into account all of the processing unit (hour minute) for example
if (unit = hour)
convert TimeSpan to a float hours
In another context, is there not a data type "Timespan" in SQL Server ?
Use the Total* properties on TimeSpan, e.g. TimeSpan.TotalHours.
Example for minutes:
var t = new TimeSpan();
var total = t.TotalMinutes;
You can do something like this
TimeSpan elapsedTime = new TimeSpan(125000);
float floatTimeSpan;
int seconds, milliseconds;
seconds = elapsedTime.Seconds;
milliseconds = elapsedTime.Milliseconds;
floatTimeSpan = (float)seconds + ((float)milliseconds / 1000);
Console.WriteLine("Time Span: {0}", floatTimeSpan);
The program output looks like this:
Time Span: 0.012
internal static string TimeSpanToDouble(TimeSpan timeSpan, string unit)
{
double result = 0;
if (unit.Equals("MINUTES"))
result = timeSpan.TotalMinutes;
else if (unit.Equals("HOURS"))
result = timeSpan.TotalHours;
else if (unit.Equals("DAYS"))
result = timeSpan.TotalHours / 24;
else
throw new Exception();
return Convert.ToString(result);
}
You can use Convert.ToSingle, like this:
var ts = new Timespan(0, 1, 1, 30);
var minutes = Convert.ToSingle(ts.TotalMinutes);
var hours = Convert.ToSingle(ts.TotalHours);
The resulting minutes and hours will be, respectively, 61.5 and 1.025
Check out this dotnetfiddle: https://dotnetfiddle.net/uSQfk0
double TsToHoursDouble(TimeSpan ts) => ts.TotalMinutes / 60;
double TsToMinsDouble(TimeSpan ts) => ts.TotalMinutes;
using:
var hrs = TsToHoursDouble(someTimeSpan);
if you need more accurate results, you can use TotalSeconds in such calculations
Is there a tidy way of doing this rather than doing a split on the colon's and multipling out each section the relevant number to calculate the seconds?
It looks like a timespan. So simple parse the text and get the seconds.
string time = "00:01:05";
double seconds = TimeSpan.Parse(time).TotalSeconds;
You can use the parse method on aTimeSpan.
http://msdn.microsoft.com/en-us/library/system.timespan.parse.aspx
TimeSpan ts = TimeSpan.Parse( "10:20:30" );
double totalSeconds = ts.TotalSeconds;
The TotalSeconds property returns the total seconds if you just want the seconds then use the seconds property
int seconds = ts.Seconds;
Seconds return '30'.
TotalSeconds return 10 * 3600 + 20 * 60 + 30
TimeSpan.Parse() will parse a formatted string.
So
TimeSpan.Parse("03:33:12").TotalSeconds;
This code allows the hours and minutes components to be optional. For example,
"30" -> 24 seconds
"1:30" -> 90 seconds
"1:1:30" -> 3690 seconds
int[] ssmmhh = {0,0,0};
var hhmmss = time.Split(':');
var reversed = hhmmss.Reverse();
int i = 0;
reversed.ToList().ForEach(x=> ssmmhh[i++] = int.Parse(x));
var seconds = (int)(new TimeSpan(ssmmhh[2], ssmmhh[1], ssmmhh[0])).TotalSeconds;
//Added code to handle invalid strings
string time = null; //"";//"1:31:00";
string rv = "0";
TimeSpan result;
if(TimeSpan.TryParse(time, out result))
{
rv = result.TotalSeconds.ToString();
}
retrun rv;
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);
}