codemod 2010-2016 to 2010-present
[hiphop-php.git] / hphp / runtime / base / dateinterval.cpp
blob4bac6d482d4ee278bf90493edc942162a75f7bfb
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
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"
26 namespace HPHP {
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 */) {
37 if (date_string) {
38 setDateString(date_interval);
39 } else {
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;
67 int r = 0;
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);
76 return;
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) {
88 StringBuffer s;
89 for(int i = 0; i < format_spec.length(); i++) {
90 const int MAXLEN = 22; // 64bit signed int string length, plus terminating \0
91 char buf[MAXLEN];
92 int l;
93 char c = format_spec.charAt(i);
95 if (c != '%') {
96 s.append(c);
97 continue;
99 i++;
100 if (i == format_spec.length()) {
101 // End of format, use literal % and finish
102 s.append(c);
103 break;
105 c = format_spec.charAt(i);
107 switch(c) {
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;
126 case 'a':
127 if (haveTotalDays()) {
128 l = snprintf(buf, MAXLEN, "%" PRId64, getTotalDays());
129 } else {
130 l = snprintf(buf, MAXLEN, "(unknown)");
132 break;
134 case 'R':
135 l = snprintf(buf, MAXLEN, "%c", isInverted() ? '-' : '+'); break;
136 case 'r':
137 l = snprintf(buf, MAXLEN, "%s", isInverted() ? "-" : ""); break;
139 case '%':
140 default:
141 l = 0;
142 s.append('%');
143 break;
146 if (l > 0) {
147 s.append(buf, l);
150 return s.detach();
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 ///////////////////////////////////////////////////////////////////////////////