ARTS  2.4.0(git:4fb77825)
artstime.cc
Go to the documentation of this file.
1 /* Copyright (C) 2020
2  * Richard Larsson <larsson@mps.mpg.de>
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License as published by the
6  * Free Software Foundation; either version 2, or (at your option) any
7  * later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
17  * USA. */
18 
27 #include <ctime>
28 #include <stdlib.h>
29 
30 #include "artstime.h"
31 
33 {
34  std::istringstream x(time_step);
35  Index length;
36  String type;
37  x >> length >> type;
38  type.tolower();
39 
40  if (type == "hour" or type == "hours" or type == "h")
41  return TimeStep(std::chrono::hours(length ));
42  else if (type == "minute" or type == "minutes" or type == "min")
43  return TimeStep(std::chrono::minutes(length));
44  else if (type == "second" or type == "seconds" or type == "s")
45  return TimeStep(std::chrono::seconds(length));
46  else
47  throw std::runtime_error("Bad time step definition");
48 }
49 
50 Time next_even(const Time& t, const TimeStep& dt)
51 {
52  auto dt_internal = std::chrono::duration_cast<Time::InternalTimeStep>(dt);
53 
54  if (dt_internal.count())
55  return t + dt_internal - t.EpochTime() % dt_internal;
56  else
57  return t;
58 }
59 
60 ArrayOfIndex time_steps(const ArrayOfTime& times, const String& step)
61 {
62  Index N = times.nelem();
63  if (N < 2) {
64  throw std::runtime_error("Can only find time steps for 2-long or longer time grids");
65  }
66 
67  auto dt = time_stepper_selection(step);
68  if (dt < decltype(dt)(0)) {
69  throw std::runtime_error("Must have positive time steps (or 0 for all times)");
70  }
71 
73 
74  if (N > 2) {
75  Time tupp = next_even(times[0], dt);
76  time_steps.push_back(1);
77 
78  for (; time_steps.back() < N; time_steps.back()++) {
79  if (not (times[time_steps.back()] < tupp)) {
80  tupp = next_even(tupp, dt);
81  time_steps.push_back(time_steps.back());
82  }
83  }
84  } else {
85  time_steps.push_back(N);
86  }
87  return time_steps;
88 }
89 
90 std::ostream& operator<<(std::ostream& os, const Time& t)
91 {
92  // FIXME: C++20 has much better calendar handling
93  std::tm x = t.toStruct();
94 
95  // Deal with seconds
96  char sec[2+1+9+100];
97  Numeric seconds = Numeric(x.tm_sec) + t.PartOfSecond();
98  sprintf(sec, "%.9lf", seconds);
99 
100  // Print based on std::tm specs
101  return os << 1900 + x.tm_year << '-' << std::setfill('0') << std::setw(2)
102  << 1 + x.tm_mon << '-' << std::setfill('0') << std::setw(2)
103  << x.tm_mday << ' ' << std::setfill('0') << std::setw(2)
104  << x.tm_hour << ':' << std::setfill('0') << std::setw(2)
105  << x.tm_min <<':' << std::setfill('0') << std::setw(12) << sec;
106 }
107 
108 std::istream& operator>>(std::istream& is, Time& t)
109 {
110  String ymd, hms;
111  is >> ymd >> hms;
112 
113  ArrayOfString YMD, HMS;
114  ymd.split(YMD, "-");
115  hms.split(HMS, ":");
116 
117  if (YMD.nelem() not_eq HMS.nelem() and YMD.nelem() not_eq 3)
118  throw std::runtime_error("Time stream must look like \"year-month-day hour:min:seconds\"");
119 
120  // FIXME: C++20 has much better calendar handling
121  std::tm x;
122  x.tm_year = std::stoi(YMD[0]) - 1900;
123  x.tm_mon = std::stoi(YMD[1]) - 1;
124  x.tm_mday = std::stoi(YMD[2]);
125  x.tm_hour = std::stoi(HMS[0]);
126  x.tm_min = std::stoi(HMS[1]);
127  x.tm_sec = 0;
128  x.tm_isdst = -1;
129 
130  t = Time(x) + TimeStep(std::stod(HMS[2]));
131 
132  return is;
133 }
134 
136 {
137  if (e == -1)
138  e = ts.nelem();
139  else if (e < 0 or e > ts.nelem())
140  throw std::runtime_error("Bad last index, valid options are [-1, ts.nelem()]");
141 
142  if (s < 0 or s > ts.nelem())
143  throw std::runtime_error("Bad first index, valid options are [0, ts.nelem()]");
144 
145  Time::InternalTimeStep dt(0);
146  for (Index i=s+1; i<e; i++)
147  dt += (ts[i] - ts[s]) / (e - s);
148  return ts[s] + dt;
149 }
150 
Time::PartOfSecond
Numeric PartOfSecond() const
Definition: artstime.h:77
TimeStep
std::chrono::duration< Numeric > TimeStep
A duration of time, 1 full tick should be 1 second.
Definition: artstime.h:37
time_steps
ArrayOfIndex time_steps(const ArrayOfTime &times, const String &step)
Finds the index matching demands in a list of times.
Definition: artstime.cc:60
time_stepper_selection
TimeStep time_stepper_selection(const String &time_step)
Definition: artstime.cc:32
operator<<
std::ostream & operator<<(std::ostream &os, const Time &t)
Output for Time.
Definition: artstime.cc:90
artstime.h
Stuff related to time in ARTS.
Array
This can be used to make arrays out of anything.
Definition: array.h:108
mean_time
Time mean_time(const ArrayOfTime &ts, Index s, Index e)
Computes the average time in a list.
Definition: artstime.cc:135
next_even
Time next_even(const Time &t, const TimeStep &dt)
Returns the next time after t with an even time-step.
Definition: artstime.cc:50
Time::EpochTime
InternalTimeStep EpochTime() const
Definition: artstime.h:63
my_basic_string< char >
operator>>
std::istream & operator>>(std::istream &is, Time &t)
Input for Time.
Definition: artstime.cc:108
Numeric
NUMERIC Numeric
The type to use for all floating point numbers.
Definition: matpack.h:33
Time::InternalTimeStep
decltype(mtime)::duration InternalTimeStep
Definition: artstime.h:45
my_basic_string::tolower
void tolower()
Convert to lower case.
Definition: mystring.h:85
my_basic_string::split
void split(Array< my_basic_string< charT > > &aos, const my_basic_string< charT > &delim) const
Split string into substrings.
Definition: mystring.h:206
N
#define N
Definition: rng.cc:164
Time
Class to handle time in ARTS.
Definition: artstime.h:40
ARTS::Group::Time
Time Time
Definition: autoarts.h:110
Time::toStruct
std::tm toStruct() const
Definition: artstime.h:60
ARTS::Var::x
Vector x(Workspace &ws) noexcept
Definition: autoarts.h:7346
Index
INDEX Index
The type to use for all integer numbers and indices.
Definition: matpack.h:39
Array::nelem
Index nelem() const
Number of elements.
Definition: array.h:195