ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
ERF_EpochTime.H File Reference
#include <string>
#include <sstream>
#include <iomanip>
#include <ctime>
#include <cctype>
Include dependency graph for ERF_EpochTime.H:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

AMREX_GPU_HOST AMREX_FORCE_INLINE bool parse_fixed_width_int (const char *&dt, int width, int &value)
 
AMREX_GPU_HOST AMREX_FORCE_INLINE std::time_t getEpochTime (const std::string &dateTime, const std::string &dateTimeFormat)
 
AMREX_FORCE_INLINE std::string getTimestamp (const amrex::Real epoch_real, const std::string &datetime_format, bool add_long_frac=true)
 

Function Documentation

◆ getEpochTime()

AMREX_GPU_HOST AMREX_FORCE_INLINE std::time_t getEpochTime ( const std::string &  dateTime,
const std::string &  dateTimeFormat 
)
35 {
36  std::tm tmTime{};
37  const char* dt = dateTime.c_str();
38  const char* fmt = dateTimeFormat.c_str();
39 
40  // Walk both the format string and the date string together
41  while (*fmt && *dt) {
42  if (*fmt == '%') {
43  ++fmt;
44  int parsed_value = 0;
45  switch (*fmt) {
46  case 'Y': // 4-digit year
47  if (!parse_fixed_width_int(dt, 4, parsed_value)) return -1;
48  tmTime.tm_year = parsed_value;
49  tmTime.tm_year -= 1900;
50  break;
51  case 'm': // 2-digit month
52  if (!parse_fixed_width_int(dt, 2, parsed_value)) return -1;
53  tmTime.tm_mon = parsed_value;
54  tmTime.tm_mon -= 1; // struct tm expects 0-11
55  break;
56  case 'd': // 2-digit day
57  if (!parse_fixed_width_int(dt, 2, parsed_value)) return -1;
58  tmTime.tm_mday = parsed_value;
59  break;
60  case 'H': // 2-digit hour
61  if (!parse_fixed_width_int(dt, 2, parsed_value)) return -1;
62  tmTime.tm_hour = parsed_value;
63  break;
64  case 'M': // 2-digit minute
65  if (!parse_fixed_width_int(dt, 2, parsed_value)) return -1;
66  tmTime.tm_min = parsed_value;
67  break;
68  case 'S': // 2-digit second
69  if (!parse_fixed_width_int(dt, 2, parsed_value)) return -1;
70  tmTime.tm_sec = parsed_value;
71  break;
72  default:
73  // Unsupported format specifier
74  return -1;
75  }
76  } else {
77  // Literal character, must match
78  if (*fmt != *dt) {
79  return -1; // mismatch
80  }
81  ++dt;
82  }
83  ++fmt;
84  }
85 
86  if (*fmt != '\0' || *dt != '\0') {
87  return -1;
88  }
89 
90  if (tmTime.tm_mon < 0 || tmTime.tm_mon > 11 ||
91  tmTime.tm_mday < 1 || tmTime.tm_mday > 31 ||
92  tmTime.tm_hour < 0 || tmTime.tm_hour > 23 ||
93  tmTime.tm_min < 0 || tmTime.tm_min > 59 ||
94  tmTime.tm_sec < 0 || tmTime.tm_sec > 60) {
95  return -1;
96  }
97 
98  return timegm(&tmTime);
99 }
AMREX_GPU_HOST AMREX_FORCE_INLINE bool parse_fixed_width_int(const char *&dt, int width, int &value)
Definition: ERF_EpochTime.H:16

Referenced by ERF::ReadParameters().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getTimestamp()

AMREX_FORCE_INLINE std::string getTimestamp ( const amrex::Real  epoch_real,
const std::string &  datetime_format,
bool  add_long_frac = true 
)
104 {
105  auto epoch_nearest_sec = static_cast<std::time_t>(epoch_real);
106  std::tm *time_info = std::gmtime(&epoch_nearest_sec);
107 
108  char buffer[80];
109  std::strftime(buffer, sizeof(buffer), datetime_format.c_str(), time_info);
110  std::string str_nearest_sec(buffer);
111 
112  if (add_long_frac) {
113  // We use abs here because the diff would come out as negative
114  // if the times themselves were negative
115  double frac_sec = std::abs(epoch_real - epoch_nearest_sec);
116  snprintf(buffer, 80, "%.6f", frac_sec);
117  AMREX_ASSERT(buffer[0] == '0');
118  std::string str_frac_sec(buffer);
119  return str_nearest_sec + str_frac_sec.substr(1);
120  } else {
121  return str_nearest_sec;
122  }
123 }

Referenced by ERF::Evolve(), ERF::Write3DPlotFile(), ERF::writeJobInfo(), and ERF::WriteSubvolume().

Here is the caller graph for this function:

◆ parse_fixed_width_int()

AMREX_GPU_HOST AMREX_FORCE_INLINE bool parse_fixed_width_int ( const char *&  dt,
int  width,
int &  value 
)
17 {
18  value = 0;
19 
20  for (int idx = 0; idx < width; ++idx) {
21  unsigned char ch = static_cast<unsigned char>(dt[idx]);
22  if (ch == '\0' || !std::isdigit(ch)) {
23  return false;
24  }
25  value = 10 * value + (dt[idx] - '0');
26  }
27 
28  dt += width;
29  return true;
30 }
amrex::Real value
Definition: ERF_HurricaneDiagnostics.H:20

Referenced by getEpochTime().

Here is the caller graph for this function: