2 +----------------------------------------------------------------------+
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
17 #include "hphp/runtime/base/dateinterval.h"
18 #include "hphp/runtime/base/datetime.h"
19 #include "hphp/runtime/base/execution-context.h"
20 #include "hphp/runtime/base/type-conversions.h"
21 #include "hphp/runtime/base/builtin-functions.h"
22 #include "hphp/runtime/base/runtime-error.h"
23 #include "hphp/runtime/base/req-ptr.h"
24 #include "hphp/util/logger.h"
28 IMPLEMENT_RESOURCE_ALLOCATION(DateInterval
)
29 ///////////////////////////////////////////////////////////////////////////////
31 DateInterval::DateInterval() {
32 m_di
= DateIntervalPtr();
35 DateInterval::DateInterval(const String
& date_interval
,
36 bool date_string
/*= false */) {
38 setDateString(date_interval
);
40 setInterval(date_interval
);
44 DateInterval::DateInterval(timelib_rel_time
*di
) {
45 m_di
= DateIntervalPtr(di
, dateinterval_deleter());
48 void DateInterval::setDateString(const String
& date_string
) {
49 timelib_error_container
*errors
= nullptr;
51 auto time
= timelib_strtotime((char*)date_string
.data(), date_string
.size(),
52 &errors
, TimeZone::GetDatabase(),
53 TimeZone::GetTimeZoneInfoRaw
);
54 DateTime::setLastErrors(errors
);
56 auto di
= timelib_rel_time_clone(&time
->relative
);
58 timelib_time_dtor(time
);
59 m_di
= DateIntervalPtr(di
, dateinterval_deleter());
62 void DateInterval::setInterval(const String
& date_interval
) {
63 timelib_rel_time
*di
= nullptr;
64 timelib_error_container
*errors
= nullptr;
66 timelib_time
*start
= nullptr, *end
= nullptr;
69 timelib_strtointerval((char*)date_interval
.data(), date_interval
.size(),
70 &start
, &end
, &di
, &r
, &errors
);
72 int error_count
= errors
->error_count
;
73 DateTime::setLastErrors(errors
);
74 if (error_count
> 0) {
75 timelib_rel_time_dtor(di
);
79 if (UNLIKELY(!di
&& start
&& end
)) {
80 timelib_update_ts(start
, nullptr);
81 timelib_update_ts(end
, nullptr);
82 di
= timelib_diff(start
, end
);
84 m_di
= DateIntervalPtr(di
, dateinterval_deleter());
87 String
DateInterval::format(const String
& format_spec
) {
89 for(int i
= 0; i
< format_spec
.length(); i
++) {
90 const int MAXLEN
= 22; // 64bit signed int string length, plus terminating \0
93 char c
= format_spec
.charAt(i
);
100 if (i
== format_spec
.length()) {
101 // End of format, use literal % and finish
105 c
= format_spec
.charAt(i
);
108 case 'Y': l
= snprintf(buf
, MAXLEN
, "%02" PRId64
, getYears()); break;
109 case 'y': l
= snprintf(buf
, MAXLEN
, "%" PRId64
, getYears()); break;
111 case 'M': l
= snprintf(buf
, MAXLEN
, "%02" PRId64
, getMonths()); break;
112 case 'm': l
= snprintf(buf
, MAXLEN
, "%" PRId64
, getMonths()); break;
114 case 'D': l
= snprintf(buf
, MAXLEN
, "%02" PRId64
, getDays()); break;
115 case 'd': l
= snprintf(buf
, MAXLEN
, "%" PRId64
, getDays()); break;
117 case 'H': l
= snprintf(buf
, MAXLEN
, "%02" PRId64
, getHours()); break;
118 case 'h': l
= snprintf(buf
, MAXLEN
, "%" PRId64
, getHours()); break;
120 case 'I': l
= snprintf(buf
, MAXLEN
, "%02" PRId64
, getMinutes()); break;
121 case 'i': l
= snprintf(buf
, MAXLEN
, "%" PRId64
, getMinutes()); break;
123 case 'S': l
= snprintf(buf
, MAXLEN
, "%02" PRId64
, getSeconds()); break;
124 case 's': l
= snprintf(buf
, MAXLEN
, "%" PRId64
, getSeconds()); break;
127 if (haveTotalDays()) {
128 l
= snprintf(buf
, MAXLEN
, "%" PRId64
, getTotalDays());
130 l
= snprintf(buf
, MAXLEN
, "(unknown)");
135 l
= snprintf(buf
, MAXLEN
, "%c", isInverted() ? '-' : '+'); break;
137 l
= snprintf(buf
, MAXLEN
, "%s", isInverted() ? "-" : ""); break;
153 req::ptr
<DateInterval
> DateInterval::cloneDateInterval() const {
154 if (!m_di
) return req::make
<DateInterval
>();
155 return req::make
<DateInterval
>(timelib_rel_time_clone(m_di
.get()));
158 ///////////////////////////////////////////////////////////////////////////////