Qt Virtual Chart Table (QVCT)
CUnitTime.cpp
Go to the documentation of this file.
1 // INDENTING (emacs/vi): -*- mode:c++; tab-width:2; c-basic-offset:2; intent-tabs-mode:nil; -*- ex: set tabstop=2 expandtab:
2 
3 /*
4  * Qt Virtual Chart Table (QVCT)
5  * Copyright (C) 2012 Cedric Dufour <http://cedric.dufour.name>
6  * Author: Cedric Dufour <http://cedric.dufour.name>
7  *
8  * The Qt Virtual Chart Table (QVCT) is free software:
9  * you can redistribute it and/or modify it under the terms of the GNU General
10  * Public License as published by the Free Software Foundation, Version 3.
11  *
12  * The Qt Virtual Chart Table (QVCT) is distributed in the hope
13  * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
14  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15  *
16  * See the GNU General Public License for more details.
17  */
18 
19 // C/C++
20 #include <cmath>
21 
22 // QT
23 #include <QDateTime>
24 #include <QMap>
25 #include <QRegExp>
26 #include <QString>
27 #include <QTime>
28 
29 // QVCT
30 #include "QVCTRuntime.hpp"
31 #include "units/CUnitTime.hpp"
32 
33 
34 //------------------------------------------------------------------------------
35 // CONSTANTS / STATIC
36 //------------------------------------------------------------------------------
37 
40 
41 const QMap<CUnitTime::EUnit,QString> &CUnitTime::symbols()
42 {
44 }
45 
47 {
48  return oUnitTimeSymbols.qMapSymbols.value( _eUnit, "?" );
49 }
50 
51 CUnitTime::EUnit CUnitTime::fromSymbol( const QString& _rqString )
52 {
53  return oUnitTimeSymbols.qMapSymbols.key( _rqString, UNDEFINED );
54 }
55 
56 const QMap<CUnitTime::EUnit,QString> &CUnitTime::codes()
57 {
59 }
60 
62 {
63  return oUnitTimeCodes.qMapCodes.value( _eUnit, "undef" );
64 }
65 
66 CUnitTime::EUnit CUnitTime::fromCode( const QString& _rqString )
67 {
68  return oUnitTimeCodes.qMapCodes.key( _rqString, UNDEFINED );
69 }
70 
71 double CUnitTime::toValue( double _fdValue, CUnitTimeZone::EUnit _eUnitTimeZone )
72 {
73  QDateTime __qDateTime = QDateTime::fromTime_t( _fdValue );
74  __qDateTime = __qDateTime.addMSecs( 1000.0*fmod( _fdValue, 1.0 ) + 0.5 );
75  QTime __qTime = _eUnitTimeZone == CUnitTimeZone::UTC ? __qDateTime.toUTC().time() : __qDateTime.toLocalTime().time();
76  return 3600.0*__qTime.hour() + 60.0*__qTime.minute() + __qTime.second() + __qTime.msec()/1000.0;
77 }
78 
79 QString CUnitTime::toString( double _fdValue, CUnitTimeZone::EUnit _eUnitTimeZone, CUnitTime::EUnit _eUnit, int _iPrecision )
80 {
81  QDateTime __qDateTime = QDateTime::fromTime_t( _fdValue );
82  __qDateTime = __qDateTime.addMSecs( 1000.0*fmod( _fdValue, 1.0 ) + 0.5 );
83  QTime __qTime = _eUnitTimeZone == CUnitTimeZone::UTC ? __qDateTime.toUTC().time() : __qDateTime.toLocalTime().time();
84  switch( _eUnit )
85  {
86 
87  case HMS:
88  {
89  int __iHour = __qTime.hour();
90  int __iMin = __qTime.minute();
91  double __fdSec = __qTime.second() + (double)__qTime.msec()/1000.0;
92  QString __qsSec = QString::number( __fdSec, 'f', _iPrecision ).prepend( "0" ).right( 2+( _iPrecision>0 ? _iPrecision+1 : 0 ) ); // WARNING: rounding-up may occur!
93  if( __qsSec[0] == '1' ) { __iMin += 1; __qsSec[0] = '0'; } // fix rounding-up
94  QString __qsMin = QString::number( __iMin ).prepend( "0" ).right( 2 );
95  if( __qsMin[0] == '6' ) { __iHour += 1; __qsMin[0] = '0'; } // fix rounding-up
96  QString __qsHour = QString::number( __iHour );
97  return __qsHour+":"+__qsMin+":"+__qsSec+( _eUnitTimeZone == CUnitTimeZone::UTC ? "Z" : "" );
98  }
99 
100  case HM:
101  {
102  int __iHour = __qTime.hour();
103  double __fdMin = __qTime.minute() + ( (double)__qTime.second() + (double)__qTime.msec()/1000.0 )/60.0;
104  QString __qsMin = QString::number( __fdMin, 'f', _iPrecision ).prepend( "0" ).right( 2+( _iPrecision>0 ? _iPrecision+1 : 0 ) ); // WARNING: rounding-up may occur!
105  if( __qsMin[0] == '6' ) { __iHour += 1; __qsMin[0] = '0'; } // fix rounding-up
106  QString __qsHour = QString::number( __iHour );
107  return __qsHour+":"+__qsMin+( _eUnitTimeZone == CUnitTimeZone::UTC ? "Z" : "" );
108  }
109 
110  default: return "?";
111  }
112 }
113 
114 QString CUnitTime::toString( double _fdValue, bool _bAlternateTimeZone )
115 {
116  CSettings* __poSettings = QVCTRuntime::useSettings();
117  CUnitTimeZone::EUnit __eUnitTimeZone = __poSettings->getUnitTimeZone();
118  if( _bAlternateTimeZone ) __eUnitTimeZone = ( __eUnitTimeZone == CUnitTimeZone::UTC ) ? CUnitTimeZone::LOCAL : CUnitTimeZone::UTC;
119  return toString( _fdValue, __eUnitTimeZone, __poSettings->getUnitTime(), __poSettings->getPrecisionTime() );
120 }
121 
122 double CUnitTime::fromString( const QString& _rqString, double _fdDate, CUnitTimeZone::EUnit _eUnitTimeZone, bool* _pbOK )
123 {
124  static const QRegExp __qRegExpHMS( "^\\s*(0?\\d|1\\d|2[0-3]):(0?\\d|[1-5]\\d):(0?\\d|[1-5]\\d)(\\.\\d+)?\\s*([ZzLl])?\\s*$" );
125  static const QRegExp __qRegExpHM( "^\\s*(0?\\d|1\\d|2[0-3]):((0?\\d|[1-5]\\d)(\\.\\d+)?)\\s*(ZzLl)?\\s*$" );
126 
127  if( _pbOK ) *_pbOK = false;
128  bool __bOK;
129  QDateTime __qDateTime;
130  __qDateTime.setTime_t( _fdDate );
131  if( __qRegExpHMS.exactMatch( _rqString ) )
132  {
133  CUnitTimeZone::EUnit __eUnitTimeZone = _eUnitTimeZone;
134  QString __qsTimeZone = __qRegExpHMS.cap(5).toUpper();
135  if( __qsTimeZone == "Z" ) __eUnitTimeZone = CUnitTimeZone::UTC;
136  else if( __qsTimeZone == "L" ) __eUnitTimeZone = CUnitTimeZone::LOCAL;
137  __qDateTime.setTimeSpec( __eUnitTimeZone == CUnitTimeZone::UTC ? Qt::UTC : Qt::LocalTime );
138  int __iHour = __qRegExpHMS.cap(1).toInt( &__bOK );
139  if( !__bOK ) return 0.0;
140  int __iMin = __qRegExpHMS.cap(2).toInt( &__bOK );
141  if( !__bOK ) return 0.0;
142  int __iSec = __qRegExpHMS.cap(3).toInt( &__bOK );
143  if( !__bOK ) return 0.0;
144  int __iMilli = 0;
145  if( !__qRegExpHMS.cap(4).isEmpty() )
146  {
147  __iMilli = 1000*__qRegExpHMS.cap(4).toDouble( &__bOK );
148  if( !__bOK ) return 0.0;
149  }
150  __qDateTime.setTime( QTime( __iHour, __iMin, __iSec, __iMilli ) );
151  }
152  else if( __qRegExpHM.exactMatch( _rqString ) )
153  {
154  CUnitTimeZone::EUnit __eUnitTimeZone = _eUnitTimeZone;
155  QString __qsTimeZone = __qRegExpHM.cap(5).toUpper();
156  if( __qsTimeZone == "Z" ) __eUnitTimeZone = CUnitTimeZone::UTC;
157  else if( __qsTimeZone == "L" ) __eUnitTimeZone = CUnitTimeZone::LOCAL;
158  __qDateTime.setTimeSpec( __eUnitTimeZone == CUnitTimeZone::UTC ? Qt::UTC : Qt::LocalTime );
159  int __iHour = __qRegExpHM.cap(1).toInt( &__bOK );
160  if( !__bOK ) return 0.0;
161  double __fdMin = __qRegExpHM.cap(2).toDouble( &__bOK );
162  if( !__bOK ) return 0.0;
163  double __fdSec = modf( __fdMin, &__fdMin ) * 60.0;
164  int __iMin = (int)__fdMin;
165  int __iMilli = (int)( modf( __fdSec, &__fdSec )*1000.0 ); // WARNING: rounding-up may occur!
166  int __iSec = (int)__fdSec;
167  if( __iMilli >= 1000 ) { __iMilli -= 1000; __iSec += 1; } // fix rounding-up
168  if( __iSec >= 60 ) { __iSec -= 60; __iMin += 1; } // fix rounding-up
169  if( __iMin >= 60 ) { __iMin -= 60; __iHour += 1; } // fix rounding-up
170  __qDateTime.setTime( QTime( __iHour, __iMin, __iSec, __iMilli ) );
171  }
172  else return 0.0;
173  if( _pbOK ) *_pbOK = true;
174  return( (double)__qDateTime.toTime_t() + (double)__qDateTime.time().msec()/1000.0 );
175 }
176 
177 double CUnitTime::fromString( const QString& _rqString, double _fdDate, bool* _pbOK )
178 {
179  CSettings* __poSettings = QVCTRuntime::useSettings();
180  return fromString( _rqString, _fdDate, __poSettings->getUnitTimeZone(), _pbOK );
181 }
[UI] Container for the application's settings
Definition: CSettings.hpp:51
CUnitTime::EUnit getUnitTime()
[Unit] Returns the time format/unit
Definition: CSettings.hpp:341
int getPrecisionTime()
[Precision] Returns the time decimal precision
Definition: CSettings.hpp:360
CUnitTimeZone::EUnit getUnitTimeZone()
[Unit] Returns the timezone format/unit
Definition: CSettings.hpp:345
Container class for supported machine-friendly format/unit codes.
Definition: CUnitTime.hpp:115
QMap< CUnitTime::EUnit, QString > qMapCodes
Definition: CUnitTime.hpp:127
Container class for supported human-readable format/unit symbols.
Definition: CUnitTime.hpp:97
QMap< CUnitTime::EUnit, QString > qMapSymbols
Definition: CUnitTime.hpp:109
EUnit
Format/unit ID.
@ LOCAL
Local Time.
@ UTC
Universal Time Coordinates.
static double fromString(const QString &_rqString, double _fdDate, CUnitTimeZone::EUnit _eUnitTimeZone, bool *_pbOK=0)
Returns the numeric value corresponding (parsed) from the string.
Definition: CUnitTime.cpp:122
static QString toString(double _fdValue, CUnitTimeZone::EUnit _eUnitTimeZone, EUnit _eUnit, int _iPrecision=0)
Returns the formatted represention of the given value, using the specified format/unit and decimal pr...
Definition: CUnitTime.cpp:79
static const CUnitTimeCodes oUnitTimeCodes
Container for supported machine-friendly format/unit codes.
Definition: CUnitTime.hpp:57
EUnit
Format/unit ID.
Definition: CUnitTime.hpp:47
@ UNDEFINED
undefined format/unit
Definition: CUnitTime.hpp:50
@ HM
HH:MM.
Definition: CUnitTime.hpp:49
@ HMS
HH:MM:SS.
Definition: CUnitTime.hpp:48
static EUnit fromSymbol(const QString &_rqsSymbol)
Returns the format/unit ID corresponding to the given human-readable symbol.
Definition: CUnitTime.cpp:51
static const CUnitTimeSymbols oUnitTimeSymbols
Container for supported human-readable format/unit symbols.
Definition: CUnitTime.hpp:55
static const QMap< EUnit, QString > & codes()
Returns the list of supported machine-friendly format/unit codes.
Definition: CUnitTime.cpp:56
static QString toSymbol(EUnit _eUnit)
Returns the human-readable symbol corresponding to the given format/unit ID.
Definition: CUnitTime.cpp:46
static const QMap< EUnit, QString > & symbols()
Returns the list of supported human-readable format/unit symbols.
Definition: CUnitTime.cpp:41
static EUnit fromCode(const QString &_rqsCode)
Returns the format/unit ID corresponding to the given machine-friendly code.
Definition: CUnitTime.cpp:66
static QString toCode(EUnit _eUnit)
Returns the machine-friendly code corresponding to the given format/unit ID.
Definition: CUnitTime.cpp:61
static double toValue(double _fdValue, CUnitTimeZone::EUnit _eUnitTimeZone)
Returns the converted value, using the specified format/unit.
Definition: CUnitTime.cpp:71
static CSettings * useSettings()