openPilotLog
time.h
1 /*
2  *openPilotLog - A FOSS Pilot Logbook Application
3  *Copyright (C) 2020-2022 Felix Turowsky
4  *
5  *This program is free software: you can redistribute it and/or modify
6  *it under the terms of the GNU General Public License as published by
7  *the Free Software Foundation, either version 3 of the License, or
8  *(at your option) any later version.
9  *
10  *This program is distributed in the hope that it will be useful,
11  *but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  *GNU General Public License for more details.
14  *
15  *You should have received a copy of the GNU General Public License
16  *along with this program. If not, see <https://www.gnu.org/licenses/>.
17  */
18 #ifndef TIME_H
19 #define TIME_H
20 
21 #include <QtCore>
22 #include <QTime>
23 #include "src/opl.h"
24 
25 namespace OPL::Time {
26 
30 inline const QString toString(const QTime &time, OPL::FlightTimeFormat format = OPL::FlightTimeFormat::Default)
31 {
32  switch (format) {
33  case OPL::FlightTimeFormat::Default:
34  return time.toString(QStringLiteral("hh:mm"));
35  break;
36  case OPL::FlightTimeFormat::Decimal:
37  return QString::number(((time.hour() * 60 + time.minute() )/60.0), 'f', 2);
38  break;
39  default:
40  return QString();
41  }
42 }
43 
47 inline const QString toString(int minutes_in, OPL::FlightTimeFormat format = OPL::FlightTimeFormat::Default)
48 {
49  switch (format) {
50  case OPL::FlightTimeFormat::Default:
51  {
52  QString hour = QString::number(minutes_in / 60);
53  if (hour.size() < 2) {
54  hour.prepend(QStringLiteral("0"));
55  }
56  QString minute = QString::number(minutes_in % 60);
57  if (minute.size() < 2) {
58  minute.prepend(QStringLiteral("0"));
59  }
60  return hour + ':' + minute;
61  }
62  case OPL::FlightTimeFormat::Decimal:
63  {
64  int hour = minutes_in / 60;
65  double minute = (minutes_in % 60) / 60.0;
66  return QString::number((hour + minute), 'f', 2);
67  }
68  default:
69  return QString();
70  }
71 
72 }
73 
74 inline double toDecimalHours(const QTime &time){
75  return (time.hour() * 60 + time.minute()) / 60.0;
76 }
77 
78 inline QTime qTimefromMinutes(int total_minutes)
79 {
80  int minute = total_minutes % 60;
81  int hour = total_minutes / 60;
82 
83  return QTime(hour, minute, 0);
84 }
85 
86 inline const QTime fromString(QString time_string, OPL::FlightTimeFormat format = OPL::FlightTimeFormat::Default)
87 {
88  switch (format) {
89  case OPL::FlightTimeFormat::Default:
90  return QTime::fromString(time_string, QStringLiteral("hh:mm"));
91  break;
92  case OPL::FlightTimeFormat::Decimal:
93  {
94  double decimal_time = time_string.toDouble();
95  int hour = decimal_time;
96  int minute = round((decimal_time - hour) * 60);
97  return QTime(hour, minute, 0);
98  break;
99  }
100  default:
101  return QTime();
102  }
103 }
104 
105 inline const QTime fromString(const char* time_string, OPL::FlightTimeFormat format = OPL::FlightTimeFormat::Default)
106 {
107  switch (format) {
108  case OPL::FlightTimeFormat::Default:
109  return QTime::fromString(time_string, QStringLiteral("hh:mm"));
110  break;
111  case OPL::FlightTimeFormat::Decimal:
112  {
113  double decimal_time = QString(time_string).toDouble();
114  int hour = decimal_time;
115  int minute = round((decimal_time - hour) * 60);
116  return QTime(hour, minute, 0);
117  break;
118  }
119  default:
120  return QTime();
121  }
122 }
123 
124 inline int toMinutes(const QTime &time) {return time.hour() * 60 + time.minute();}
125 inline int toMinutes(const QString &time_string) {return toMinutes(fromString(time_string));}
126 
127 inline QTime blocktime(const QTime &tofb, const QTime &tonb)
128 {
129  QTime blocktime_out(0, 0); // initialise return value at midnight
130 
131  if (tonb > tofb) { // landing same day
132  int block_seconds = tofb.secsTo(tonb);
133  blocktime_out = blocktime_out.addSecs(block_seconds);
134  } else { // landing next day
135  QTime midnight(0, 0);
136  int seconds = tofb.secsTo(midnight);
137  blocktime_out = blocktime_out.addSecs(seconds);
138  seconds = midnight.secsTo(tonb);
139  blocktime_out = blocktime_out.addSecs(seconds);
140  }
141  return blocktime_out;
142 }
143 
144 inline QTime blocktime(const QString& tofb, const QString& tonb)
145 {
146  QTime t_tofb = OPL::Time::fromString(tofb);
147  QTime t_tonb = OPL::Time::fromString(tonb);
148  return blocktime(t_tofb, t_tonb);
149 }
150 
155 inline int blockMinutes(const QString& tofb, const QString& tonb)
156 {
157  const QTime t_tofb = OPL::Time::fromString(tofb);
158  const QTime t_tonb = OPL::Time::fromString(tonb);
159  if (t_tofb.isValid() && t_tonb.isValid()) {
160  const auto tblk = OPL::Time::blocktime(t_tofb, t_tonb);
161  return OPL::Time::toMinutes(tblk);
162  } else
163  return 0;
164 }
165 
170 inline int blockMinutes(const QTime& tofb, const QTime& tonb)
171 {
172  if (tofb.isValid() && tonb.isValid()) {
173  const auto tblk = OPL::Time::blocktime(tofb, tonb);
174  return OPL::Time::toMinutes(tblk);
175  } else
176  return 0;
177 }
178 
186 inline const QString formatTimeInput(QString user_input)
187 {
188  QTime temp_time; //empty time object is invalid by default
189 
190  bool contains_seperator = user_input.contains(':');
191  if (user_input.length() == 4 && !contains_seperator) {
192  temp_time = QTime::fromString(user_input, QStringLiteral("hhmm"));
193  } else if (user_input.length() == 3 && !contains_seperator) {
194  if (user_input.toInt() < 240) { //Qtime is invalid if time is between 000 and 240 for this case
195  QString tempstring = user_input.prepend(QStringLiteral("0"));
196  temp_time = QTime::fromString(tempstring, QStringLiteral("hhmm"));
197  } else {
198  temp_time = QTime::fromString(user_input, QStringLiteral("Hmm"));
199  }
200  } else if (user_input.length() == 4 && contains_seperator) {
201  temp_time = QTime::fromString(user_input, QStringLiteral("h:mm"));
202  } else if (user_input.length() == 5 && contains_seperator) {
203  temp_time = QTime::fromString(user_input, QStringLiteral("hh:mm"));
204  }
205 
206  auto output = temp_time.toString(QStringLiteral("hh:mm"));
207 
208  if (output.isEmpty()) {
209  DEB << "Time input is invalid.";
210  }
211  return output;
212 }
213 
214 } // namespace OPL::Time
215 
216 #endif // TIME_H
QString formatTimeInput(QString user_input)
OPL::Calc::formatTimeInput verifies user input and formats to hh:mm if the output is not a valid time...
Definition: calc.cpp:31