14 #include <qdatetime.h>
20 static const double msecs[] =
26 24.0 * 3600.0 * 1000.0,
27 7.0 * 24.0 * 3600.0 * 1000.0,
28 30.0 * 24.0 * 3600.0 * 1000.0,
29 365.0 * 24.0 * 3600.0 * 1000.0,
32 if ( type < 0 || type >=
static_cast< int >(
sizeof( msecs ) /
sizeof( msecs[0] ) ) )
39 double value,
double stepSize,
bool up )
41 double d = value / stepSize;
42 d = up ? std::ceil(
d ) : std::floor(
d );
44 return static_cast< int >(
d * stepSize );
50 switch( intervalType )
54 const double secsTo = minDate.secsTo( maxDate );
55 const double msecs = maxDate.time().msec() -
56 minDate.time().msec();
58 return secsTo * 1000 + msecs;
62 return minDate.secsTo( maxDate );
66 const double secsTo = minDate.secsTo( maxDate );
67 return std::floor( secsTo / 60 );
71 const double secsTo = minDate.secsTo( maxDate );
72 return std::floor( secsTo / 3600 );
76 return minDate.daysTo( maxDate );
80 return std::floor( minDate.daysTo( maxDate ) / 7.0 );
85 double( maxDate.date().year() ) - minDate.date().year();
87 int months = maxDate.date().month() - minDate.date().month();
88 if ( maxDate.date().day() < minDate.date().day() )
91 return years * 12 + months;
96 double( maxDate.date().year() ) - minDate.date().year();
98 if ( maxDate.date().month() < minDate.date().month() )
109 const QDateTime& minDate,
const QDateTime& maxDate,
113 const QDateTime maxD =
QwtDate::ceil( maxDate, intervalType );
119 const int limits[],
size_t numLimits )
121 for ( uint i = 0; i < numLimits; i++ )
123 const int numSteps = intervalSize / limits[ i ];
125 if ( numSteps > 1 && numSteps <= maxSteps &&
126 numSteps * limits[ i ] == intervalSize )
135 static int qwtStepSize(
int intervalSize,
int maxSteps, uint base )
142 for (
int numSteps = maxSteps; numSteps > 1; numSteps-- )
144 const double stepSize = double( intervalSize ) / numSteps;
146 const double p = std::floor( std::log( stepSize ) / std::log(
double( base ) ) );
147 const double fraction = std::pow( base, p );
149 for ( uint n = base; n >= 1; n /= 2 )
151 if ( qFuzzyCompare( stepSize, n * fraction ) )
152 return qRound( stepSize );
154 if ( n == 3 && ( base % 2 ) == 0 )
156 if ( qFuzzyCompare( stepSize, 2 * fraction ) )
157 return qRound( stepSize );
167 const int limits[],
size_t numLimits )
169 const int v =
qwtCeil( intervalSize /
double( numSteps ) );
171 for ( uint i = 0; i < numLimits - 1; i++ )
173 if ( v <= limits[i] )
177 return limits[ numLimits - 1 ];
185 if ( ( intervalSize > numSteps ) &&
186 ( intervalSize <= 2 * numSteps ) )
194 switch( intervalType )
199 static int limits[] = { 1, 2, 5, 10, 15, 20, 30, 60 };
202 limits,
sizeof( limits ) /
sizeof(
int ) );
208 static int limits[] = { 1, 2, 3, 4, 6, 12, 24 };
211 limits,
sizeof( limits ) /
sizeof(
int ) );
217 const double v = intervalSize / double( numSteps );
219 stepSize = std::ceil( v );
221 stepSize = std::ceil( v / 7 ) * 7;
227 static int limits[] = { 1, 2, 4, 8, 12, 26, 52 };
230 limits,
sizeof( limits ) /
sizeof(
int ) );
236 static int limits[] = { 1, 2, 3, 4, 6, 12 };
239 limits,
sizeof( limits ) /
sizeof(
int ) );
248 intervalSize, numSteps, 10 );
258 double minStepSize = 0.0;
260 switch( intervalType )
264 minStepSize =
qwtStepSize( stepSize, maxMinSteps, 10 );
265 if ( minStepSize == 0.0 )
266 minStepSize = 0.5 * stepSize;
272 static int limits[] = { 1, 2, 5, 10, 15, 20, 30, 60 };
276 if ( stepSize > maxMinSteps )
279 limits,
sizeof( limits ) /
sizeof(
int ) );
285 limits,
sizeof( limits ) /
sizeof(
int ) );
289 minStepSize = stepSize / numSteps;
297 if ( stepSize > maxMinSteps )
299 static int limits[] = { 1, 2, 3, 4, 6, 12, 24, 48, 72 };
302 limits,
sizeof( limits ) /
sizeof(
int ) );
306 static int limits[] = { 1, 2, 5, 10, 15, 20, 30, 60 };
309 limits,
sizeof( limits ) /
sizeof(
int ) );
313 minStepSize = stepSize / numSteps;
321 if ( stepSize > maxMinSteps )
323 static int limits[] = { 1, 2, 3, 7, 14, 28 };
326 limits,
sizeof( limits ) /
sizeof(
int ) );
330 static int limits[] = { 1, 2, 3, 4, 6, 12, 24, 48, 72 };
333 limits,
sizeof( limits ) /
sizeof(
int ) );
337 minStepSize = stepSize / numSteps;
343 const int daysInStep = stepSize * 7;
345 if ( maxMinSteps >= daysInStep )
348 minStepSize = 1.0 / 7.0;
355 const int stepSizeInWeeks = stepSize;
357 if ( stepSizeInWeeks <= maxMinSteps )
364 stepSizeInWeeks, maxMinSteps, 10 );
373 if ( stepSize < maxMinSteps )
374 maxMinSteps =
static_cast< int >( stepSize );
376 static int limits[] = { 1, 2, 3, 4, 6, 12 };
379 limits,
sizeof( limits ) /
sizeof(
int ) );
382 minStepSize = stepSize / numSteps;
388 if ( stepSize >= maxMinSteps )
391 stepSize, maxMinSteps, 10 );
397 static int limits[] = { 1, 2, 3, 4, 6, 12 };
399 int numSteps =
qwtStepCount( 12 * stepSize, maxMinSteps,
400 limits,
sizeof( limits ) /
sizeof(
int ) );
403 minStepSize = stepSize / numSteps;
413 && minStepSize == 0.0 )
415 minStepSize = 0.5 * stepSize;
422 int secondsMajor,
int secondsMinor )
424 if ( secondsMinor <= 0 )
427 QDateTime minDate = dateTime.addSecs( -secondsMajor );
435 while ( minDate < dateTime &&
438 minDate = minDate.addSecs( 3600 );
439 dstMin += 3600 * 1000.0;
443 ticks.reserve( 3600 / secondsMinor);
445 for (
int i = 0; i < 3600; i += secondsMinor )
446 ticks += dstMin + i * 1000.0;
452 const QDateTime& minDate,
const QDateTime& maxDate,
453 double stepSize,
int maxMinSteps,
457 double minStepSize = 0;
459 if ( maxMinSteps > 1 )
462 maxMinSteps, intervalType );
465 bool daylightSaving =
false;
466 if ( minDate.timeSpec() == Qt::LocalTime )
471 daylightSaving = stepSize > 1;
476 const int secondsMajor =
static_cast< int >( stepSize *
s );
477 const double secondsMinor = minStepSize *
s;
490 for ( QDateTime dt = minDate; dt <= maxDate;
491 dt = dt.addSecs( secondsMajor ) )
498 if ( daylightSaving )
501 majorValue += offset * 1000.0;
503 if ( offset > dstOff )
508 dt, secondsMajor, qRound( secondsMinor ) );
514 if ( majorTicks.isEmpty() || majorTicks.last() != majorValue )
515 majorTicks += majorValue;
517 if ( secondsMinor > 0.0 )
519 const int numMinorSteps =
qwtFloor( secondsMajor / secondsMinor );
521 for (
int i = 1; i < numMinorSteps; i++ )
523 const QDateTime mt = dt.addMSecs(
524 qRound64( i * secondsMinor * 1000 ) );
527 if ( daylightSaving )
530 minorValue += offset * 1000.0;
533 if ( minorTicks.isEmpty() || minorTicks.last() != minorValue )
535 const bool isMedium = ( numMinorSteps % 2 == 0 )
536 && ( i != 1 ) && ( i == numMinorSteps / 2 );
539 mediumTicks += minorValue;
541 minorTicks += minorValue;
560 QDateTime& minDate,
const QDateTime& maxDate,
561 double stepSize,
int maxMinSteps )
568 int minStepSize = 0.0;
570 if ( maxMinSteps > 1 )
574 if ( maxMinSteps >= 30 )
576 else if ( maxMinSteps >= 6 )
578 else if ( maxMinSteps >= 3 )
594 for ( QDateTime dt = minDate;
595 dt <= maxDate; dt = dt.addMonths( stepSize ) )
602 if ( minStepDays > 0 )
604 for (
int days = minStepDays;
605 days < 30; days += minStepDays )
609 if ( days == 15 && minStepDays != 15 )
615 else if ( minStepSize > 0.0 )
617 const int numMinorSteps = qRound( stepSize / (
double) minStepSize );
619 for (
int i = 1; i < numMinorSteps; i++ )
621 const double minorValue =
624 if ( ( numMinorSteps % 2 == 0 ) && ( i == numMinorSteps / 2 ) )
625 mediumTicks += minorValue;
627 minorTicks += minorValue;
644 const QDateTime& minDate,
const QDateTime& maxDate,
645 double stepSize,
int maxMinSteps )
651 double minStepSize = 0.0;
653 if ( maxMinSteps > 1 )
659 int numMinorSteps = 0;
660 if ( minStepSize > 0.0 )
661 numMinorSteps =
qwtFloor( stepSize / minStepSize );
663 bool dateBC = minDate.date().year() < -1;
665 for ( QDateTime dt = minDate; dt <= maxDate;
666 dt = dt.addYears( stepSize ) )
668 if ( dateBC && dt.date().year() > 1 )
671 dt = dt.addYears( -1 );
680 for (
int i = 1; i < numMinorSteps; i++ )
684 const double years = qRound( i * minStepSize );
685 if ( years >= std::numeric_limits< int >::max() / 12 )
687 tickDate = dt.addYears( years );
691 tickDate = dt.addMonths( qRound( years * 12 ) );
694 const bool isMedium = ( numMinorSteps > 2 ) &&
695 ( numMinorSteps % 2 == 0 ) && ( i == numMinorSteps / 2 );
699 mediumTicks += minorValue;
701 minorTicks += minorValue;
870 const QDateTime& minDate,
const QDateTime& maxDate,
873 const double jdMin = minDate.date().toJulianDay();
874 const double jdMax = maxDate.date().toJulianDay();
876 if ( ( jdMax - jdMin ) / 365 > maxSteps )
880 if ( months > maxSteps * 6 )
888 if ( days > 4 * maxSteps * 7 )
892 if ( days > maxSteps * 7 )
896 if ( hours > maxSteps * 24 )
901 if ( seconds >= maxSteps * 3600 )
904 if ( seconds >= maxSteps * 60 )
907 if ( seconds >= maxSteps )
930 double& x1,
double& x2,
double& stepSize )
const
946 if ( interval.
width() == 0.0 )
952 if ( from.isValid() && to.isValid() )
954 if ( maxNumSteps < 1 )
962 const double stepWidth =
qwtDivideScale( width, maxNumSteps, intvType );
965 const QDateTime d1 =
alignDate( from, stepWidth, intvType,
false );
966 const QDateTime d2 =
alignDate( to, stepWidth, intvType,
true );
981 stepSize = -stepSize;
997 int maxMajorSteps,
int maxMinorSteps,
double stepSize )
const
999 if ( maxMajorSteps < 1 )
1002 const double min =
qwtMinF( x1, x2 );
1003 const double max =
qwtMaxF( x1, x2 );
1011 stepSize = qAbs( stepSize );
1012 if ( stepSize > 0.0 )
1018 maxMajorSteps =
qwtCeil( ( max - min ) / stepSize );
1030 maxMajorSteps, maxMinorSteps, stepSize );
1038 maxMajorSteps, maxMinorSteps, intvType );
1043 scaleDiv = scaleDiv.
bounded( min, max );
1053 const QDateTime& minDate,
const QDateTime& maxDate,
1054 int maxMajorSteps,
int maxMinorSteps,
1064 if ( !dt0.isValid() )
1083 stepSize, maxMinorSteps );
1088 stepSize, maxMinorSteps );
1113 const QDateTime& dateTime,
double stepSize,
1118 QDateTime dt = dateTime;
1120 if ( dateTime.timeSpec() == Qt::OffsetFromUTC )
1122 #if QT_VERSION >= 0x050200
1123 dt.setOffsetFromUtc( 0 );
1125 dt.setUtcOffset( 0 );
1134 dt.time().msec(), stepSize, up );
1137 dt = dt.addMSecs( ms );
1143 int second = dt.time().second();
1146 if ( dt.time().msec() > 0 )
1153 dt = dt.addSecs(
s );
1159 int minute = dt.time().minute();
1162 if ( dt.time().msec() > 0 || dt.time().second() > 0 )
1169 dt = dt.addSecs( m * 60 );
1175 int hour = dt.time().hour();
1178 if ( dt.time().msec() > 0 || dt.time().second() > 0
1179 || dt.time().minute() > 0 )
1187 dt = dt.addSecs( h * 3600 );
1197 int day = dt.date().dayOfYear();
1200 if ( dt.time() > QTime( 0, 0 ) )
1207 dt = dt.addDays(
d - 1 );
1216 int numWeeks = date.daysTo( dt.date() ) / 7;
1219 if ( dt.time() > QTime( 0, 0 ) ||
1220 date.daysTo( dt.date() ) % 7 )
1230 dt = dt.addDays(
d );
1236 int month = dt.date().month();
1239 if ( dt.date().day() > 1 ||
1240 dt.time() > QTime( 0, 0 ) )
1249 dt = dt.addMonths( m );
1255 int year = dateTime.date().year();
1258 if ( dateTime.date().dayOfYear() > 1 ||
1259 dt.time() > QTime( 0, 0 ) )
1271 dt.setDate( QDate( stepSize, 1, 1 ).addYears( -stepSize ) );
1275 dt.setDate( QDate(
y, 1, 1 ) );
1282 if ( dateTime.timeSpec() == Qt::OffsetFromUTC )
1284 #if QT_VERSION >= 0x050200
1285 dt.setOffsetFromUtc( dateTime.offsetFromUtc() );
1287 dt.setUtcOffset( dateTime.utcOffset() );
1305 if ( !dt.isValid() )
1307 const QDate date = ( value <= 0.0 )
1316 #if QT_VERSION >= 0x050200