Newer
Older
Janik Zikovsky
committed
#include <time.h>
namespace Mantid
{
namespace Kernel
{
Janik Zikovsky
committed
namespace DateAndTime
{
Janik Zikovsky
committed
//-----------------------------------------------------------------------------------------------
Janik Zikovsky
committed
/** Portable implementation of gmtime_r (re-entrant gmtime)
*
*/
std::tm * gmtime_r_portable( const std::time_t *clock, struct std::tm *result )
{
#ifdef _WIN32
if (gmtime_s(result, clock))
{
return result;
}
else
{
return NULL;
}
#else
//Unix implementation
return gmtime_r(clock, result);
#endif
}
Janik Zikovsky
committed
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
/// utc_mktime() converts a struct tm that contains
/// broken down time in utc to a time_t. This function uses
/// a brute-force method of conversion that does not require
/// the environment variable TZ to be changed at all, and is
/// therefore slightly more thread-safe in that regard.
///
/// The difference between mktime() and utc_mktime() is that
/// standard mktime() expects the struct tm to be in localtime,
/// according to the current TZ and system setting, while utc_mktime()
/// always assumes that the struct tm is in UTC, and converts it
/// to time_t regardless of what TZ is currently set.
///
/// The difference between utc_mktime() and TzWrapper::iso_mktime()
/// is that iso_mktime() will parse straight from an ISO string,
/// and if the ISO timestamp ends in a 'Z', it will behave like
/// utc_mktime() except it will alter the TZ environment variable
/// to do it. If the ISO timestamp has no 'Z', then iso_mktime()
/// behaves like mktime().
///
/// Copyright (C) 2010, Chris Frey <cdfrey@foursquare.net>, To God be the glory
/// Released to the public domain.
time_t utc_mktime(struct tm *utctime)
{
time_t result;
struct tm tmp, check;
// loop, converting "local time" to time_t and back to utc tm,
// and adjusting until there are no differences... this
// automatically takes care of DST issues.
// do first conversion
tmp = *utctime;
tmp.tm_isdst = -1;
result = mktime(&tmp);
if( result == (time_t)-1 )
return (time_t)-1;
Janik Zikovsky
committed
if( gmtime_r_portable(&result, &check) == NULL )
Janik Zikovsky
committed
return (time_t)-1;
// loop until match
while( check.tm_year != utctime->tm_year ||
check.tm_mon != utctime->tm_mon ||
check.tm_mday != utctime->tm_mday ||
check.tm_hour != utctime->tm_hour ||
check.tm_min != utctime->tm_min )
{
tmp.tm_min += utctime->tm_min - check.tm_min;
tmp.tm_hour += utctime->tm_hour - check.tm_hour;
tmp.tm_mday += utctime->tm_mday - check.tm_mday;
tmp.tm_year += utctime->tm_year - check.tm_year;
tmp.tm_isdst = -1;
result = mktime(&tmp);
if( result == (time_t)-1 )
return (time_t)-1;
Janik Zikovsky
committed
gmtime_r_portable(&result, &check);
if( gmtime_r_portable(&result, &check) == NULL )
Janik Zikovsky
committed
return (time_t)-1;
}
return result;
}
//-----------------------------------------------------------------------------------------------
Janik Zikovsky
committed
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/**
* Return the number of seconds in a duration, as a double, including fractional seconds.
*/
double durationInSeconds(time_duration duration)
{
return static_cast<double>(duration.total_seconds()) + static_cast<double>(duration.total_nanoseconds()) / 1e9;
}
//-----------------------------------------------------------------------------------------------
/// Create dateAndTime instance from a ISO 8601 yyyy-mm-ddThh:mm:ss input string
dateAndTime create_DateAndTime_FromISO8601_String(const std::string &str)
{
//Make a copy
std::string time = str;
//Replace "T" with a space
size_t n = time.find('T');
if (n != std::string::npos)
time[n] = ' ';
//The boost conversion will handle it
return boost::posix_time::time_from_string(time);
}
//-----------------------------------------------------------------------------------------------
/// Create a ISO 8601 yyyy-mm-ddThh:mm:ss string from a time
std::string create_ISO8601_String(const dateAndTime &time)
{
char buffer [25];
std::tm time_tm = boost::posix_time::to_tm(time); //turn into that struct
strftime (buffer,25,"%Y-%m-%dT%H:%M:%S", &time_tm); //Make into a string
return std::string(buffer);
}
Janik Zikovsky
committed
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
//-----------------------------------------------------------------------------------------------
/** Convert a dateAndTime object to a std::tm time structure, using whatever time zone in the
* dateAndtime (should be UTC) .
*/
std::tm to_tm(const dateAndTime &time)
{
std::tm as_tm = boost::posix_time::to_tm(time);
return as_tm;
}
//-----------------------------------------------------------------------------------------------
/** Returns the current dateAndTime, in UTC time, with microsecond precision
*
*/
dateAndTime get_current_time()
{
return boost::posix_time::microsec_clock::universal_time();
}
//-----------------------------------------------------------------------------------------------
/** Returns a dateAndTime object made from a time_t input.
* If the input time_t is in UTC, then the output will be as well.
*/
dateAndTime from_time_t(const std::time_t &time)
{
return boost::posix_time::from_time_t( time );
}
//-----------------------------------------------------------------------------------------------
/** Convert a dateAndTime object (in UTC time) to std::time_t, in UTC time.
*/
std::time_t to_time_t(const dateAndTime &time)
{
std::tm as_tm = boost::posix_time::to_tm(time);
std::time_t as_time_t = utc_mktime( &as_tm );
return as_time_t;
}
Janik Zikovsky
committed
} //namespace DateAndTime
Janik Zikovsky
committed
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
TimeInterval::TimeInterval(const dateAndTime& from, const dateAndTime& to)
:m_begin(from)
{
if (to > from) m_end = to;
else
m_end = from;
}
/** Returns an intersection of this interval with \a ti
@param ti Time interval
@return A valid time interval if this interval intersects with \a ti or
an empty interval otherwise.
*/
TimeInterval TimeInterval::intersection(const TimeInterval& ti)const
{
if (!isValid() || !ti.isValid()) return TimeInterval();
dateAndTime t1 = begin();
if (ti.begin() > t1) t1 = ti.begin();
dateAndTime t2 = end();
if (ti.end() < t2) t2 = ti.end();
return t1 < t2? TimeInterval(t1,t2) : TimeInterval();
}
/// String representation of the begin time
std::string TimeInterval::begin_str()const
{
Janik Zikovsky
committed
return boost::posix_time::to_simple_string(this->m_begin);
// char buffer [25];
// strftime (buffer,25,"%Y-%b-%d %H:%M:%S",localtime(&m_begin));
//// strftime (buffer,25,"%H:%M:%S",localtime(&m_begin));
// return std::string(buffer);
}
/// String representation of the end time
std::string TimeInterval::end_str()const
{
Janik Zikovsky
committed
return boost::posix_time::to_simple_string(this->m_end);
// char buffer [25];
// strftime (buffer,25,"%Y-%b-%d %H:%M:%S",localtime(&m_end));
// return std::string(buffer);
} // namespace Kernel
} // namespace Mantid
std::ostream& operator<<(std::ostream& s,const Mantid::Kernel::TimeInterval& t)
Janik Zikovsky
committed
s << t.begin() << " - " << t.end();
return s;
// char buffer [25];
// Mantid::Kernel::dateAndTime d = t.begin();
// strftime (buffer,25,"%Y-%b-%d %H:%M:%S",localtime(&d));
// s<<buffer<<" - ";
// d = t.end();
// strftime (buffer,25,"%Y-%b-%d %H:%M:%S",localtime(&d));
// s<<buffer;
// return s;