Routing and analysis engine for GTFS (General Transit Feed Specification) data
1#include "convert-time.h"
2
3#include <iostream>
4
5// ---------- Functions to convert start time: ----------
6
7bool time_is_hhmmss (const std::string &hms) // "HH:MM:SS"
8{
9 bool check = false;
10 if (hms.size () == 8 && std::count (hms.begin(), hms.end(), ':') == 2)
11 check = true;
12 return check;
13}
14
15bool time_is_hhmm (const std::string &hms) // "HH:MM"
16{
17 bool check = false;
18 if (hms.size () == 5 && std::count (hms.begin(), hms.end(), ':') == 1)
19 check = true;
20 return check;
21}
22
23bool time_is_lubridate (const std::string &hms)
24{
25 // stardard is HH:MM:SS
26 bool check = false;
27 if (std::count (hms.begin (), hms.end (), 'H') == 1 &&
28 std::count (hms.begin (), hms.end (), 'M') == 1 &&
29 std::count (hms.begin (), hms.end (), 'S') == 1)
30 check = true;
31 return check;
32}
33
34int convert_time_hhmmss (std::string hms)
35{
36 const std::string delim = ":";
37 unsigned int ipos = static_cast <unsigned int> (hms.find (delim.c_str ()));
38 std::string h = hms.substr (0, ipos), m, s;
39 hms = hms.substr (ipos + 1, hms.length () - ipos - 1);
40 if (hms.find (delim.c_str ()) != std::string::npos) // has seconds
41 {
42 ipos = static_cast <unsigned int> (hms.find (delim.c_str ()));
43 m = hms.substr (0, ipos);
44 s = hms.substr (ipos + 1, hms.length () - ipos - 1);
45 //} else // difftime objects always have seconds so this is not possible
46 //{
47 // m = hms;
48 // s = "00";
49 }
50 return 3600 * atoi (h.c_str ()) +
51 60 * atoi (m.c_str ()) +
52 atoi (s.c_str ());
53}
54
55int convert_time_hhmm (std::string hms)
56{
57 const std::string delim = ":";
58 unsigned int ipos = static_cast <unsigned int> (hms.find (delim.c_str ()));
59 std::string h = hms.substr (0, ipos), m, s;
60 hms = hms.substr (ipos + 1, hms.length () - ipos - 1);
61
62 return 3600 * atoi (h.c_str ()) +
63 60 * atoi (hms.c_str ());
64}
65
66// lubridate format is "00H 00M 00S"
67int convert_time_lubridate (std::string hms)
68{
69 unsigned int ipos = static_cast <unsigned int> (hms.find ("H"));
70 std::string h = hms.substr (0, ipos);
71 hms = hms.substr (ipos + 2, hms.length () - ipos - 1);
72 ipos = static_cast <unsigned int> (hms.find ("M"));
73 std::string m = hms.substr (0, ipos);
74 hms = hms.substr (ipos + 2, hms.length () - ipos - 1);
75 ipos = static_cast <unsigned int> (hms.find ("S"));
76 std::string s = hms.substr (0, ipos);
77 return 3600 * atoi (h.c_str ()) +
78 60 * atoi (m.c_str ()) +
79 atoi (s.c_str ());
80}
81
82//' rcpp_convert_time
83//'
84//' @noRd
85// [[Rcpp::export]]
86int rcpp_convert_time (const std::string &hms)
87{
88 int time;
89 std::string hms_cp = hms;
90
91 if (time_is_hhmmss (hms_cp))
92 time = convert_time_hhmmss (hms_cp);
93 else if (time_is_hhmm (hms_cp))
94 time = convert_time_hhmm (hms_cp);
95 else if (time_is_lubridate (hms_cp))
96 time = convert_time_lubridate (hms_cp);
97 else // already checked in R before passing to this fn
98 Rcpp::stop ("Unrecognized time format"); // # nocov
99
100 return time;
101}
102
103// ---------- Vector conversion of GTFS times: ----------
104
105int convert_time_to_seconds (std::string hms)
106{
107 const std::string delim = ":";
108 unsigned int ipos = static_cast <unsigned int> (hms.find (delim.c_str ()));
109 int h = atoi (hms.substr (0, ipos).c_str ());
110 hms = hms.substr (ipos + 1, hms.length () - ipos - 1);
111 ipos = static_cast <unsigned int> (hms.find (delim.c_str ()));
112 int m = atoi (hms.substr (0, ipos).c_str ());
113 int s = atoi (hms.substr (ipos + 1, hms.length ()).c_str ());
114
115 return 3600 * h + 60 * m + s;
116}
117
118//' rcpp_time_to_seconds
119//'
120//' Vectorize the above function
121//'
122//' @noRd
123// [[Rcpp::export]]
124Rcpp::IntegerVector rcpp_time_to_seconds (std::vector <std::string> times)
125{
126 Rcpp::IntegerVector res (times.size ());
127 for (size_t i = 0; i < times.size (); i++)
128 {
129 res (i) = convert_time_to_seconds (times [i]);
130 }
131 return res;
132}
133