tc_common.cpp 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602
  1. /**
  2. * Tencent is pleased to support the open source community by making Tars available.
  3. *
  4. * Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved.
  5. *
  6. * Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
  7. * in compliance with the License. You may obtain a copy of the License at
  8. *
  9. * https://opensource.org/licenses/BSD-3-Clause
  10. *
  11. * Unless required by applicable law or agreed to in writing, software distributed
  12. * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
  13. * CONDITIONS OF ANY KIND, either express or implied. See the License for the
  14. * specific language governing permissions and limitations under the License.
  15. */
  16. #include "util/tc_common.h"
  17. #include "util/tc_port.h"
  18. #include <chrono>
  19. #include <thread>
  20. #if TARGET_PLATFORM_WINDOWS
  21. #include <sys/timeb.h>
  22. #pragma comment(lib, "ws2_32.lib")
  23. #include "util/tc_strptime.h"
  24. #endif
  25. #include <signal.h>
  26. #include <string.h>
  27. #include <cmath>
  28. namespace tars
  29. {
  30. #define MATCH_DOUBLE \
  31. if (vx.size() != vy.size()) { return false; } \
  32. auto it1 = vx.begin(); auto it2 = vy.end(); \
  33. while(it1 != vx.end() && it2 != vy.end() ) { \
  34. if (!equal(*it1, *it2, epsilon)) { return false; } \
  35. ++it1; \
  36. ++it2; \
  37. } \
  38. return true;
  39. const float TC_Common::_EPSILON_FLOAT = 0.000001f;
  40. const double TC_Common::_EPSILON_DOUBLE = 0.000001;
  41. #if !TARGET_PLATFORM_WINDOWS
  42. string TC_Common::TimezoneHelper::timezone_local;
  43. #endif
  44. int64_t TC_Common::TimezoneHelper::timezone_diff_secs = 0;
  45. TC_Common::TimezoneHelper TC_Common::_TimeZoneHelper;
  46. void TC_Common::sleep(uint32_t sec)
  47. {
  48. std::this_thread::sleep_for(std::chrono::seconds(sec));
  49. }
  50. void TC_Common::msleep(uint32_t ms)
  51. {
  52. std::this_thread::sleep_for(std::chrono::milliseconds(ms));
  53. }
  54. bool TC_Common::equal(double x, double y, double epsilon)
  55. {
  56. return fabs(x - y) < epsilon;
  57. }
  58. bool TC_Common::equal(double x, double y, float epsilon)
  59. {
  60. return equal(x ,y,(double)epsilon);
  61. }
  62. bool TC_Common::equal(float x, float y, float epsilon)
  63. {
  64. return fabsf(x - y) < epsilon;
  65. }
  66. bool TC_Common::equal(float x, float y, double epsilon)
  67. {
  68. return equal(x, y, float(epsilon));
  69. }
  70. bool TC_Common::equal(const vector<double>& vx, const vector<double>& vy, double epsilon)
  71. {
  72. MATCH_DOUBLE
  73. }
  74. bool TC_Common::equal(const vector<double> &vx, const vector<double> &vy, float epsilon)
  75. {
  76. return equal(vx, vy, double(epsilon));
  77. }
  78. bool TC_Common::equal(const vector<float> &vx, const vector<float> &vy, float epsilon)
  79. {
  80. MATCH_DOUBLE
  81. }
  82. bool TC_Common::equal(const vector<float> &vx, const vector<float> &vy, double epsilon)
  83. {
  84. return equal(vx, vy, float(epsilon));
  85. }
  86. bool TC_Common::equal(const set<double> & vx, const set<double>& vy, double epsilon)
  87. {
  88. MATCH_DOUBLE
  89. }
  90. bool TC_Common::equal(const set<double>& vx, const set<double>& vy, float epsilon )
  91. {
  92. return equal(vx, vy, double(epsilon));
  93. }
  94. bool TC_Common::equal(const set<float>& vx, const set<float> & vy, float epsilon)
  95. {
  96. return equal(vx, vy, double(epsilon));
  97. }
  98. bool TC_Common::equal(const set<float>& vx, const set<float>& vy, double epsilon )
  99. {
  100. MATCH_DOUBLE
  101. }
  102. bool TC_Common::equal(const unordered_set<double> & vx, const unordered_set<double>& vy, double epsilon)
  103. {
  104. MATCH_DOUBLE
  105. }
  106. bool TC_Common::equal(const unordered_set<double>& vx, const unordered_set<double>& vy, float epsilon )
  107. {
  108. return equal(vx, vy, double(epsilon));
  109. }
  110. bool TC_Common::equal(const unordered_set<float>& vx, const unordered_set<float> & vy, float epsilon)
  111. {
  112. return equal(vx, vy, double(epsilon));
  113. }
  114. bool TC_Common::equal(const unordered_set<float>& vx, const unordered_set<float>& vy, double epsilon )
  115. {
  116. MATCH_DOUBLE
  117. }
  118. template<>
  119. string TC_Common::tostr<bool>(const bool &t)
  120. {
  121. char buf[2];
  122. buf[0] = t ? '1' : '0';
  123. buf[1] = '\0';
  124. return string(buf);
  125. }
  126. template<>
  127. string TC_Common::tostr<char>(const char &t)
  128. {
  129. char buf[2];
  130. snprintf(buf, 2, "%c", t);
  131. return string(buf);
  132. }
  133. template<>
  134. string TC_Common::tostr<unsigned char>(const unsigned char &t)
  135. {
  136. char buf[2];
  137. snprintf(buf, 2, "%c", t);
  138. return string(buf);
  139. }
  140. template<>
  141. string TC_Common::tostr<short>(const short &t)
  142. {
  143. char buf[16];
  144. snprintf(buf, 16, "%d", t);
  145. return string(buf);
  146. }
  147. template<>
  148. string TC_Common::tostr<unsigned short>(const unsigned short &t)
  149. {
  150. char buf[16];
  151. snprintf(buf, 16, "%u", t);
  152. return string(buf);
  153. }
  154. template<>
  155. string TC_Common::tostr<int>(const int &t)
  156. {
  157. char buf[16];
  158. snprintf(buf, 16, "%d", t);
  159. return string(buf);
  160. }
  161. template<>
  162. string TC_Common::tostr<unsigned int>(const unsigned int &t)
  163. {
  164. char buf[16];
  165. snprintf(buf, 16, "%u", t);
  166. return string(buf);
  167. }
  168. template<>
  169. string TC_Common::tostr<long>(const long &t)
  170. {
  171. char buf[32];
  172. snprintf(buf, 32, "%ld", t);
  173. return string(buf);
  174. }
  175. template<>
  176. string TC_Common::tostr<long long>(const long long &t)
  177. {
  178. char buf[32];
  179. snprintf(buf, 32, "%lld", t);
  180. return string(buf);
  181. }
  182. template<>
  183. string TC_Common::tostr<unsigned long>(const unsigned long &t)
  184. {
  185. char buf[32];
  186. snprintf(buf, 32, "%lu", t);
  187. return string(buf);
  188. }
  189. template<>
  190. string TC_Common::tostr<float>(const float &t)
  191. {
  192. //C++11 to_string,默认保留后面6位小数
  193. string s = std::to_string(t);
  194. //去掉无效0, eg. 1.0300 -> 1.03;1.00 -> 1
  195. bool bFlag = false;
  196. int pos = int(s.size() - 1);
  197. for (; pos > 0; --pos)
  198. {
  199. if (s[pos] == '0')
  200. {
  201. bFlag = true;
  202. if (s[pos - 1] == '.')
  203. {
  204. //-2为了去掉"."号
  205. pos -= 2;
  206. break;
  207. }
  208. }
  209. else
  210. {
  211. break;
  212. }
  213. }
  214. if (bFlag)
  215. s = s.substr(0, pos + 1);
  216. return s;
  217. }
  218. template<>
  219. string TC_Common::tostr<double>(const double &t)
  220. {
  221. //C++11 to_string,默认保留后面6位小数
  222. string s = std::to_string(t);
  223. //去掉无效0, eg. 1.0300 -> 1.03;1.00 -> 1
  224. bool bFlag = false;
  225. int pos = int(s.size() - 1);
  226. for (; pos > 0; --pos)
  227. {
  228. if (s[pos] == '0')
  229. {
  230. bFlag = true;
  231. if (s[pos - 1] == '.')
  232. {
  233. //-2为了去掉"."号
  234. pos -= 2;
  235. break;
  236. }
  237. }
  238. else
  239. {
  240. break;
  241. }
  242. }
  243. if (bFlag)
  244. s = s.substr(0, pos + 1);
  245. return s;
  246. }
  247. template<>
  248. string TC_Common::tostr<long double>(const long double &t)
  249. {
  250. char buf[32];
  251. snprintf(buf, 32, "%Lf", t);
  252. string s(buf);
  253. //去掉无效0, eg. 1.0300 -> 1.03;1.00 -> 1
  254. bool bFlag = false;
  255. int pos = int(s.size() - 1);
  256. for (; pos > 0; --pos)
  257. {
  258. if (s[pos] == '0')
  259. {
  260. bFlag = true;
  261. if (s[pos - 1] == '.')
  262. {
  263. //-2为了去掉"."号
  264. pos -= 2;
  265. break;
  266. }
  267. }
  268. else
  269. {
  270. break;
  271. }
  272. }
  273. if (bFlag)
  274. s = s.substr(0, pos + 1);
  275. return s;
  276. }
  277. template<>
  278. string TC_Common::tostr<std::string>(const std::string &t)
  279. {
  280. return t;
  281. }
  282. string TC_Common::trim(const string &sStr, const string &s, bool bChar)
  283. {
  284. if (sStr.empty())
  285. {
  286. return sStr;
  287. }
  288. /**
  289. * 将完全与s相同的字符串去掉
  290. */
  291. if (!bChar)
  292. {
  293. return trimright(trimleft(sStr, s, false), s, false);
  294. }
  295. return trimright(trimleft(sStr, s, true), s, true);
  296. }
  297. string TC_Common::trimleft(const string &sStr, const string &s, bool bChar)
  298. {
  299. if (sStr.empty())
  300. {
  301. return sStr;
  302. }
  303. /**
  304. * 去掉sStr左边的字符串s
  305. */
  306. if (!bChar)
  307. {
  308. if (sStr.length() < s.length())
  309. {
  310. return sStr;
  311. }
  312. if (sStr.compare(0, s.length(), s) == 0)
  313. {
  314. return sStr.substr(s.length());
  315. }
  316. return sStr;
  317. }
  318. /**
  319. * 去掉sStr左边的 字符串s中的字符
  320. */
  321. string::size_type pos = 0;
  322. while (pos < sStr.length())
  323. {
  324. if (s.find_first_of(sStr[pos]) == string::npos)
  325. {
  326. break;
  327. }
  328. pos++;
  329. }
  330. if (pos == 0) return sStr;
  331. return sStr.substr(pos);
  332. }
  333. string TC_Common::trimright(const string &sStr, const string &s, bool bChar)
  334. {
  335. if (sStr.empty())
  336. {
  337. return sStr;
  338. }
  339. /**
  340. * 去掉sStr右边的字符串s
  341. */
  342. if (!bChar)
  343. {
  344. if (sStr.length() < s.length())
  345. {
  346. return sStr;
  347. }
  348. if (sStr.compare(sStr.length() - s.length(), s.length(), s) == 0)
  349. {
  350. return sStr.substr(0, sStr.length() - s.length());
  351. }
  352. return sStr;
  353. }
  354. /**
  355. * 去掉sStr右边的 字符串s中的字符
  356. */
  357. string::size_type pos = sStr.length();
  358. while (pos != 0)
  359. {
  360. if (s.find_first_of(sStr[pos - 1]) == string::npos)
  361. {
  362. break;
  363. }
  364. pos--;
  365. }
  366. if (pos == sStr.length()) return sStr;
  367. return sStr.substr(0, pos);
  368. }
  369. string TC_Common::lower(const string &s)
  370. {
  371. string sString = s;
  372. for (string::iterator iter = sString.begin(); iter != sString.end(); ++iter)
  373. {
  374. *iter = tolower(*iter);
  375. }
  376. return sString;
  377. }
  378. string TC_Common::upper(const string &s)
  379. {
  380. string sString = s;
  381. for (string::iterator iter = sString.begin(); iter != sString.end(); ++iter)
  382. {
  383. *iter = toupper(*iter);
  384. }
  385. return sString;
  386. }
  387. bool TC_Common::isdigit(const string &sInput)
  388. {
  389. string::const_iterator iter = sInput.begin();
  390. if (sInput.empty())
  391. {
  392. return false;
  393. }
  394. while (iter != sInput.end())
  395. {
  396. if (!::isdigit(*iter))
  397. {
  398. return false;
  399. }
  400. ++iter;
  401. }
  402. return true;
  403. }
  404. TC_Common::TimezoneHelper::TimezoneHelper()
  405. {
  406. struct tm timeinfo;
  407. time_t secs, local_secs, gmt_secs;
  408. // UTC时间戳
  409. time(&secs);
  410. //带时区时间
  411. TC_Port::localtime_r(&secs, &timeinfo);
  412. local_secs = ::mktime(&timeinfo);
  413. #if !TARGET_PLATFORM_WINDOWS
  414. timezone_local = string(timeinfo.tm_zone);
  415. #endif
  416. //不带时区时间
  417. TC_Port::gmtime_r(&secs, &timeinfo);
  418. gmt_secs = ::mktime(&timeinfo);
  419. timezone_diff_secs = local_secs - gmt_secs;
  420. }
  421. int TC_Common::str2tm(const string &sString, const string &sFormat, struct tm &stTm)
  422. {
  423. memset(&stTm, 0, sizeof(stTm));
  424. char *p = strptime(sString.c_str(), sFormat.c_str(), &stTm);
  425. return (p != NULL) ? 0 : -1;
  426. }
  427. time_t TC_Common::str2time(const string &sString, const string &sFormat)
  428. {
  429. struct tm stTm;
  430. if (0 == str2tm(sString, sFormat, stTm))
  431. {
  432. //注意这里没有直接用mktime, mktime会访问时区文件, 会巨慢!
  433. return TC_Port::timegm(&stTm) - TimezoneHelper::timezone_diff_secs;
  434. }
  435. return 0;
  436. }
  437. int TC_Common::strgmt2tm(const string &sString, struct tm &stTm)
  438. {
  439. return str2tm(sString, "%a, %d %b %Y %H:%M:%S GMT", stTm);
  440. }
  441. string TC_Common::tm2str(const struct tm &stTm, const string &sFormat)
  442. {
  443. char sTimeString[255] = "\0";
  444. strftime(sTimeString, sizeof(sTimeString), sFormat.c_str(), &stTm);
  445. return string(sTimeString);
  446. }
  447. int TC_Common::gettimeofday(struct timeval &tv)
  448. {
  449. return TC_Port::gettimeofday(tv);
  450. }
  451. void TC_Common::tm2time(const time_t &t, struct tm &tt)
  452. {
  453. //加快速度, 否则会比较慢, 不用localtime_r(会访问时区文件, 较慢)
  454. time_t localt = t + TimezoneHelper::timezone_diff_secs;
  455. TC_Port::gmtime_r(&localt, &tt);
  456. #if !TARGET_PLATFORM_WINDOWS
  457. static string local_timezone = TimezoneHelper::timezone_local;
  458. tt.tm_zone = const_cast<char *>(local_timezone.c_str());
  459. tt.tm_gmtoff = TimezoneHelper::timezone_diff_secs;
  460. #endif
  461. }
  462. time_t TC_Common::UTC2LocalTime(const string& utcTimeStr)
  463. {
  464. // 2022-06-07T18:04:37.703806784Z
  465. if (utcTimeStr.length() < 20 || utcTimeStr.at(10) != 'T' || utcTimeStr.back() != 'Z')
  466. {
  467. return 0;
  468. }
  469. return TC_Common::str2time(utcTimeStr, "%Y-%m-%dT%H:%M:%S") + TimezoneHelper::timezone_diff_secs;
  470. }
  471. string TC_Common::tm2str(const time_t &t, const string &sFormat)
  472. {
  473. struct tm tt;
  474. tm2time(t, tt);
  475. return tm2str(tt, sFormat);
  476. }
  477. void TC_Common::tm2tm(const time_t &t, struct tm &tt)
  478. {
  479. tm2time(t, tt);
  480. }
  481. string TC_Common::now2str(const string &sFormat)
  482. {
  483. time_t t = time(NULL);
  484. return tm2str(t, sFormat.c_str());
  485. }
  486. //string TC_Common::now2msstr()
  487. //{
  488. // return ms2str(now2ms());
  489. //}
  490. string TC_Common::ms2str(int64_t ms)
  491. {
  492. time_t t = ms / 1000;
  493. auto duration_in_ms = ms % 1000;
  494. tm tt;
  495. TC_Port::localtime_r(&t, &tt);
  496. string s;
  497. s.resize(128);
  498. const char *szFormat = "%04d-%02d-%02d %02d:%02d:%02d.%03ld";
  499. size_t n = snprintf(&s[0], s.size(), szFormat, tt.tm_year + 1900, tt.tm_mon + 1, tt.tm_mday, tt.tm_hour, tt.tm_min, tt.tm_sec, duration_in_ms);
  500. s.resize(n);
  501. return s;
  502. }
  503. string TC_Common::now2msstr()
  504. {
  505. time_t t = time(NULL);
  506. auto duration_in_ms = now2ms();
  507. tm tt;
  508. TC_Port::localtime_r(&t, &tt);
  509. string s;
  510. s.resize(128);
  511. const char *szFormat = "%04d-%02d-%02d %02d:%02d:%02d.%03ld";
  512. size_t n = snprintf(&s[0], s.size(), szFormat, tt.tm_year + 1900, tt.tm_mon + 1, tt.tm_mday, tt.tm_hour, tt.tm_min, tt.tm_sec, duration_in_ms % 1000);
  513. s.resize(n);
  514. return s;
  515. }
  516. string TC_Common::now2GMTstr()
  517. {
  518. time_t t = time(NULL);
  519. return tm2GMTstr(t);
  520. }
  521. string TC_Common::tm2GMTstr(const time_t &t)
  522. {
  523. struct tm tt;
  524. TC_Port::gmtime_r(&t, &tt);
  525. return tm2str(tt, "%a, %d %b %Y %H:%M:%S GMT");
  526. }
  527. string TC_Common::tm2GMTstr(const struct tm &stTm)
  528. {
  529. return tm2str(stTm, "%a, %d %b %Y %H:%M:%S GMT");
  530. }
  531. string TC_Common::nowdate2str()
  532. {
  533. return now2str("%Y%m%d");
  534. }
  535. string TC_Common::nowtime2str()
  536. {
  537. return now2str("%H%M%S");
  538. }
  539. int64_t TC_Common::now2ms()
  540. {
  541. struct timeval tv;
  542. TC_Common::gettimeofday(tv);
  543. return tv.tv_sec * (int64_t) 1000 + tv.tv_usec / 1000;
  544. }
  545. int64_t TC_Common::now2us()
  546. {
  547. struct timeval tv;
  548. TC_Common::gettimeofday(tv);
  549. return tv.tv_sec * (int64_t) 1000000 + tv.tv_usec;
  550. }
  551. //参照phorix的优化
  552. static char c_b2s[256][4] = {"00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "0a", "0b", "0c", "0d", "0e", "0f", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "1a", "1b", "1c", "1d", "1e", "1f", "20", "21", "22",
  553. "23", "24", "25", "26", "27", "28", "29", "2a", "2b", "2c", "2d", "2e", "2f", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "3a", "3b", "3c", "3d", "3e", "3f", "40", "41", "42", "43", "44", "45",
  554. "46", "47", "48", "49", "4a", "4b", "4c", "4d", "4e", "4f", "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "5a", "5b", "5c", "5d", "5e", "5f", "60", "61", "62", "63", "64", "65", "66", "67", "68",
  555. "69", "6a", "6b", "6c", "6d", "6e", "6f", "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "7a", "7b", "7c", "7d", "7e", "7f", "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "8a", "8b",
  556. "8c", "8d", "8e", "8f", "90", "91", "92", "93", "94", "95", "96", "97", "98", "99", "9a", "9b", "9c", "9d", "9e", "9f", "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9", "aa", "ab", "ac", "ad", "ae",
  557. "af", "b0", "b1", "b2", "b3", "b4", "b5", "b6", "b7", "b8", "b9", "ba", "bb", "bc", "bd", "be", "bf", "c0", "c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9", "ca", "cb", "cc", "cd", "ce", "cf", "d0", "d1",
  558. "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "da", "db", "dc", "dd", "de", "df", "e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7", "e8", "e9", "ea", "eb", "ec", "ed", "ee", "ef", "f0", "f1", "f2", "f3", "f4",
  559. "f5", "f6", "f7", "f8", "f9", "fa", "fb", "fc", "fd", "fe", "ff"};
  560. string TC_Common::bin2str(const void *buf, size_t len, const string &sSep, size_t lines)
  561. {
  562. if (buf == NULL || len <= 0)
  563. {
  564. return "";
  565. }
  566. string sOut;
  567. const unsigned char *p = (const unsigned char *) buf;
  568. for (size_t i = 0; i < len; ++i, ++p)
  569. {
  570. sOut += c_b2s[*p][0];
  571. sOut += c_b2s[*p][1];
  572. sOut += sSep;
  573. //换行
  574. if ((lines != 0) && ((i + 1) % lines == 0))
  575. {
  576. sOut += "\n";
  577. }
  578. }
  579. return sOut;
  580. }
  581. string TC_Common::bin2str(const string &sBinData, const string &sSep, size_t lines)
  582. {
  583. return bin2str((const void *) sBinData.data(), sBinData.length(), sSep, lines);
  584. }
  585. int TC_Common::str2bin(const char *psAsciiData, unsigned char *sBinData, int iBinSize)
  586. {
  587. int iAsciiLength = (int) strlen(psAsciiData);
  588. int iRealLength = (iAsciiLength / 2 > iBinSize) ? iBinSize : (iAsciiLength / 2);
  589. for (int i = 0; i < iRealLength; i++)
  590. {
  591. sBinData[i] = x2c(psAsciiData + i * 2);
  592. }
  593. return iRealLength;
  594. }
  595. string TC_Common::str2bin(const string &sString, const string &sSep, size_t lines)
  596. {
  597. const char *psAsciiData = sString.c_str();
  598. size_t iAsciiLength = sString.length();
  599. string sBinData;
  600. for (size_t i = 0; i < iAsciiLength; i++)
  601. {
  602. sBinData += x2c(psAsciiData + i);
  603. i++;
  604. i += sSep.length(); //过滤掉分隔符
  605. if (lines != 0 && sBinData.length() % lines == 0)
  606. {
  607. i++; //过滤掉回车
  608. }
  609. }
  610. return sBinData;
  611. }
  612. char TC_Common::x2c(const string &sWhat)
  613. {
  614. register char digit;
  615. if (sWhat.length() < 2)
  616. {
  617. return '\0';
  618. }
  619. digit = (sWhat[0] >= 'A' ? ((sWhat[0] & 0xdf) - 'A') + 10 : (sWhat[0] - '0'));
  620. digit *= 16;
  621. digit += (sWhat[1] >= 'A' ? ((sWhat[1] & 0xdf) - 'A') + 10 : (sWhat[1] - '0'));
  622. return (digit);
  623. }
  624. string TC_Common::replace(const string &sString, const string &sSrc, const string &sDest)
  625. {
  626. if (sSrc.empty())
  627. {
  628. return sString;
  629. }
  630. string sBuf = sString;
  631. string::size_type pos = 0;
  632. while ((pos = sBuf.find(sSrc, pos)) != string::npos)
  633. {
  634. sBuf.replace(pos, sSrc.length(), sDest);
  635. pos += sDest.length();
  636. }
  637. return sBuf;
  638. }
  639. string TC_Common::replace(const string &sString, const map<string, string> &mSrcDest)
  640. {
  641. if (sString.empty())
  642. {
  643. return sString;
  644. }
  645. string tmp = sString;
  646. map<string, string>::const_iterator it = mSrcDest.begin();
  647. while (it != mSrcDest.end())
  648. {
  649. string::size_type pos = 0;
  650. while ((pos = tmp.find(it->first, pos)) != string::npos)
  651. {
  652. tmp.replace(pos, it->first.length(), it->second);
  653. pos += it->second.length();
  654. }
  655. ++it;
  656. }
  657. return tmp;
  658. }
  659. bool TC_Common::matchPeriod(const string &s, const string &pat)
  660. {
  661. if (s.empty())
  662. {
  663. return false;
  664. }
  665. if (pat.empty())
  666. {
  667. return true;
  668. }
  669. if (pat.find('*') == string::npos)
  670. {
  671. return s == pat;
  672. }
  673. string::size_type sIndex = 0;
  674. string::size_type patIndex = 0;
  675. do
  676. {
  677. if (pat[patIndex] == '*')
  678. {
  679. if (s[sIndex] == '.')
  680. {
  681. return false;
  682. }
  683. while (sIndex < s.size() && s[sIndex] != '.')
  684. {
  685. ++sIndex;
  686. }
  687. patIndex++;
  688. }
  689. else
  690. {
  691. if (pat[patIndex] != s[sIndex])
  692. {
  693. return false;
  694. }
  695. ++sIndex;
  696. ++patIndex;
  697. }
  698. } while (sIndex < s.size() && patIndex < pat.size());
  699. return sIndex == s.size() && patIndex == pat.size();
  700. }
  701. bool TC_Common::matchPeriod(const string &s, const vector<string> &pat)
  702. {
  703. for (size_t i = 0; i < pat.size(); i++)
  704. {
  705. if (TC_Common::matchPeriod(s, pat[i]))
  706. {
  707. return true;
  708. }
  709. }
  710. return false;
  711. }
  712. #if TARGET_PLATFORM_LINUX || TARGET_PLATFORM_IOS
  713. void TC_Common::daemon()
  714. {
  715. pid_t pid;
  716. if ((pid = fork()) != 0)
  717. {
  718. exit(0);
  719. }
  720. setsid();
  721. signal(SIGINT, SIG_IGN);
  722. signal(SIGHUP, SIG_IGN);
  723. signal(SIGQUIT, SIG_IGN);
  724. signal(SIGPIPE, SIG_IGN);
  725. signal(SIGTTOU, SIG_IGN);
  726. signal(SIGTTIN, SIG_IGN);
  727. signal(SIGCHLD, SIG_IGN);
  728. signal(SIGTERM, SIG_IGN);
  729. ignorePipe();
  730. if ((pid = fork()) != 0)
  731. {
  732. //父进程结束,变成daemon
  733. exit(0);
  734. }
  735. umask(0);
  736. // chdir("/");
  737. }
  738. void TC_Common::ignorePipe()
  739. {
  740. struct sigaction sig;
  741. memset(&sig, 0, sizeof(struct sigaction));
  742. sig.sa_handler = SIG_IGN;
  743. sig.sa_flags = 0;
  744. sigemptyset(&sig.sa_mask);
  745. sigaction(SIGPIPE, &sig, NULL);
  746. }
  747. #endif
  748. bool TC_Common::isPrimeNumber(size_t n)
  749. {
  750. size_t nn = (size_t)sqrt((double)n);
  751. for(size_t i = 2; i <= nn;i++)
  752. {
  753. if (n % i == 0)
  754. {
  755. return false;
  756. }
  757. }
  758. return true;
  759. }
  760. size_t TC_Common::toSize(const string &s, size_t iDefaultSize)
  761. {
  762. if (s.empty())
  763. {
  764. return iDefaultSize;
  765. }
  766. char c = s[s.length() - 1];
  767. if (c != 'K' && c != 'M' && c != 'G' && TC_Common::trim(s) == TC_Common::tostr(TC_Common::strto<size_t>(s)))
  768. {
  769. //没有后缀, 且转换是正确的
  770. return (size_t) (TC_Common::strto<size_t>(s));
  771. }
  772. else if (c == 'K' || c == 'M' || c == 'G')
  773. {
  774. if (s.length() == 1)
  775. {
  776. return iDefaultSize;
  777. }
  778. float n = TC_Common::strto<float>(s.substr(0, s.length() - 1));
  779. if (TC_Common::trim(s.substr(0, s.length() - 1)) != TC_Common::tostr(n))
  780. {
  781. return iDefaultSize;
  782. }
  783. if (c == 'K')
  784. {
  785. return (size_t) (n * 1024);
  786. }
  787. if (c == 'M')
  788. {
  789. return (size_t) (n * 1024 * 1024);
  790. }
  791. if (c == 'G')
  792. {
  793. return (size_t) (n * 1024 * 1024 * 1024);
  794. }
  795. }
  796. return iDefaultSize;
  797. }
  798. string TC_Common::getHostName()
  799. {
  800. string hostName;
  801. char buff[256] = {0};
  802. int ret = ::gethostname(buff, sizeof(buff));
  803. if (0 == ret)
  804. {
  805. hostName = string(buff);
  806. }
  807. else
  808. {
  809. // 获取不到host, 则直接传空串。
  810. }
  811. return hostName;
  812. }
  813. #if TARGET_PLATFORM_LINUX || TARGET_PLATFORM_IOS
  814. // Generate the randome string, a SHA1-sized random number
  815. void TC_Common::getRandomHexChars(char *p, unsigned int len)
  816. {
  817. const char *const chars = "0123456789abcdef";
  818. FILE *fp = fopen("/dev/urandom", "r");
  819. if (!fp || fread(p, len, 1, fp) == 0)
  820. {
  821. for (unsigned int j = 0; j < len; j++)
  822. p[j] ^= rand();
  823. }
  824. if (fp) fclose(fp);
  825. for (unsigned int j = 0; j < len; j++)
  826. p[j] = chars[p[j] & 0x0F];
  827. }
  828. #endif
  829. string TC_Common::nextDate(const string &sDate)
  830. {
  831. time_t tomorrow = TC_Common::str2time(sDate + "000000", "%Y%m%d%H%M%S") + 60 * 60 * 24;
  832. return TC_Common::tm2str(tomorrow, "%Y%m%d");
  833. }
  834. string TC_Common::prevDate(const string &sDate)
  835. {
  836. time_t tomorrow = TC_Common::str2time(sDate + "000000", "%Y%m%d%H%M%S") - 60 * 60 * 24;
  837. return TC_Common::tm2str(tomorrow, "%Y%m%d");
  838. }
  839. int TC_Common::nextDate(int iDate)
  840. {
  841. return TC_Common::strto<int>(nextDate(TC_Common::tostr(iDate)));
  842. }
  843. int TC_Common::prevDate(int iDate)
  844. {
  845. return TC_Common::strto<int>(prevDate(TC_Common::tostr(iDate)));
  846. }
  847. string TC_Common::nextMonth(const string &sMonth)
  848. {
  849. if (sMonth.length() != 6)
  850. {
  851. return "197001";
  852. }
  853. int year = TC_Common::strto<int>(sMonth.substr(0, 4));
  854. int month = TC_Common::strto<int>(sMonth.substr(4, 2));
  855. int monthNew = month + 1;
  856. int yearNew = year;
  857. if (monthNew == 13)
  858. {
  859. monthNew = 1;
  860. yearNew = year + 1;
  861. }
  862. yearNew = (yearNew >= 1970 && yearNew <= 9999) ? yearNew : 1970;
  863. monthNew = (monthNew >= 1 && monthNew <= 12) ? monthNew : 0;
  864. char szMonth[4] = {0};
  865. snprintf(szMonth, sizeof(szMonth) - 1, "%02d", monthNew);
  866. return TC_Common::tostr(yearNew) + szMonth;
  867. }
  868. string TC_Common::prevMonth(const string &sMonth)
  869. {
  870. if (sMonth.length() != 6)
  871. {
  872. return "197001";
  873. }
  874. int year = TC_Common::strto<int>(sMonth.substr(0, 4));
  875. int month = TC_Common::strto<int>(sMonth.substr(4, 2));
  876. int monthNew = month - 1;
  877. int yearNew = year;
  878. if (monthNew == 0)
  879. {
  880. monthNew = 12;
  881. yearNew = year - 1;
  882. }
  883. yearNew = (yearNew >= 1970 && yearNew <= 9999) ? yearNew : 1970;
  884. monthNew = (monthNew >= 1 && monthNew <= 12) ? monthNew : 0;
  885. char szMonth[4] = {0};
  886. snprintf(szMonth, sizeof(szMonth) - 1, "%02d", monthNew);
  887. return TC_Common::tostr(yearNew) + szMonth;
  888. }
  889. string TC_Common::nextYear(const string &sYear)
  890. {
  891. if (sYear.length() != 4)
  892. {
  893. return "1970";
  894. }
  895. int year = TC_Common::strto<int>(sYear.substr(0, 4));
  896. int yearNew = year + 1;
  897. yearNew = (yearNew >= 1970 && yearNew <= 9999) ? yearNew : 1970;
  898. return TC_Common::tostr(yearNew);
  899. }
  900. string TC_Common::prevYear(const string &sYear)
  901. {
  902. if (sYear.length() != 4)
  903. {
  904. return "1970";
  905. }
  906. int year = TC_Common::strto<int>(sYear.substr(0, 4));
  907. int yearNew = year - 1;
  908. yearNew = (yearNew >= 1970 && yearNew <= 9999) ? yearNew : 1970;
  909. return TC_Common::tostr(yearNew);
  910. }
  911. int TC_Common::secondsToDateInt(time_t seconds)
  912. {
  913. struct tm tt;
  914. TC_Common::tm2tm(seconds, tt);
  915. return (1900 + tt.tm_year) * 10000 + (tt.tm_mon + 1) * 100 + tt.tm_mday;
  916. }
  917. string TC_Common::secondsToDateString(time_t seconds)
  918. {
  919. return TC_Common::tostr(secondsToDateInt(seconds));
  920. }
  921. string TC_Common::secondsToMondayString(time_t seconds)
  922. {
  923. //换到周一
  924. int week = TC_Common::strto<int>(TC_Common::tm2str(seconds, "%w"));
  925. seconds -= (week - 1) * 86400;
  926. return TC_Common::tm2str(seconds, "%Y%m%d");
  927. }
  928. string TC_Common::secondsToMonthString(time_t seconds)
  929. {
  930. return TC_Common::tm2str(seconds, "%Y-%m");
  931. }
  932. string TC_Common::msToTimeString(int64_t ms)
  933. {
  934. int64_t sec = ms / 1000;
  935. int64_t msec = ms % 1000;
  936. char szMS[5] = {0};
  937. snprintf(szMS, sizeof(szMS) - 1, "%03d", (int) msec);
  938. return TC_Common::tm2str(sec, "%Y%m%d-%H%M%S-") + string(szMS);
  939. }
  940. int64_t TC_Common::timeStringToMs(const string &timeStr)
  941. {
  942. vector<string> vt = TC_Common::sepstr<string>(timeStr, "-");
  943. if (vt.size() != 3)
  944. {
  945. return 0;
  946. }
  947. string &date = vt[0];
  948. string &time = vt[1];
  949. string &ms = vt[2];
  950. if (date.size() != 8 || time.size() != 6 || ms.size() != 3)
  951. {
  952. return 0;
  953. }
  954. int64_t lsec = TC_Common::str2time(date + time);
  955. int64_t lms = TC_Common::strto<int64_t>(ms);
  956. return lsec * 1000 + lms;
  957. }
  958. bool TC_Common::getSectionFromMs(int64_t ms, string &date, string &time, string &mstick)
  959. {
  960. string timeStr = msToTimeString(ms);
  961. vector<string> vt = TC_Common::sepstr<string>(timeStr, "-");
  962. if (vt.size() != 3)
  963. {
  964. return false;
  965. }
  966. date = vt[0];
  967. time = vt[1];
  968. mstick = vt[2];
  969. return true;
  970. }
  971. string TC_Common::getDateFromMs(int64_t ms)
  972. {
  973. string date;
  974. string time;
  975. string mstick;
  976. if (!getSectionFromMs(ms, date, time, mstick))
  977. {
  978. return "00000000";
  979. }
  980. return date;
  981. }
  982. string TC_Common::getTimeFromMs(int64_t ms)
  983. {
  984. string date;
  985. string time;
  986. string mstick;
  987. if (!getSectionFromMs(ms, date, time, mstick))
  988. {
  989. return "000000";
  990. }
  991. return time;
  992. }
  993. int TC_Common::msToNowSeconds(int64_t ms)
  994. {
  995. int64_t sec = ms / 1000;
  996. //换成当天的秒
  997. int64_t now = TC_Common::str2time(TC_Common::tm2str(sec, "%Y%m%d") + "000000", "%Y%m%d%H%M%S");
  998. return (sec - now);
  999. }
  1000. int TC_Common::nowDaySeconds()
  1001. {
  1002. return TC_Common::msToNowSeconds(TC_Common::now2ms());
  1003. }
  1004. int64_t TC_Common::msToNowMs(int64_t ms)
  1005. {
  1006. int64_t sec = ms / 1000;
  1007. //换成当天的秒
  1008. int64_t now = TC_Common::str2time(TC_Common::tm2str(sec, "%Y%m%d") + "000000", "%Y%m%d%H%M%S");
  1009. return now * 1000;
  1010. }
  1011. int64_t TC_Common::us()
  1012. {
  1013. struct timeval tv;
  1014. TC_Common::gettimeofday(tv);
  1015. return tv.tv_sec * (int64_t) 1000000 + tv.tv_usec;
  1016. }
  1017. int64_t TC_Common::dateToMs(const string &sDate)
  1018. {
  1019. int64_t now;
  1020. if (sDate.find('-') != string::npos)
  1021. {
  1022. now = TC_Common::str2time(sDate + "000000", "%Y-%m-%d%H%M%S");
  1023. }
  1024. else
  1025. {
  1026. //换成当天的秒
  1027. now = TC_Common::str2time(sDate + "000000", "%Y%m%d%H%M%S");
  1028. }
  1029. return now * 1000;
  1030. }
  1031. int64_t TC_Common::dateToSecond(const string &sDate)
  1032. {
  1033. int64_t now;
  1034. if (sDate.find('-') != string::npos)
  1035. {
  1036. now = TC_Common::str2time(sDate + "000000", "%Y-%m-%d%H%M%S");
  1037. }
  1038. else
  1039. {
  1040. //换成当天的秒
  1041. now = TC_Common::str2time(sDate + "000000", "%Y%m%d%H%M%S");
  1042. }
  1043. return now;
  1044. }
  1045. int TC_Common::dateTo(const string &sDate, const string &sPeriod)
  1046. {
  1047. if (sPeriod == "W")
  1048. {
  1049. return dateToWeek(sDate);
  1050. }
  1051. else if (sPeriod == "M")
  1052. {
  1053. return dateToMonth(sDate);
  1054. }
  1055. else if (sPeriod == "Q")
  1056. {
  1057. return dateToSeason(sDate);
  1058. }
  1059. else if (sPeriod == "S")
  1060. {
  1061. return dateToHalfYear(sDate);
  1062. }
  1063. else if (sPeriod == "Y")
  1064. {
  1065. return dateToYear(sDate);
  1066. }
  1067. return 0;
  1068. }
  1069. int TC_Common::dateToWeekday(const string &sDate)
  1070. {
  1071. struct tm date;
  1072. TC_Common::str2tm(sDate, "%Y%m%d", date);
  1073. return date.tm_wday;
  1074. }
  1075. int TC_Common::dateToWeek(const string &sDate)
  1076. {
  1077. struct tm date;
  1078. TC_Common::str2tm(sDate, "%Y%m%d", date);
  1079. return TC_Common::strto<int>(TC_Common::tm2str(date, "%W"));
  1080. }
  1081. int TC_Common::dateToMonth(const string &sDate)
  1082. {
  1083. return TC_Common::strto<int>(sDate.substr(4, 2));
  1084. }
  1085. int TC_Common::dateToSeason(const string &sDate)
  1086. {
  1087. string month = sDate.substr(4, 2);
  1088. if (month == "01" || (month == "02") || (month == "03"))
  1089. {
  1090. return 1;
  1091. }
  1092. else if (month == "04" || (month == "05") || (month == "06"))
  1093. {
  1094. return 2;
  1095. }
  1096. else if (month == "07" || (month == "08") || (month == "09"))
  1097. {
  1098. return 3;
  1099. }
  1100. else if (month == "10" || (month == "11") || (month == "12"))
  1101. {
  1102. return 4;
  1103. }
  1104. return 0;
  1105. }
  1106. int TC_Common::dateToHalfYear(const string &sDate)
  1107. {
  1108. string month = sDate.substr(4, 2);
  1109. if (month == "01" || (month == "02") || (month == "03") || (month == "04") || (month == "05") || (month == "06"))
  1110. {
  1111. return 1;
  1112. }
  1113. else if (month == "07" || (month == "08") || (month == "09") || (month == "10") || (month == "11") || (month == "12"))
  1114. {
  1115. return 2;
  1116. }
  1117. return 0;
  1118. }
  1119. int TC_Common::dateToYear(const string &sDate)
  1120. {
  1121. return TC_Common::strto<int>(sDate.substr(0, 4));
  1122. }
  1123. int64_t TC_Common::timeToDaySec(int64_t hour, int64_t min)
  1124. {
  1125. return hour * 3600 + min * 60;
  1126. }
  1127. int64_t TC_Common::getNextAbsClockMs(int64_t clockSec)
  1128. {
  1129. int64_t now = TC_Common::now2ms();
  1130. int64_t nowSec = TC_Common::msToNowSeconds(now);
  1131. int64_t currentDateMs = TC_Common::dateToMs(TC_Common::getDateFromMs(now));
  1132. //如果已经超过了通知时间,则改到第二天继续通知
  1133. int64_t notityRealTimeMs = 0;
  1134. if (nowSec > clockSec + 1)
  1135. {
  1136. notityRealTimeMs = currentDateMs + clockSec * 1000 + ONE_DAY_MS;
  1137. }
  1138. else
  1139. {
  1140. notityRealTimeMs = currentDateMs + clockSec * 1000;
  1141. }
  1142. return notityRealTimeMs;
  1143. }
  1144. int TC_Common::nextDate(int iDate, int offset)
  1145. {
  1146. if (offset == 0)
  1147. {
  1148. return iDate;
  1149. }
  1150. else if (offset < 0)
  1151. {
  1152. return prevDate(iDate, std::abs(offset));
  1153. }
  1154. time_t t = TC_Common::str2time(TC_Common::tostr(iDate * 1000000LL));
  1155. t = t + ONE_DAY_SEC * offset;
  1156. return TC_Common::strto<int>(TC_Common::tm2str(t, "%Y%m%d"));
  1157. }
  1158. int TC_Common::prevDate(int iDate, int offset)
  1159. {
  1160. if (offset == 0)
  1161. {
  1162. return iDate;
  1163. }
  1164. else if (offset < 0)
  1165. {
  1166. return nextDate(iDate, std::abs(offset));
  1167. }
  1168. time_t t = TC_Common::str2time(TC_Common::tostr(iDate * 1000000LL));
  1169. t = t - ONE_DAY_SEC * offset;
  1170. return TC_Common::strto<int>(TC_Common::tm2str(t, "%Y%m%d"));
  1171. }
  1172. int TC_Common::lastDate(int iDate, const char period)
  1173. {
  1174. if (period == 'D')
  1175. {
  1176. return iDate;
  1177. }
  1178. switch (period)
  1179. {
  1180. case 'W': // 周日为一周的开始, 周六结束
  1181. {
  1182. struct tm t;
  1183. int rc = TC_Common::str2tm(TC_Common::tostr(iDate), "%Y%m%d", t);
  1184. if (rc != 0)
  1185. {
  1186. return rc;
  1187. }
  1188. if (t.tm_wday == 6)
  1189. {
  1190. return iDate;
  1191. }
  1192. int offset = 6 - t.tm_wday; // 下周六
  1193. return nextDate(iDate, offset);
  1194. }
  1195. case 'M': // 下月一号的上一天是一个月的开始
  1196. {
  1197. int month = iDate / 10000;
  1198. month = iDate - month * 10000;
  1199. month = month / 100;
  1200. int monthDateStart = ((iDate / 10000)) * 10000 + (month + 1) * 100 + 1; // 下月初
  1201. if (month == 12)
  1202. {
  1203. monthDateStart = ((iDate / 10000) + 1) * 10000 + (0 + 1) * 100 + 1; // 下年一月初
  1204. }
  1205. return prevDate(monthDateStart, 1); // 上一天: 上月底
  1206. }
  1207. case 'Q': // 331, 630, 930, 1231
  1208. {
  1209. const int seasonDateEnd[4] = {331, 630, 930, 1231};
  1210. std::function<int(int)> date2season = [](int date)
  1211. {
  1212. int month = date / 10000;
  1213. month = date - month * 10000;
  1214. month = month / 100;
  1215. return ((month - 1) / 3);
  1216. };
  1217. return ((iDate / 10000)) * 10000 + seasonDateEnd[date2season(iDate)];
  1218. }
  1219. case 'S': // 631, 1231
  1220. {
  1221. int tmp = ((iDate / 10000)) * 10000 + 631;
  1222. if (iDate > tmp)
  1223. {
  1224. return ((iDate / 10000)) * 10000 + 1231;
  1225. }
  1226. else
  1227. {
  1228. return tmp;
  1229. }
  1230. }
  1231. break;
  1232. case 'Y': // 1231
  1233. {
  1234. return ((iDate / 10000)) * 10000 + 1231;
  1235. }
  1236. default:
  1237. return -1;
  1238. }
  1239. }
  1240. // 判断两个日期是否在同一周期中
  1241. inline bool TC_Common::matchPeriod(int lastDate, int date, const std::string &period)
  1242. {
  1243. if (lastDate == 0 || date == 0)
  1244. {
  1245. return false;
  1246. }
  1247. if (period == "W")
  1248. {
  1249. int a = TC_Common::dateToWeek(TC_Common::tostr(lastDate));
  1250. int b = TC_Common::dateToWeek(TC_Common::tostr(date));
  1251. return a == b;
  1252. }
  1253. else if (period == "M")
  1254. {
  1255. int a = TC_Common::dateToMonth(TC_Common::tostr(lastDate));
  1256. int b = TC_Common::dateToMonth(TC_Common::tostr(date));
  1257. return a == b;
  1258. }
  1259. else if (period == "Q")
  1260. {
  1261. int a = TC_Common::dateToSeason(TC_Common::tostr(lastDate));
  1262. int b = TC_Common::dateToSeason(TC_Common::tostr(date));
  1263. return a == b;
  1264. }
  1265. else if (period == "S")
  1266. {
  1267. int a = TC_Common::dateToHalfYear(TC_Common::tostr(lastDate));
  1268. int b = TC_Common::dateToHalfYear(TC_Common::tostr(date));
  1269. return a == b;
  1270. }
  1271. else if (period == "Y")
  1272. {
  1273. int a = TC_Common::dateToYear(TC_Common::tostr(lastDate));
  1274. int b = TC_Common::dateToYear(TC_Common::tostr(date));
  1275. return a == b;
  1276. }
  1277. return false;
  1278. }
  1279. int TC_Common::getMatchPeriodDays(const std::vector<int> &days, const std::pair<string, int> &period, std::vector<int> &matchDays)
  1280. {
  1281. std::map<std::string, int> periodList{{"W", 5},
  1282. {"M", 25},
  1283. {"Q", 25 * 3},
  1284. {"S", 25 * 3 * 2},
  1285. {"Y", 256}};
  1286. std::string p = TC_Common::upper(period.first);
  1287. if (periodList.find(p) == periodList.end())
  1288. {
  1289. return -1;
  1290. }
  1291. else if ((periodList.at(p) < std::abs(period.second)) || period.second == 0)
  1292. {
  1293. return -1;
  1294. }
  1295. // 按周期切片
  1296. std::vector<std::vector<int>> slice;
  1297. int lastDate = 0;
  1298. int idx = 0;
  1299. for (auto const d : days)
  1300. {
  1301. if (d <= 0)
  1302. {
  1303. continue;
  1304. }
  1305. // 第一次必然不匹配 lastDate == 0
  1306. if (!TC_Common::matchPeriod(d, lastDate, p))
  1307. {
  1308. lastDate = d;
  1309. slice.emplace_back(std::vector<int>());
  1310. idx++;
  1311. }
  1312. slice[idx - 1].push_back(d);
  1313. }
  1314. // 在周期切片中按下标取对应的数据
  1315. for (auto const &v : slice)
  1316. {
  1317. if (std::abs(period.second) > v.size())
  1318. {
  1319. continue;
  1320. }
  1321. if (period.second > 0)
  1322. {
  1323. matchDays.push_back(v.at(period.second - 1));
  1324. }
  1325. else if (period.second < 0)
  1326. {
  1327. matchDays.push_back(v.at(v.size() + period.second));
  1328. }
  1329. }
  1330. return 0;
  1331. }
  1332. }