I am updating an old 1992-style application that previously used time_t based time to produce trend graphs of logged data. I am putting in ptime instead, and have come unstuck. The time range of the X-axis in this app is essentially under user control. It can show any period from a few seconds (sub seconds in the new version) up to three years. The labels on the x axis are placed at sensible points for the current range. For example if the graph shows 30 minutes, the ticks on the axis occur at 5 minute intervals; if it is displaying a week they occur on day boundaries. The old version of the program achieves this label placing by using the % operator and doing arithmetic with the seconds that underly time_t. I would like to do something similar with ptime. My attempt went like this: // Get next time (>= start) which falls on an itvl boundary ptime GetNextBoundary2(const ptime& start, const time_duration& itvl) { // Use 1/1/1970 as a base - not ideal but good enough for this const ptime origin(date(1970,1,1)); time_duration start_offset = start - origin; return ptime (start + itvl - nanosec(start_offset.ticks() % itvl.ticks())); } This fails because - among other reasons - although I can get ticks out, nanosec() won't put them back in again. I guess it is normalising on the way in? I feel sure I am going about this the wrong way, but am baffled as to what I should do next. All help gratefully received. Please be gentle with me - I am essentially a Pascal programmer who is busking, and finding this C++ template stuff hard. TIA Will Watts AIS Ltd
willw_at_ais wrote
// Get next time (>= start) which falls on an itvl boundary ptime GetNextBoundary2(const ptime& start, const time_duration& itvl) { // Use 1/1/1970 as a base - not ideal but good enough for this const ptime origin(date(1970,1,1)); time_duration start_offset = start - origin; return ptime (start + itvl - nanosec(start_offset.ticks() % itvl.ticks())); }
Not sure this will compile. I think you might need to try: // | //Note comma v return ptime (start, itvl - nanosec(start_offset.ticks() % itvl.ticks()));
This fails because - among other reasons - although I can get ticks out, nanosec() won't put them back in again. I guess it is normalising on the way in?
Not really, just adjustment of a count to the appropriate resolution. Maybe you could be a little bit more specific about how this is 'failing' -- runtime or compile time... HTH, Jeff
Maybe you could be a little bit more specific about how this is 'failing' -- runtime or compile time...
My apologies. I stated my problem in haste, and made a poor show of
it. Let me try harder.
1. I believe I need to do arithmetic on time lengths using the %
operator. So I need to get at some sort of integer that represents
them. I have been using the .ticks() to get my integer out and the
nanosec() class to put things back into periods. However I notice that
using namespace boost::posix_time;
using namespace boost::gregorian;
// ...
LONGLONG res = 1548000000000;
LONGLONG otherres = nanosec(res).ticks();
if (otherres != res)
TRACE("Eeek\n"); // Send to debug window
puts "Eeek" on my debug console. So nanosec() does not work as the
inverse of ticks(). (Perhaps it takes a long?) So having done
arithmetic on a value obtained from ticks(), how should I be poking it
back in?
2. Even if it worked, I hate using nanosec() for this job anyway. If I
am pulling something out with ticks(), I feel I should be putting it
back as ticks(). So that I could change to the cheap and cheerful
microsecond only resolution and have it still work.
I suspect maybe I could if I had access to a private constructor of
yours
explicit time_duration(tick_type ticks) :
date_time::time_duration
1. I believe I need to do arithmetic on time lengths using the % operator. So I need to get at some sort of integer that represents them. I have been using the .ticks() to get my integer out and the nanosec() class to put things back into periods. However I notice that
using namespace boost::posix_time; using namespace boost::gregorian; // ...
LONGLONG res = 1548000000000; LONGLONG otherres = nanosec(res).ticks(); if (otherres != res) TRACE("Eeek\n"); // Send to debug window
puts "Eeek" on my debug console. So nanosec() does not work as the inverse of ticks(). (Perhaps it takes a long?) So having done arithmetic on a value obtained from ticks(), how should I be poking it back in?
I'm suprised by this -- I think it should work. But I agree this isn't the best approach.
2. Even if it worked, I hate using nanosec() for this job anyway. If I am pulling something out with ticks(), I feel I should be putting it back as ticks(). So that I could change to the cheap and cheerful microsecond only resolution and have it still work.
Agree, for sure.
I suspect maybe I could if I had access to a private constructor of yours
explicit time_duration(tick_type ticks) : date_time::time_duration
(ticks) {} but obviously this is Not For Me. So I suspect that I am missing something.
I'm not sure you are missing something, but perhaps the library is. This constructor is private because I've seen too many errors in the past with programmers using the raw tick counts.
3. Furthermore, I have a suspicion that my technique is all wrong, and that somewhere there is a Much Better Way which the libaray anticipates. Let me set out my ideal, as a punter, merrily ignoring
It might be that you have found something that the library hasn't anticipated.
the constraints of real life. I would like to see (say) methods of the ptime class, floor() and ceil(), that worked like this
ptime t1(date(2002,Jan,10), time_duration(5,27,31)); // t1 is 2002/01/10 05:27:31
ptime t2(t1.floor(minutes(5)); // t2 is 2002/01/10 05:25:00 // ie previous five minute boundary
ptime t3(t1.ceil(seconds(10)); // t3 is 2002/01/10 05:27:40 // ie next 10 second boundary
I like the idea. What if we called them round_up and round_down instead? I don't have time to do anything with this today, but I can probably add this in the next few days. BTW, I have written a 'multi-precision' time point based on ptime for another user that keeps track of whether the ptime actually represents a day, minute, second, etc. This might be another approach to this problem.
I would like this to work from multiples of days down to multiples of nanoseconds. I am prepared to specify an origin - eg 1/1/1970 - as a second parameter which usually defaults, and I certainly do not wish to be tripped up by the scary sounding leap seconds that you mention in your docs.
Don't want much, do I? :-) But it's a bit similar to the algorithm stuff you do with dates, so I thought it might be in there somewhere.
I'm not sure what you are asking for here...
FYI the Change History document 'Changes.html' for Date/Time is missing from both the Boost website and the archived docs, and the
Yes, this just got patched on the website.
typo 'tommorrow' for 'tomorrow' has snuck in as a variable name in various example programs - see Google for details. C++ programming is beyond me, but proof reading I can do <g>
Thanks, I'll put these on the todo fix list. Jeff
In article
LONGLONG res = 1548000000000; LONGLONG otherres = nanosec(res).ticks(); if (otherres != res) TRACE("Eeek\n"); // Send to debug window
puts "Eeek" on my debug console. So nanosec() does not work as the inverse of ticks(). (Perhaps it takes a long?) So having done arithmetic on a value obtained from ticks(), how should I be poking it back in?
I'm suprised by this -- I think it should work.
Well for the record this is with MS VC6 and according to the debugger, otherres contains 1811773440 afterwards. Or to express that in another way res = 0x000001686bfd7800 otherres = 0x000000006bfd7800 which is rather suggestive, is it not? Treacherous chaps, integer types.
I like the idea. What if we called them round_up and round_down instead?
In the circs, I think I can see my way to allowing you to name your own library. <g> Seriously - if you think you can do anything soon, that would be fab. I undertake to put it into this 'ere app and stress it a bit.
BTW, I have written a 'multi-precision' time point based on ptime for another user that keeps track of whether the ptime actually represents a day, minute, second, etc. This might be another approach to this problem.
Whatever you think is best.
I would like this to work from multiples of days down to multiples of nanoseconds. I am prepared to specify an origin - eg 1/1/1970 - as a second parameter which usually defaults, and I certainly do not wish to be tripped up by the scary sounding leap seconds that you mention in your docs.
Don't want much, do I? :-) But it's a bit similar to the algorithm stuff you do with dates, so I thought it might be in there somewhere.
I'm not sure what you are asking for here...
When you round, you must be doing so with respect to some basetime, which is 0. This is your choice not mine. So that if I ask for ptime t2(t1.round_down(hours(24 * 7)); then t2 will always turn out to be a Wednesday (or whatever it happens to be) because your time zero happens to be a Wednesday. I should like always to get a Thursday, because I am a member of TheWeekBeginsOnThursday cult. So I'm suggesting there be an optional second parameter, or an overloaded version, where one can specify one's own date as a base ptime MyBeginningOfTime; // Intitalised to some a Sunday long ago ptime t2(t1.round_down(hours(24 * 7), MyBeginningOfTime); Or if I wanted the time of the most recent log entry since blast off, where log entries are made at 30 second intervals of elapsed time from blast off ptime BlastOff; ptime l(second_clock::universal_time().round_down(seconds(30), BlastOff); Of course, there are other ways of doing this stuff by fiddling with the result. If you say it is over-egging the pudding, I'm not arguing. It just occurred to me that once you start in on this kind of arithmetic, it would be jolly lovely to keep it all in the library and out of my face. Will
In article
So I'm suggesting there be an optional second parameter, or an overloaded version, where one can specify one's own date as a base
ptime MyBeginningOfTime; // Intitalised to some a Sunday long ago
Ooops I meant
ptime MyBeginningOfTime; // Intitalised to some *Thursday*
Will
participants (3)
-
Jeff Garland
-
Will Watts
-
willw_at_ais