www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - core.time Duration how to get units in double/float format?

reply Borislav Kosharov <boby_dsm abv.bg> writes:
Seeing that TickDuration is being deprecated and that I should 
use Duration instead, I faced a problem. I need to get total 
seconds like a float. Using .total!"seconds" returns a long and 
if the duration is less than 1 second I get 0. My question is 
whats the right way to do it. Because I saw that TickDuration has 
a to!("seconds", float) method, but Duration doesn't have one. I 
can convert Duration to TickDuration and call to but seeing that 
its deprecated makes me think there is a better way.
Jan 17
next sibling parent reply biozic <dransic gmail.com> writes:
On Sunday, 17 January 2016 at 14:43:26 UTC, Borislav Kosharov 
wrote:
 Seeing that TickDuration is being deprecated and that I should 
 use Duration instead, I faced a problem. I need to get total 
 seconds like a float. Using .total!"seconds" returns a long and 
 if the duration is less than 1 second I get 0. My question is 
 whats the right way to do it. Because I saw that TickDuration 
 has a to!("seconds", float) method, but Duration doesn't have 
 one. I can convert Duration to TickDuration and call to but 
 seeing that its deprecated makes me think there is a better way.
Why not just use a smaller granularity for Duration.total and convert the result? duration.total!"nsecs" / cast(float) 1e9
Jan 17
parent Borislav Kosharov <boby_dsm abv.bg> writes:
On Sunday, 17 January 2016 at 18:57:13 UTC, biozic wrote:
 On Sunday, 17 January 2016 at 14:43:26 UTC, Borislav Kosharov 
 wrote:
 Seeing that TickDuration is being deprecated and that I should 
 use Duration instead, I faced a problem. I need to get total 
 seconds like a float. Using .total!"seconds" returns a long 
 and if the duration is less than 1 second I get 0. My question 
 is whats the right way to do it. Because I saw that 
 TickDuration has a to!("seconds", float) method, but Duration 
 doesn't have one. I can convert Duration to TickDuration and 
 call to but seeing that its deprecated makes me think there is 
 a better way.
Why not just use a smaller granularity for Duration.total and convert the result? duration.total!"nsecs" / cast(float) 1e9
Yea I could do that, but its not intuitive to get a total of one magnitude to just convert it to another. My question is why doesn't `to!` accept Duration.
Jan 17
prev sibling parent reply Jonathan M Davis via Digitalmars-d-learn writes:
On Sunday, January 17, 2016 14:43:26 Borislav Kosharov via Digitalmars-d-learn
wrote:
 Seeing that TickDuration is being deprecated and that I should
 use Duration instead, I faced a problem. I need to get total
 seconds like a float. Using .total!"seconds" returns a long and
 if the duration is less than 1 second I get 0. My question is
 whats the right way to do it. Because I saw that TickDuration has
 a to!("seconds", float) method, but Duration doesn't have one. I
 can convert Duration to TickDuration and call to but seeing that
 its deprecated makes me think there is a better way.
In general, using floating point values with time is an incredibly bad idea. It can certainly make sense when printing stuff out, but using it in calculations is just asking for trouble given all of the unnecessary imprecision that it adds. So, Duration does not directly support floating point values at all, and that's very much on purpose. I'd strongly argue that the fact that TickDuration does was a mistake. So, if you're doing floating point calculations with time, I'd strongly urge you to rethink your code. And if you're just trying to print out the a duration as a floating point value, because it's nice to view that way, then that's fine, but you'll need to do the conversion yourself. And it's not that hard. It just isn't handed to you directly, because aside from printing, code really shouldn't be using floating point values for time. e.g. string toFloatingSeconds(Duration d) { import std.conv; enum hnsecsPerSecond = convert!("seconds", "hnsecs")(1); auto s = d.split!("seconds", "hnsecs")(); return to!string(s.seconds + cast(real)(s.hnsecs) / hnsecsPerSecond); } And yes, that's a bit more of a pain than using to!("seconds", float) with TickDuration, but it's also the sort of thing that most code really shouldn't be doing. So, adding that functionality to Duration would just encourage folks to write buggy code. - Jonathan M Davis
Jan 18
parent reply Borislav Kosharov <boby_dsm abv.bg> writes:
On Monday, 18 January 2016 at 12:46:31 UTC, Jonathan M Davis 
wrote:
 In general, using floating point values with time is an 
 incredibly bad idea. It can certainly make sense when printing 
 stuff out, but using it in calculations is just asking for 
 trouble given all of the unnecessary imprecision that it adds. 
 So, Duration does not directly support floating point values at 
 all, and that's very much on purpose. I'd strongly argue that 
 the fact that TickDuration does was a mistake.

 So, if you're doing floating point calculations with time, I'd 
 strongly urge you to rethink your code. And if you're just 
 trying to print out the a duration as a floating point value, 
 because it's nice to view that way, then that's fine, but 
 you'll need to do the conversion yourself. And it's not that 
 hard. It just isn't handed to you directly, because aside from 
 printing, code really shouldn't be using floating point values 
 for time. e.g.

 string toFloatingSeconds(Duration d)
 {
     import std.conv;
     enum hnsecsPerSecond = convert!("seconds", "hnsecs")(1);
     auto s = d.split!("seconds", "hnsecs")();
     return to!string(s.seconds + cast(real)(s.hnsecs) / 
 hnsecsPerSecond);
 }

 And yes, that's a bit more of a pain than using to!("seconds", 
 float) with TickDuration, but it's also the sort of thing that 
 most code really shouldn't be doing. So, adding that 
 functionality to Duration would just encourage folks to write 
 buggy code.

 - Jonathan M Davis
