PageRenderTime 46ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/hphp/runtime/base/dateinterval.cpp

http://github.com/facebook/hiphop-php
C++ | 158 lines | 111 code | 29 blank | 18 comment | 15 complexity | 6a8dd100991af0e868493add0c7111b2 MD5 | raw file
Possible License(s): LGPL-2.1, BSD-2-Clause, BSD-3-Clause, MPL-2.0-no-copyleft-exception, MIT, LGPL-2.0, Apache-2.0
  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. +----------------------------------------------------------------------+
  15. */
  16. #include "hphp/runtime/base/dateinterval.h"
  17. #include "hphp/runtime/base/datetime.h"
  18. #include "hphp/runtime/base/execution-context.h"
  19. #include "hphp/runtime/base/builtin-functions.h"
  20. #include "hphp/runtime/base/runtime-error.h"
  21. #include "hphp/runtime/base/req-ptr.h"
  22. #include "hphp/util/logger.h"
  23. namespace HPHP {
  24. IMPLEMENT_RESOURCE_ALLOCATION(DateInterval)
  25. ///////////////////////////////////////////////////////////////////////////////
  26. DateInterval::DateInterval() {
  27. m_di = DateIntervalPtr();
  28. }
  29. DateInterval::DateInterval(const String& date_interval,
  30. bool date_string /*= false */) {
  31. if (date_string) {
  32. setDateString(date_interval);
  33. } else {
  34. setInterval(date_interval);
  35. }
  36. }
  37. DateInterval::DateInterval(timelib_rel_time *di) {
  38. m_di = DateIntervalPtr(di, dateinterval_deleter());
  39. }
  40. void DateInterval::setDateString(const String& date_string) {
  41. timelib_error_container *errors = nullptr;
  42. auto time = timelib_strtotime((char*)date_string.data(), date_string.size(),
  43. &errors, TimeZone::GetDatabase(),
  44. TimeZone::GetTimeZoneInfoRaw);
  45. DateTime::setLastErrors(errors);
  46. auto di = timelib_rel_time_clone(&time->relative);
  47. timelib_time_dtor(time);
  48. m_di = DateIntervalPtr(di, dateinterval_deleter());
  49. }
  50. void DateInterval::setInterval(const String& date_interval) {
  51. timelib_rel_time *di = nullptr;
  52. timelib_error_container *errors = nullptr;
  53. timelib_time *start = nullptr, *end = nullptr;
  54. int r = 0;
  55. timelib_strtointerval((char*)date_interval.data(), date_interval.size(),
  56. &start, &end, &di, &r, &errors);
  57. int error_count = errors->error_count;
  58. DateTime::setLastErrors(errors);
  59. if (error_count > 0) {
  60. timelib_rel_time_dtor(di);
  61. return;
  62. }
  63. if (UNLIKELY(!di && start && end)) {
  64. timelib_update_ts(start, nullptr);
  65. timelib_update_ts(end, nullptr);
  66. di = timelib_diff(start, end);
  67. }
  68. m_di = DateIntervalPtr(di, dateinterval_deleter());
  69. }
  70. String DateInterval::format(const String& format_spec) {
  71. StringBuffer s;
  72. for(int i = 0; i < format_spec.length(); i++) {
  73. const int MAXLEN = 22; // 64bit signed int string length, plus terminating \0
  74. char buf[MAXLEN];
  75. int l;
  76. char c = format_spec.charAt(i);
  77. if (c != '%') {
  78. s.append(c);
  79. continue;
  80. }
  81. i++;
  82. if (i == format_spec.length()) {
  83. // End of format, use literal % and finish
  84. s.append(c);
  85. break;
  86. }
  87. c = format_spec.charAt(i);
  88. switch(c) {
  89. case 'Y': l = snprintf(buf, MAXLEN, "%02" PRId64, getYears()); break;
  90. case 'y': l = snprintf(buf, MAXLEN, "%" PRId64, getYears()); break;
  91. case 'M': l = snprintf(buf, MAXLEN, "%02" PRId64, getMonths()); break;
  92. case 'm': l = snprintf(buf, MAXLEN, "%" PRId64, getMonths()); break;
  93. case 'D': l = snprintf(buf, MAXLEN, "%02" PRId64, getDays()); break;
  94. case 'd': l = snprintf(buf, MAXLEN, "%" PRId64, getDays()); break;
  95. case 'H': l = snprintf(buf, MAXLEN, "%02" PRId64, getHours()); break;
  96. case 'h': l = snprintf(buf, MAXLEN, "%" PRId64, getHours()); break;
  97. case 'I': l = snprintf(buf, MAXLEN, "%02" PRId64, getMinutes()); break;
  98. case 'i': l = snprintf(buf, MAXLEN, "%" PRId64, getMinutes()); break;
  99. case 'S': l = snprintf(buf, MAXLEN, "%02" PRId64, getSeconds()); break;
  100. case 's': l = snprintf(buf, MAXLEN, "%" PRId64, getSeconds()); break;
  101. case 'a':
  102. if (haveTotalDays()) {
  103. l = snprintf(buf, MAXLEN, "%" PRId64, getTotalDays());
  104. } else {
  105. l = snprintf(buf, MAXLEN, "(unknown)");
  106. }
  107. break;
  108. case 'R':
  109. l = snprintf(buf, MAXLEN, "%c", isInverted() ? '-' : '+'); break;
  110. case 'r':
  111. l = snprintf(buf, MAXLEN, "%s", isInverted() ? "-" : ""); break;
  112. case '%':
  113. default:
  114. l = 0;
  115. s.append('%');
  116. break;
  117. }
  118. if (l > 0) {
  119. s.append(buf, l);
  120. }
  121. }
  122. return s.detach();
  123. }
  124. req::ptr<DateInterval> DateInterval::cloneDateInterval() const {
  125. if (!m_di) return req::make<DateInterval>();
  126. return req::make<DateInterval>(timelib_rel_time_clone(m_di.get()));
  127. }
  128. ///////////////////////////////////////////////////////////////////////////////
  129. }