Rcpp Version 1.0.14
Loading...
Searching...
No Matches
Date.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// Date.h: Rcpp R/C++ interface class library -- dates
4//
5// Copyright (C) 2010 - 2015 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__Date_h
23#define Rcpp__Date_h
24
25#if defined(WIN32) || defined(__WIN32) || defined(__WIN32__)
26#include <time.h>
27#endif
28
29namespace Rcpp {
30
31 class Date {
32 public:
33 Date() {
34 m_d = 0;
35 update_tm();
36 }
37 Date(SEXP s);
38
39 // from integer (with negative dates before Jan 1, 1970)
40 Date(const int &dt) {
41 m_d = dt;
42 update_tm();
43 }
44
45 // from fractional integer since epoch, just like R
46 Date(const double &dt) {
47 m_d = dt;
48 update_tm();
49 }
50 Date(const std::string &s, const std::string &fmt="%Y-%m-%d");
51
52 Date(const unsigned int &mon, const unsigned int &day, const unsigned int &year) {
53 m_tm.tm_sec = m_tm.tm_min = m_tm.tm_hour = m_tm.tm_isdst = 0;
54
55 // allow for ISO-notation case (yyyy, mm, dd) which we prefer over (mm, dd, year)
56 if (mon >= baseYear() && day <= 12 && year <= 31) {
57 m_tm.tm_year = mon - baseYear();
58 m_tm.tm_mon = day - 1; // range 0 to 11
59 m_tm.tm_mday = year;
60 } else {
61 m_tm.tm_mday = day;
62 m_tm.tm_mon = mon - 1; // range 0 to 11
63 m_tm.tm_year = year - baseYear();
64 }
65 double tmp = mktime00(m_tm); // use mktime() replacement borrowed from R
66 m_tm.tm_year += baseYear(); // we'd rather keep it as a normal year
67 m_d = tmp/(24*60*60);
68 }
69
70 double getDate(void) const {
71 return m_d;
72 }
73
74 // intra-day useless for date class
75 //int getSeconds() const { return m_tm.tm_sec; }
76 //int getMinutes() const { return m_tm.tm_min; }
77 //int getHours() const { return m_tm.tm_hour; }
78 int getDay() const { return m_tm.tm_mday; }
79 int getMonth() const { return m_tm.tm_mon + 1; } // makes it 1 .. 12
80 int getYear() const { return m_tm.tm_year; } // does include 1900 (see Date.cpp)
81 int getWeekday() const { return m_tm.tm_wday + 1; } // makes it 1 .. 7
82 int getYearday() const { return m_tm.tm_yday + 1; } // makes it 1 .. 366
83
84 // 1900 as per POSIX mktime() et al
85 static inline unsigned int baseYear() {
86 return 1900;
87 }
88
89 // Minimal set of date operations.
90 friend Date operator+( const Date &date, int offset);
91 friend double operator-( const Date &date1, const Date& date2);
92 friend bool operator<( const Date &date1, const Date& date2);
93 friend bool operator>( const Date &date1, const Date& date2);
94 friend bool operator==(const Date &date1, const Date& date2);
95 friend bool operator>=(const Date &date1, const Date& date2);
96 friend bool operator<=(const Date &date1, const Date& date2);
97 friend bool operator!=(const Date &date1, const Date& date2);
98
99 inline int is_na() const {
101 }
102
103 operator double() const {
104 return m_d;
105 }
106
107 inline std::string format(const char *fmt = "%Y-%m-%d") const {
108 char txt[32];
109 struct tm temp = m_tm;
110 temp.tm_year -= baseYear(); // adjust for fact that system has year rel. to 1900
111 size_t res = ::strftime(txt, 31, fmt, &temp);
112 if (res == 0) {
113 return std::string("");
114 } else {
115 return std::string(txt);
116 }
117 }
118
119 friend inline std::ostream &operator<<(std::ostream & os, const Date d);
120
121 private:
122 double m_d; // (fractional) day number, relative to epoch of Jan 1, 1970
123 struct tm m_tm; // standard time representation
124
125 // update m_tm based on m_d
126 void update_tm() {
127 if (R_FINITE(m_d)) {
128 time_t t = static_cast<time_t>(24*60*60 * m_d); // (fractional) days since epoch to seconds since epoch
129 m_tm = *gmtime_(&t);
130 } else {
131 m_tm.tm_sec = m_tm.tm_min = m_tm.tm_hour = m_tm.tm_isdst = NA_INTEGER;
132 m_tm.tm_min = m_tm.tm_hour = m_tm.tm_mday = m_tm.tm_mon = m_tm.tm_year = NA_INTEGER;
133 }
134 }
135
136 };
137
138 // template specialisation for wrap() on the date
140
141 // needed to wrap containers of Date such as vector<Date> or map<string,Date>
142 namespace internal {
143 template<> inline double caster<Rcpp::Date,double>(Rcpp::Date from) {
144 return static_cast<double>(from.getDate());
145 }
146 template<> inline Rcpp::Date caster<double,Rcpp::Date>(double from) {
147 return Rcpp::Date(static_cast<int>(from));
148 }
149 }
150
153 return x;
154 }
155
156 inline Date operator+(const Date &date, int offset) {
157 Date newdate(date.m_d);
158 newdate.m_d += offset;
159 time_t t = static_cast<time_t>(24*60*60 * newdate.m_d); // days since epoch to seconds since epo
160 newdate.m_tm = *gmtime_(&t);
161 return newdate;
162 }
163
164 inline double operator-( const Date& d1, const Date& d2) { return d1.m_d - d2.m_d; }
165 inline bool operator<( const Date &d1, const Date& d2) { return d1.m_d < d2.m_d; }
166 inline bool operator>( const Date &d1, const Date& d2) { return d1.m_d > d2.m_d; }
167 inline bool operator==(const Date &d1, const Date& d2) { return d1.m_d == d2.m_d; }
168 inline bool operator>=(const Date &d1, const Date& d2) { return d1.m_d >= d2.m_d; }
169 inline bool operator<=(const Date &d1, const Date& d2) { return d1.m_d <= d2.m_d; }
170 inline bool operator!=(const Date &d1, const Date& d2) { return d1.m_d != d2.m_d; }
171
172 inline std::ostream &operator<<(std::ostream & os, const Date d) {
173 os << d.format();
174 return os;
175 }
176
177 namespace internal {
178
185
186 inline SEXP new_posixt_object( double d) {
189 return x;
190 }
191
192 inline SEXP new_date_object(double d) {
195 return x;
196 }
197
198 }
199
200
201}
202
203#endif
Date()
Definition Date.h:33
struct tm m_tm
Definition Date.h:123
friend Date operator+(const Date &date, int offset)
Definition Date.h:156
int getMonth() const
Definition Date.h:79
friend bool operator==(const Date &date1, const Date &date2)
Definition Date.h:167
int getYear() const
Definition Date.h:80
friend bool operator>=(const Date &date1, const Date &date2)
Definition Date.h:168
int getWeekday() const
Definition Date.h:81
int getDay() const
Definition Date.h:78
double m_d
Definition Date.h:122
Date(const unsigned int &mon, const unsigned int &day, const unsigned int &year)
Definition Date.h:52
friend bool operator<=(const Date &date1, const Date &date2)
Definition Date.h:169
void update_tm()
Definition Date.h:126
friend std::ostream & operator<<(std::ostream &os, const Date d)
Definition Date.h:172
friend bool operator<(const Date &date1, const Date &date2)
Definition Date.h:165
friend bool operator!=(const Date &date1, const Date &date2)
Definition Date.h:170
double getDate(void) const
Definition Date.h:70
Date(const double &dt)
Definition Date.h:46
int getYearday() const
Definition Date.h:82
friend double operator-(const Date &date1, const Date &date2)
Definition Date.h:164
Date(const int &dt)
Definition Date.h:40
friend bool operator>(const Date &date1, const Date &date2)
Definition Date.h:166
int is_na() const
Definition Date.h:99
std::string format(const char *fmt="%Y-%m-%d") const
Definition Date.h:107
static unsigned int baseYear()
Definition Date.h:85
SEXP new_posixt_object(double d)
Definition Date.h:186
T as(SEXP x, ::Rcpp::traits::r_type_primitive_tag)
Definition as.h:43
Rcpp::Date caster< double, Rcpp::Date >(double from)
Definition Date.h:146
SEXP getPosixClasses()
Definition Date.h:179
double caster< Rcpp::Date, double >(Rcpp::Date from)
Definition Date.h:143
SEXP new_date_object(double d)
Definition Date.h:192
bool is_na< REALSXP >(double x)
Definition is_na.h:42
Rcpp API.
Definition algo.h:28
std::ostream & operator<<(std::ostream &os, const Date d)
Definition Date.h:172
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:435
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
SEXP wrap_extra_steps< Rcpp::Date >(SEXP)
Definition Date.h:151
attribute_hidden double mktime00(struct tm &tm)
Definition routines.h:130
T as(SEXP x)
Definition as.h:151
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
SEXP wrap< Rcpp::Date >(const Rcpp::Date &date)
Date operator+(const Date &date, int offset)
Definition Date.h:156