I want to use float time in a game where I call the update method passing the delta time as float seconds. It's more easy to multiply the dt with a speed constant meaning how much the object will move after 1 second. Such float delta time is used in many game engines and it's somewhat standart way of doing it. Also the method you wrote returns a string and I need a float to multiply it with a number. Thanks for the reply anyway
Jan 19
next sibling parent reply wobbles <grogan.colin gmail.com> writes:
On Tuesday, 19 January 2016 at 14:07:50 UTC, Borislav Kosharov 
wrote:
 On Monday, 18 January 2016 at 12:46:31 UTC, Jonathan M Davis 
 wrote:
 [...]
I want to use float time in a game where I call the update method passing the delta time as float seconds. It's more easy to multiply the dt with a speed constant meaning how much the object will move after 1 second. Such float delta time is used in many game engines and it's somewhat standart way of doing it. Also the method you wrote returns a string and I need a float to multiply it with a number. Thanks for the reply anyway
Checkout out how DSFML handles this. You simply pass around a Clock object that you can restart every frame using clock.restart(); You then call your update function with update(Clock.getElapsedTime()); Then in each objects update(Time t) method you just get the time in whatever unit you want. Works pretty well. http://www.dsfml.com/
Jan 19
parent Borislav Kosharov <boby_dsm abv.bg> writes:
On Tuesday, 19 January 2016 at 15:25:58 UTC, wobbles wrote:
 On Tuesday, 19 January 2016 at 14:07:50 UTC, Borislav Kosharov 
 wrote:
 On Monday, 18 January 2016 at 12:46:31 UTC, Jonathan M Davis 
 wrote:
 [...]
I want to use float time in a game where I call the update method passing the delta time as float seconds. It's more easy to multiply the dt with a speed constant meaning how much the object will move after 1 second. Such float delta time is used in many game engines and it's somewhat standart way of doing it. Also the method you wrote returns a string and I need a float to multiply it with a number. Thanks for the reply anyway
Checkout out how DSFML handles this. You simply pass around a Clock object that you can restart every frame using clock.restart(); You then call your update function with update(Clock.getElapsedTime()); Then in each objects update(Time t) method you just get the time in whatever unit you want. Works pretty well. http://www.dsfml.com/
Yes that's exactly what I'm using. But they changed it to return a Duration instead of Time and that broke my code. See the source https://github.com/Jebbs/DSFML/blob/master/src/dsfml/system/clock.d#L65
Jan 19
prev sibling parent Jonathan M Davis via Digitalmars-d-learn writes:
On Tuesday, January 19, 2016 14:07:50 Borislav Kosharov via Digitalmars-d-learn
wrote:
 On Monday, 18 January 2016 at 12:46:31 UTC, Jonathan M Davis
 wrote:
 In general, using floating point values with time is an
 incredibly bad idea. It can certainly make sense when printing
 stuff out, but using it in calculations is just asking for
 trouble given all of the unnecessary imprecision that it adds.
 So, Duration does not directly support floating point values at
 all, and that's very much on purpose. I'd strongly argue that
 the fact that TickDuration does was a mistake.

 So, if you're doing floating point calculations with time, I'd
 strongly urge you to rethink your code. And if you're just
 trying to print out the a duration as a floating point value,
 because it's nice to view that way, then that's fine, but
 you'll need to do the conversion yourself. And it's not that
 hard. It just isn't handed to you directly, because aside from
 printing, code really shouldn't be using floating point values
 for time. e.g.

 string toFloatingSeconds(Duration d)
 {
     import std.conv;
     enum hnsecsPerSecond = convert!("seconds", "hnsecs")(1);
     auto s = d.split!("seconds", "hnsecs")();
     return to!string(s.seconds + cast(real)(s.hnsecs) /
 hnsecsPerSecond);
 }

 And yes, that's a bit more of a pain than using to!("seconds",
 float) with TickDuration, but it's also the sort of thing that
 most code really shouldn't be doing. So, adding that
 functionality to Duration would just encourage folks to write
 buggy code.

 - Jonathan M Davis
I want to use float time in a game where I call the update method passing the delta time as float seconds. It's more easy to multiply the dt with a speed constant meaning how much the object will move after 1 second. Such float delta time is used in many game engines and it's somewhat standart way of doing it. Also the method you wrote returns a string and I need a float to multiply it with a number. Thanks for the reply anyway
Using floating point as a delta for time is inherently buggy. Depending on what you're doing, you may get away with it, but it means that error is going to creep into your timing. And the bugs introduced by using floating point like that can be quite subtle. I would strongly urge anyone using floating point values with timing like that to rework their code to use integral values. Aside from TickDuration, all of core.time and std.datetime quite carefully avoids floating point values - even functions like convClockFreq (which converts one clock frequency to another). So, if you want to use floating point values with time stuff, that's obviously your prerogative, but Duration does not directly support it and isn't ever going to directly support it precisely because it's error-prone. - Jonathan M Davis
Jan 19