Rcpp Version 1.0.9
Datetime.h
Go to the documentation of this file.
1 // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*-
2 //
3 // Datetime.h: Rcpp R/C++ interface class library -- Datetime (POSIXct)
4 //
5 // Copyright (C) 2010 - 2016 Dirk Eddelbuettel and Romain Francois
6 //
7 // This file is part of Rcpp.
8 //
9 // Rcpp is free software: you can redistribute it and/or modify it
10 // under the terms of the GNU General Public License as published by
11 // the Free Software Foundation, either version 2 of the License, or
12 // (at your option) any later version.
13 //
14 // Rcpp is distributed in the hope that it will be useful, but
15 // WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 // GNU General Public License for more details.
18 //
19 // You should have received a copy of the GNU General Public License
20 // along with Rcpp. If not, see <http://www.gnu.org/licenses/>.
21 
22 #ifndef Rcpp__Datetime_h
23 #define Rcpp__Datetime_h
24 
25 #include <RcppCommon.h>
26 
27 #if defined(WIN32) || defined(__WIN32) || defined(__WIN32__)
28 #include <time.h>
29 #endif
30 
31 namespace Rcpp {
32 
33  class Datetime {
34  public:
36  m_dt = 0;
37  update_tm();
38  }
39  Datetime(SEXP s);
40 
41  // from double, just like POSIXct
42  Datetime(const double &dt) {
43  m_dt = dt;
44  update_tm();
45  }
46  Datetime(const std::string &s, const std::string &fmt="%Y-%m-%d %H:%M:%OS");
47 
48  double getFractionalTimestamp(void) const { return m_dt; }
49 
50  int getMicroSeconds() const { return m_us; }
51  int getSeconds() const { return m_tm.tm_sec; }
52  int getMinutes() const { return m_tm.tm_min; }
53  int getHours() const { return m_tm.tm_hour; }
54  int getDay() const { return m_tm.tm_mday; }
55  int getMonth() const { return m_tm.tm_mon + 1; } // makes it 1 .. 12
56  int getYear() const { return m_tm.tm_year ; }
57  int getWeekday() const { return m_tm.tm_wday + 1; } // makes it 1 .. 7
58  int getYearday() const { return m_tm.tm_yday + 1; } // makes it 1 .. 366
59 
60  // Minimal set of date operations.
61  friend Datetime operator+( const Datetime &dt, double offset);
62  friend Datetime operator+( const Datetime &dt, int offset);
63  friend double operator-( const Datetime &dt1, const Datetime& dt2);
64  friend bool operator<( const Datetime &dt1, const Datetime& dt2);
65  friend bool operator>( const Datetime &dt1, const Datetime& dt2);
66  friend bool operator==(const Datetime &dt1, const Datetime& dt2);
67  friend bool operator>=(const Datetime &dt1, const Datetime& dt2);
68  friend bool operator<=(const Datetime &dt1, const Datetime& dt2);
69  friend bool operator!=(const Datetime &dt1, const Datetime& dt2);
70 
71  inline int is_na() const { return traits::is_na<REALSXP>(m_dt); }
72 
73  operator double() const { return m_dt; }
74 
75  inline std::string format(const char *fmt = "%Y-%m-%d %H:%M:%S") const {
76  char txtiso[64], txtsec[64];
77  time_t t = static_cast<time_t>(std::floor(m_dt));
78  struct tm temp = *localtime(&t); // localtime, not gmtime
79  size_t res = ::strftime(txtiso, 63, fmt, &temp);
80  if (res == 0) {
81  return std::string("");
82  } else {
83  res = ::snprintf(txtsec, 63, "%s.%06d", txtiso, m_us);
84  if (res <= 0) {
85  return std::string("");
86  } else {
87  return std::string(txtsec);
88  }
89  }
90  }
91 
92  friend inline std::ostream &operator<<(std::ostream & s, const Datetime d);
93 
94  private:
95  double m_dt; // fractional seconds since epoch
96  struct tm m_tm; // standard time representation
97  unsigned int m_us; // microsecond (to complement m_tm)
98 
99  // update m_tm based on m_dt
100  void update_tm() {
101  if (R_FINITE(m_dt)) {
102  double dt = std::floor(m_dt);
103  time_t t = static_cast<time_t>(dt);
104  m_tm = *gmtime_(&t);
105  // m_us is fractional (micro)secs as diff. between (fractional) m_dt and m_tm
106  m_us = static_cast<int>(::Rf_fround( (m_dt - dt) * 1.0e6, 0.0));
107  } else {
108  m_dt = NA_REAL; // NaN and Inf need it set
109  m_tm.tm_sec = m_tm.tm_min = m_tm.tm_hour = m_tm.tm_isdst = NA_INTEGER;
110  m_tm.tm_min = m_tm.tm_hour = m_tm.tm_mday = m_tm.tm_mon = m_tm.tm_year = NA_INTEGER;
111  m_us = NA_INTEGER;
112  }
113  }
114 
115  // 1900 as per POSIX mktime() et al
116  static inline unsigned int baseYear() {
117  return 1900;
118  }
119 
120  };
121 
122 
123  // template specialisation for wrap() on datetime
124  template <> SEXP wrap<Rcpp::Datetime>(const Rcpp::Datetime &dt);
125 
126  // needed to wrap containers of Date such as vector<Datetime> or map<string,Datetime>
127  namespace internal {
128  template<> inline double caster<Rcpp::Datetime,double>(Rcpp::Datetime from) {
129  return from.getFractionalTimestamp();
130  }
131  template<> inline Rcpp::Datetime caster<double,Rcpp::Datetime>(double from) {
132  return Rcpp::Datetime( from );
133  }
134  }
135 
136  template<> SEXP wrap_extra_steps<Rcpp::Datetime>(SEXP x);
137 
138  inline Datetime operator+(const Datetime &datetime, double offset) {
139  Datetime newdt(datetime.m_dt);
140  newdt.m_dt += offset;
141  double dt = std::floor(newdt.m_dt);
142  time_t t = static_cast<time_t>(dt);
143  newdt.m_tm = *gmtime_(&t);
144  newdt.m_us = static_cast<int>(::Rf_fround( (newdt.m_dt - dt) * 1.0e6, 0.0));
145  return newdt;
146  }
147 
148  inline Datetime operator+(const Datetime &datetime, int offset) {
149  Datetime newdt(datetime.m_dt);
150  newdt.m_dt += offset;
151  double dt = std::floor(newdt.m_dt);
152  time_t t = static_cast<time_t>(dt);
153  newdt.m_tm = *gmtime_(&t);
154  newdt.m_us = static_cast<int>(::Rf_fround( (newdt.m_dt - dt) * 1.0e6, 0.0));
155  return newdt;
156  }
157 
158  inline double operator-(const Datetime& d1, const Datetime& d2) { return d1.m_dt - d2.m_dt; }
159  inline bool operator<(const Datetime &d1, const Datetime& d2) { return d1.m_dt < d2.m_dt; }
160  inline bool operator>(const Datetime &d1, const Datetime& d2) { return d1.m_dt > d2.m_dt; }
161  inline bool operator==(const Datetime &d1, const Datetime& d2) { return d1.m_dt == d2.m_dt; }
162  inline bool operator>=(const Datetime &d1, const Datetime& d2) { return d1.m_dt >= d2.m_dt; }
163  inline bool operator<=(const Datetime &d1, const Datetime& d2) { return d1.m_dt <= d2.m_dt; }
164  inline bool operator!=(const Datetime &d1, const Datetime& d2) { return d1.m_dt != d2.m_dt; }
165 
166  inline std::ostream &operator<<(std::ostream & os, const Datetime d) {
167  os << d.format();
168  return os;
169  }
170 
171 }
172 
173 #endif
double m_dt
Definition: Datetime.h:95
int getMicroSeconds() const
Definition: Datetime.h:50
friend bool operator>(const Datetime &dt1, const Datetime &dt2)
Definition: Datetime.h:160
friend std::ostream & operator<<(std::ostream &s, const Datetime d)
Definition: Datetime.h:166
friend bool operator==(const Datetime &dt1, const Datetime &dt2)
Definition: Datetime.h:161
friend bool operator<=(const Datetime &dt1, const Datetime &dt2)
Definition: Datetime.h:163
double getFractionalTimestamp(void) const
Definition: Datetime.h:48
int getMonth() const
Definition: Datetime.h:55
int getYear() const
Definition: Datetime.h:56
void update_tm()
Definition: Datetime.h:100
friend double operator-(const Datetime &dt1, const Datetime &dt2)
Definition: Datetime.h:158
static unsigned int baseYear()
Definition: Datetime.h:116
std::string format(const char *fmt="%Y-%m-%d %H:%M:%S") const
Definition: Datetime.h:75
int getSeconds() const
Definition: Datetime.h:51
struct tm m_tm
Definition: Datetime.h:96
int is_na() const
Definition: Datetime.h:71
int getMinutes() const
Definition: Datetime.h:52
friend bool operator>=(const Datetime &dt1, const Datetime &dt2)
Definition: Datetime.h:162
friend Datetime operator+(const Datetime &dt, double offset)
Definition: Datetime.h:138
Datetime(const double &dt)
Definition: Datetime.h:42
int getDay() const
Definition: Datetime.h:54
unsigned int m_us
Definition: Datetime.h:97
int getYearday() const
Definition: Datetime.h:58
int getWeekday() const
Definition: Datetime.h:57
int getHours() const
Definition: Datetime.h:53
friend bool operator<(const Datetime &dt1, const Datetime &dt2)
Definition: Datetime.h:159
friend bool operator!=(const Datetime &dt1, const Datetime &dt2)
Definition: Datetime.h:164
double dt(double x, double n, int lg)
Definition: Rmath.h:90
bool is_na< REALSXP >(double x)
Definition: is_na.h:42
Rcpp API.
Definition: algo.h:28
bool operator>=(const Date &d1, const Date &d2)
Definition: Date.h:168
bool operator!=(const Date &d1, const Date &d2)
Definition: Date.h:170
double operator-(const Date &d1, const Date &d2)
Definition: Date.h:164
static struct tm tm
Definition: date.cpp:436
bool operator>(const Date &d1, const Date &d2)
Definition: Date.h:166
attribute_hidden struct tm * gmtime_(const time_t *const x)
Definition: routines.h:136
std::ostream & operator<<(std::ostream &os, const Date d)
Definition: Date.h:172
bool operator<(const Date &d1, const Date &d2)
Definition: Date.h:165
bool operator==(const Date &d1, const Date &d2)
Definition: Date.h:167
bool operator<=(const Date &d1, const Date &d2)
Definition: Date.h:169
Date operator+(const Date &date, int offset)
Definition: Date.h:156