C++ 時間處理-日期時間類

  • 1. 關鍵詞
  • 2. 問題
  • 3. 設計理念
  • 4. 支持的能力
  • 5. 代碼實現
    • 5.1. datetime.h
    • 5.2. timecount.cpp
  • 6. 測試代碼
  • 7. 運行結果
  • 8. 源碼地址

1. 關鍵詞

C++ 時間處理 日期時間類 跨平臺

2. 問題

為什么C++就沒有一個方便好用的表示日期時間的類?

同樣是高級語言,Java中有Date,C#中有DateTime,Python中有datetime,為什么C++就沒有一個方便好用的表示日期時間的類?我覺得這是C++ STL的遺憾,在這個點上做的是挺失敗的。C++11之前,處理日期時間一般都會用C語言函數,如:localtime, gmtime, mktime, gettimeofday, put_time等。C++11之后,引入了chrono庫,做到了時間處理的跨平臺化和標準化,時間精度也支持到了納秒級,但是chrono庫的用法非常累贅,一點也不簡潔,如:要以毫秒為單位獲取當前時間戳,他的實現要寫以下這么一長串的代碼。

auto now = std::chrono::system_clock::now();
auto timestamp_ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count();
auto ms = static_cast<uint64_t>(timestamp_ms);

那~ 有沒有更簡潔、漂亮的實現方式呢?

答案是:自己寫一個!

3. 設計理念

  • 極簡
  • 易用
  • 跨平臺

4. 支持的能力

  • 獲取當前時間
  • 獲取UTC時間
  • 格式化時間
  • 從字符串解析時間
  • 時間差計算
  • 時間精度:毫秒級

5. 代碼實現

5.1. datetime.h

#pragma once#include <cstdint>
#include <string>
#include <iostream>
#include <regex>
#include <vector>
#include <utility>namespace cutl
{/*** @brief the string datetime format for parsing and formatting**/enum class datetime_format{/** YYYY-MM-DD HH:MM:SS.sss */datetime_format_a,/** YYYY.MM.DD HH:MM:SS */datetime_format_b,/** YYYY/MM/DD HH:MM:SS */datetime_format_c,/** YYYYMMDD HH:MM:SS */datetime_format_d,};/*** @brief A simple, feature-rich modern C++ date-time class**/class datetime{public:/*** @brief Constants value: second, expressed in milliseconds.**/static constexpr int second = 1000;/*** @brief Constants value: min, expressed in milliseconds.**/static constexpr int min = 60 * second;/*** @brief Constants value: hour, expressed in milliseconds.**/static constexpr int hour = 60 * min;/*** @brief Constants value: day, expressed in milliseconds.**/static constexpr int day = 24 * hour;public:/*** @brief Construct a new datetime object** @param ms a timestamp in milliseconds for initialize the datetime object*/datetime(uint64_t ms);/*** @brief Construct a new datetime object** @param other other datetime object to copy*/datetime(const datetime &other);/*** @brief Destroy the datetime object**/~datetime();private:datetime();public:/*** @brief Get a datetime object for the current system time** @return datetime object for the current system time*/static datetime now();/*** @brief Constructs a datetime object from a local time string.** Only the following time formats are supported:* - YYYY-MM-DD HH:MM:SS.sss* - YYYY-MM-DD HH:MM:SS* - YYYY.MM.DD HH:MM:SS.sss* - YYYY.MM.DD HH:MM:SS* - YYYY/MM/DD HH:MM:SS.sss* - YYYY/MM/DD HH:MM:SS* - YYYYMMDD HH:MM:SS.sss* - YYYYMMDD HH:MM:SS* @param time_text local time string, use the below formats to construct a datetime object.* @param isdst the setting of daylight saving time, -1 means system automatically determine, 0 means not in daylight saving time, 1 means in daylight saving time* @return datetime object constructed from the local time string*/static datetime get(const std::string &time_text, int isdst = -1);public:/*** @brief Get the timestamp in milliseconds** @return the timestamp in milliseconds*/uint64_t timestamp() const;/*** @brief format the datetime object to a string** @param dfmt datetime format, a value of datetime_format enum, default is datetime_format_a* @param local whether to use local time, default is true. if true means output in local time, otherwise, output in UTC time.* @param show_milliseconds whether to show milliseconds, default is true. if true means show milliseconds, otherwise, not show milliseconds.* @return formatted datetime string described by std::string*/std::string format(datetime_format dfmt = datetime_format::datetime_format_a, bool local = true, bool show_milliseconds = true) const;// fmt, usages like std::put_time/*** @brief Format the datetime object to a string with a custom format string** @param fmt datetime format string, default is "%Y-%m-%d %H:%M:%S.%f". usages like std::put_time, reference to https://en.cppreference.com/w/cpp/io/manip/put_time* @param local whether to use local time, default is true. if true means output in local time, otherwise, output in UTC time.* @param show_milliseconds whether to show milliseconds, default is true. if true means show milliseconds, otherwise, not show milliseconds.* @return formatted datetime string described by std::string*/std::string format(const std::string &fmt, bool local = true, bool show_milliseconds = true) const;/*** @brief Get the string of UTC time described by datetime object** @return the string of UTC time in format "YYYY-MM-DD HH:MM:SS.sss"*/std::string utctime() const{return format(datetime_format::datetime_format_a, false);}/*** @brief Define the assignment operator** @param other other datetime object to copy* @return datetime& the reference of the current datetime object*/datetime &operator=(const datetime &other);/*** @brief Define the addition operator** @param ms milliseconds to add* @return datetime object after adding milliseconds*/datetime operator+(uint64_t ms);/*** @brief Define the subtraction operator** @param ms milliseconds to subtract* @return datetime object after subtracting milliseconds*/datetime operator-(uint64_t ms);/*** @brief Define the addition and assignment operator** @param ms milliseconds to add* @return datetime& the reference of the current datetime object after adding milliseconds*/datetime &operator+=(uint64_t ms);/*** @brief Define the subtraction and assignment operator** @param ms milliseconds to subtract* @return datetime& the reference of the current datetime object after subtracting milliseconds*/datetime &operator-=(uint64_t ms);/*** @brief Define the subtraction operator between two datetime objects** @param other datetime object to subtract* @return the duration in milliseconds between current and other datetime objects*/int64_t operator-(const datetime &other) const;private:using time_regex_type = std::pair<std::string, std::regex>;using time_regex_vec_type = std::vector<time_regex_type>;static std::string supported_time_formats(const time_regex_vec_type &fmtlist);static bool verify_time(const struct tm &time);private:uint64_t timestamp_ms_;};/*** @brief Define the output stream operator for datetime object** @param os the std::ostream object* @param dt the datetime object to be output* @return std::ostream& the reference of the std::ostream object after outputting the datetime object*/std::ostream &operator<<(std::ostream &os, const datetime &dt);} // namespace

5.2. timecount.cpp

#include "datetime.h"
#include "timeutil.h"
#include "strfmt.h"
#include "inner/logger.h"namespace cutl
{datetime::datetime(const datetime &other){timestamp_ms_ = other.timestamp_ms_;}datetime::datetime(){timestamp_ms_ = 0;}datetime::datetime(uint64_t ms) : timestamp_ms_(ms){}datetime::~datetime(){}datetime datetime::now(){return datetime(cutl::timestamp(timeunit::ms));}datetime datetime::get(const std::string &time_text, int isdst){std::smatch matchRes;bool result = false;static time_regex_vec_type fmt_list = {// 0/1, 2/3, 4/5, 6/7的順序不能反,因為不含毫秒數的時間會被優先匹配到std::make_pair("YYYY-MM-DD HH:MM:SS.sss", std::regex(R"((\d{4})-(\d{2})-(\d{2})[ ](\d{2}):(\d{2}):(\d{2}).(\d{3}))")),std::make_pair("YYYY-MM-DD HH:MM:SS", std::regex(R"((\d{4})-(\d{2})-(\d{2})[ ](\d{2}):(\d{2}):(\d{2}))")),std::make_pair("YYYY.MM.DD HH:MM:SS.sss", std::regex(R"((\d{4}).(\d{2}).(\d{2})[ ](\d{2}):(\d{2}):(\d{2}).(\d{3}))")),std::make_pair("YYYY.MM.DD HH:MM:SS", std::regex(R"((\d{4}).(\d{2}).(\d{2})[ ](\d{2}):(\d{2}):(\d{2}))")),std::make_pair("YYYY/MM/DD HH:MM:SS.sss", std::regex(R"((\d{4})/(\d{2})/(\d{2})[ ](\d{2}):(\d{2}):(\d{2}).(\d{3}))")),std::make_pair("YYYY/MM/DD HH:MM:SS", std::regex(R"((\d{4})/(\d{2})/(\d{2})[ ](\d{2}):(\d{2}):(\d{2}))")),std::make_pair("YYYYMMDD HH:MM:SS.sss", std::regex(R"((\d{4})(\d{2})(\d{2})[ ](\d{2}):(\d{2}):(\d{2}).(\d{3}))")),std::make_pair("YYYYMMDD HH:MM:SS", std::regex(R"((\d{4})(\d{2})(\d{2})[ ](\d{2}):(\d{2}):(\d{2}))")),};for (size_t i = 0; i < fmt_list.size(); i++){auto &fmt_text = fmt_list[i].first;auto &fmt_pattern = fmt_list[i].second;result = std::regex_search(time_text, matchRes, fmt_pattern);if (result){CUTL_DEBUG("matched regex: " + fmt_text);break;}}if (!result || matchRes.size() < 7){auto time_fmts = supported_time_formats(fmt_list);CUTL_ERROR("Only the following time formats are supported:\n" + time_fmts);return datetime();}CUTL_DEBUG("matchRes size:" + std::to_string(matchRes.size()) + ", res:" + matchRes[0].str());// 解析毫秒值int ms = 0;if (matchRes.size() == 8){ms = std::stoi(matchRes[7].str());}// 解析tm結構的時間struct tm time = {};if (matchRes.size() >= 7){for (size_t i = 1; i < 7; i++){time.tm_year = std::stoi(matchRes[1]);time.tm_mon = std::stoi(matchRes[2]);time.tm_mday = std::stoi(matchRes[3]);time.tm_hour = std::stoi(matchRes[4]);time.tm_min = std::stoi(matchRes[5]);time.tm_sec = std::stoi(matchRes[6]);time.tm_isdst = isdst;}}if (!verify_time(time)){return datetime();}// 轉換為時間戳time.tm_year -= 1900;time.tm_mon -= 1;auto ret = mktime(&time);if (ret == -1){CUTL_ERROR("mktime() failed");return datetime();}auto s = static_cast<uint64_t>(ret);return datetime(s2ms(s) + ms);}uint64_t datetime::timestamp() const{return timestamp_ms_;}std::string get_format_str(datetime_format fmt){std::string text;switch (fmt){case datetime_format::datetime_format_a: // YYYY-MM-DD HH:MM:SStext = "%Y-%m-%d %H:%M:%S";break;case datetime_format::datetime_format_b: // YYYY.MM.DD HH:MM:SStext = "%Y.%m.%d %H:%M:%S";break;case datetime_format::datetime_format_c: // YYYY/MM/DD HH:MM:SStext = "%Y/%m/%d %H:%M:%S";break;case datetime_format::datetime_format_d: // YYYYMMDD HH:MM:SStext = "%Y%m%d %H:%M:%S";break;default:break;}return text;}std::string datetime::format(datetime_format fmt, bool local, bool show_milliseconds) const{auto fmtstr = get_format_str(fmt);auto s = timestamp_ms_ / 1000;auto ms = timestamp_ms_ % 1000;auto text = fmt_timestamp(s, local, fmtstr);if (show_milliseconds){text += "." + fmt_uint(ms, 3);}return text;}std::string datetime::format(const std::string &fmt, bool local, bool show_milliseconds) const{auto s = timestamp_ms_ / 1000;auto ms = timestamp_ms_ % 1000;auto text = fmt_timestamp(s, local, fmt);if (show_milliseconds){text += "." + fmt_uint(ms, 3);}return text;}datetime &datetime::operator=(const datetime &other){if (this == &other){return *this;}timestamp_ms_ = other.timestamp_ms_;return *this;}datetime datetime::operator+(uint64_t ms){datetime dt(*this);dt.timestamp_ms_ += ms;return dt;}datetime datetime::operator-(uint64_t ms){datetime dt(*this);dt.timestamp_ms_ -= ms;return dt;}datetime &datetime::operator+=(uint64_t ms){timestamp_ms_ += ms;return *this;}datetime &datetime::operator-=(uint64_t ms){timestamp_ms_ -= ms;return *this;}int64_t datetime::operator-(const datetime &other) const{int64_t diff = timestamp_ms_ - other.timestamp_ms_;return diff;}std::string datetime::supported_time_formats(const time_regex_vec_type &fmtlist){std::string time_fmts;for (size_t i = 0; i < fmtlist.size(); i++){time_fmts += fmtlist[i].first + "\n";}return time_fmts;}bool datetime::verify_time(const struct tm &time){// 校驗年if (time.tm_year < 1900){CUTL_ERROR("the year should be >= 1900");return false;}// 校驗月if (time.tm_mon < 1 || time.tm_mon > 12){CUTL_ERROR("the month should be between 1 and 12");return false;}// 校驗日std::vector<int> large_month = {1, 3, 5, 7, 8, 10, 12};if (std::find(large_month.begin(), large_month.end(), time.tm_mon) != large_month.end() && (time.tm_mday < 1 || time.tm_mday > 31)){CUTL_ERROR("the day should be between 1 and 31 for " + std::to_string(time.tm_mon) + " month");return false;}std::vector<int> small_month = {4, 6, 9, 11};if (std::find(small_month.begin(), small_month.end(), time.tm_mon) != small_month.end() && (time.tm_mday < 1 || time.tm_mday > 30)){CUTL_ERROR("the day should be between 1 and 30 for " + std::to_string(time.tm_mon) + " month");return false;}if (time.tm_mon == 2){auto is_leap_year = [](int year){ return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0); };if (is_leap_year(time.tm_year) && (time.tm_mday < 1 || time.tm_mday > 29)){CUTL_ERROR("the day should be between 1 and 29 for " + std::to_string(time.tm_year) + "-" + fmt_uint(time.tm_mon, 2));return false;}if (!is_leap_year(time.tm_year) && (time.tm_mday < 1 || time.tm_mday > 28)){CUTL_ERROR("the day should be between 1 and 28 for " + std::to_string(time.tm_year) + "-" + fmt_uint(time.tm_mon, 2));return false;}}// 校驗時分秒if (time.tm_hour < 0 || time.tm_hour > 23){CUTL_ERROR("the hour should be between 0 and 23");return false;}if (time.tm_min < 0 || time.tm_min > 59){CUTL_ERROR("the minute should be between 0 and 59");return false;}if (time.tm_sec < 0 || time.tm_sec > 59){CUTL_ERROR("the second should be between 0 and 59");return false;}return true;}std::ostream &operator<<(std::ostream &os, const datetime &dt){os << dt.format();return os;}} // namespace

6. 測試代碼

#pragma once#include <iostream>
#include "datetime.h"
#include "common.hpp"void TestDatetimeBasicUsage()
{PrintSubTitle("TestDatetimeBasicUsage");auto now = cutl::datetime::now();std::cout << "current timestamp(ms): " << now.timestamp() << std::endl;std::cout << "current time(UTC time): " << now.utctime() << std::endl;std::cout << "current time(local time): " << now.format() << std::endl;std::cout << "current time(UTC time) format b: " << now.format(cutl::datetime_format::datetime_format_b, false, true) << std::endl;std::cout << "current time(UTC time) format b, don't show milliseconds: " << now.format(cutl::datetime_format::datetime_format_b, false, false) << std::endl;std::cout << "current time(UTC time) format c: " << now.format(cutl::datetime_format::datetime_format_c, false, true) << std::endl;std::cout << "current time(UTC time) format d: " << now.format(cutl::datetime_format::datetime_format_d, false, true) << std::endl;std::cout << "current time(UTC time) custom format 1: " << now.format("%c %Z", false, true) << std::endl;std::cout << "current time(UTC time) custom format 2: " << now.format("%m/%d/%Y/ %H:%M:%S", false, false) << std::endl;
}void TestDatetimeOperator()
{// 運算符重載PrintSubTitle("TestDatetimeOperator");std::cout << "one day == " << cutl::datetime::day << "ms" << std::endl;std::cout << "one hour == " << cutl::datetime::hour << "ms" << std::endl;std::cout << "one minute == " << cutl::datetime::min << "ms" << std::endl;auto now = cutl::datetime::now();std::cout << "current time: " << now << std::endl;auto dt1 = now - cutl::datetime::min;std::cout << "before one minute: " << dt1 << std::endl;// std::cout << "current time 1: " << now << std::endl;auto dt2 = now + cutl::datetime::min;std::cout << "after one minute: " << dt2 << std::endl;// std::cout << "current time 2: " << now << std::endl;now -= (2 * cutl::datetime::hour);std::cout << "before two hours: " << now << std::endl;now += (4 * cutl::datetime::hour);std::cout << "after two hours: " << now << std::endl;auto dt3 = cutl::datetime::get("2024-03-01 10:00:00");auto dt4 = cutl::datetime::get("2024-03-30 14:18:44");auto duration1 = dt4 - dt3;std::cout << "the difference between " << dt3 << " and " << dt4 << " is: " << duration1 << "ms, formatted: " << cutl::fmt_timeduration_ms(duration1) << std::endl;auto duration2 = dt3 - dt4;std::cout << "the difference between " << dt4 << " and " << dt3 << " is: " << duration2 << "ms" << std::endl;
}void TestDatetimeParseString()
{// 字符串解析成時間PrintSubTitle("TestDatetimeParseString");auto dt0 = cutl::datetime::get(" 2024-03-02 14:18:44 ");std::cout << "dt0: " << dt0 << std::endl;auto dt1 = cutl::datetime::get(" 2024-03-02 14:18:44.023 ");std::cout << "dt1: " << dt1 << std::endl;auto dt2 = cutl::datetime::get(" 2024.03.12 14:18:44");std::cout << "dt2: " << dt2 << std::endl;auto dt3 = cutl::datetime::get(" 2024.03.12 14:18:44.003");std::cout << "dt3: " << dt3 << std::endl;auto dt4 = cutl::datetime::get("2024/03/22 14:18:44 ");std::cout << "dt4: " << dt4 << std::endl;auto dt5 = cutl::datetime::get("2024/03/22 14:18:44.200 ");std::cout << "dt5: " << dt5 << std::endl;auto dt6 = cutl::datetime::get("2024/03/23 09:28:04");std::cout << "dt6: " << dt6 << std::endl;auto dt7 = cutl::datetime::get("2024/03/23 09:28:04.276");std::cout << "dt7: " << dt7 << std::endl;// format errorauto dt8 = cutl::datetime::get(" 2024-0322 14:18:44 ");std::cout << "dt8: " << dt8 << std::endl;// mounth errorauto dt9 = cutl::datetime::get(" 2024-13-02 14:18:44 ");std::cout << "dt9: " << dt9 << std::endl;// leap year errorauto dt10 = cutl::datetime::get(" 2023-02-29 14:18:44 ");std::cout << "dt10: " << dt10 << std::endl;// day errorauto dt11 = cutl::datetime::get(" 2024-03-42 14:18:44 ");std::cout << "dt11: " << dt11 << std::endl;// year > 2038auto dt12 = cutl::datetime::get(" 2044-03-02 14:18:44 ");std::cout << "dt12: " << dt12 << std::endl;std::cout << "dt12 timestamp: " << dt12.timestamp() << std::endl;
}void TestDatetime()
{PrintTitle("datetime");TestDatetimeBasicUsage();TestDatetimeOperator();TestDatetimeParseString();
}

7. 運行結果

==============================================datetime==============================================
---------------------------------------TestDatetimeBasicUsage---------------------------------------
current timestamp(ms): 1716129275853
current time(UTC time): 2024-05-19 14:34:35.853
current time(local time): 2024-05-19 22:34:35.853
current time(UTC time) format b: 2024.05.19 14:34:35.853
current time(UTC time) format b, don't show milliseconds: 2024.05.19 14:34:35
current time(UTC time) format c: 2024/05/19 14:34:35.853
current time(UTC time) format d: 20240519 14:34:35.853
current time(UTC time) custom format 1: Sun May 19 14:34:35 2024 UTC.853
current time(UTC time) custom format 2: 05/19/2024/ 14:34:35
----------------------------------------TestDatetimeOperator----------------------------------------
one day == 86400000ms
one hour == 3600000ms
one minute == 60000ms
current time: 2024-05-19 22:34:35.854
before one minute: 2024-05-19 22:33:35.854
after one minute: 2024-05-19 22:35:35.854
before two hours: 2024-05-19 20:34:35.854
after two hours: 2024-05-20 00:34:35.854
the difference between 2024-03-01 10:00:00.000 and 2024-03-30 14:18:44.000 is: 2521124000ms, formatted: 29d:04h:18m:44s.000ms
the difference between 2024-03-30 14:18:44.000 and 2024-03-01 10:00:00.000 is: -2521124000ms
--------------------------------------TestDatetimeParseString---------------------------------------
dt0: 2024-03-02 14:18:44.000
dt1: 2024-03-02 14:18:44.023
dt2: 2024-03-12 14:18:44.000
dt3: 2024-03-12 14:18:44.003
dt4: 2024-03-22 14:18:44.000
dt5: 2024-03-22 14:18:44.200
dt6: 2024-03-23 09:28:04.000
dt7: 2024-03-23 09:28:04.276
[2024-05-19 22:34:35.857][E]]0x7ff844a9b100](cutl) [datetime.cpp:79:get] Only the following time formats are supported:
YYYY-MM-DD HH:MM:SS.sss
YYYY-MM-DD HH:MM:SS
YYYY.MM.DD HH:MM:SS.sss
YYYY.MM.DD HH:MM:SS
YYYY/MM/DD HH:MM:SS.sss
YYYY/MM/DD HH:MM:SS
YYYYMMDD HH:MM:SS.sss
YYYYMMDD HH:MM:SSdt8: 1970-01-01 08:00:00.000
[2024-05-19 22:34:35.857][E]]0x7ff844a9b100](cutl) [datetime.cpp:241:verify_time] the month should be between 1 and 12
dt9: 1970-01-01 08:00:00.000
[2024-05-19 22:34:35.857][E]]0x7ff844a9b100](cutl) [datetime.cpp:268:verify_time] the day should be between 1 and 28 for 2023-02
dt10: 1970-01-01 08:00:00.000
[2024-05-19 22:34:35.858][E]]0x7ff844a9b100](cutl) [datetime.cpp:248:verify_time] the day should be between 1 and 31 for 3 month
dt11: 1970-01-01 08:00:00.000
dt12: 2044-03-02 14:18:44.000
dt12 timestamp: 2340512324000

8. 源碼地址

更多詳細代碼,請查看本人寫的C++ 通用工具庫: common_util, 本項目已開源,代碼簡潔,且有詳細的文檔和Demo。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/13763.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/13763.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/13763.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

2024 HGDD 榮耀開發者日·成都站

HGDD 榮耀開發者日成都站 活動時間&#xff1a;2024 年 5 月 27 日 活動地點&#xff1a;成都市雙流區 LA CADIERE 蔚藍湖濱城 期待與大家的見面&#xff01;

ISO 9001認證 要換版了!

ISO TC176/SC2 第50次會議2023年10月8日至13日在盧旺達基加利舉行。 會議確定ISO 9001標準的修訂從2024年1月開始&#xff0c;將包括WD&#xff08;Working Draft&#xff09;、CD&#xff08; Committee Draft&#xff09;、DIS&#xff08;Draft for International Standard&…

js+vue3+elementplus發送驗證碼實現(含倒計時重新發送)

<template><el-form :model"formValue" :rules"rules" ref"form"><el-form-item prop"phone"><el-input v-model.number"formValue.phone" class"form-input" placeholder"請輸入手機號…

[matlab]yalmip國內源yalmip下載地址所有版本匯總

概述 MATLAB是一個強大的數值計算工具&#xff0c;用于數學建模、算法開發和數據分析。在MATLAB中&#xff0c;有很多工具箱可以幫助用戶完成不同類型的任務。本文將介紹如何在MATLAB中安裝Yalmip和Cplex&#xff0c;這兩個工具箱可以幫助用戶解決優化問題。 如果不想看文字描…

【oracle004】oracle內置函數手冊總結(已更新)

1.熟悉、梳理、總結下oracle相關知識體系。 2.日常研發過程中使用較少&#xff0c;隨著時間的推移&#xff0c;很快就忘得一干二凈&#xff0c;所以梳理總結下&#xff0c;以備日常使用參考 3.歡迎批評指正&#xff0c;跪謝一鍵三連&#xff01; 總結源文件資源下載地址&#x…

RoctetMQ使用(2):在項目中使用

一、導入相關依賴 在項目中引入MQ客戶端依賴&#xff0c;依賴版本最好和RocketMQ版本一致。 <!-- rocket客戶端--><dependency><groupId>org.apache.rocketmq</groupId><artifactId>rocketmq-client</artifactId><version&…

npm常用指令

基礎 命令&#xff1a;run 解釋&#xff1a;運行腳本 示例&#xff1a;npm run dev 命令&#xff1a;list || ls 解釋&#xff1a;查看依賴列表 示例&#xff1a;npm list || npm ls 命令&#xff1a;install || i 解釋&#xff1a;安裝依賴 示例&#xff1a;npm install ||…

一文掌握python隨機數random模塊

目錄 一、常用函數 1、 random.random() 2、random.uniform(a, b) 3、random.randint(a, b) 4、random.randrange(start, stop[, step]) 5、random.choice(sequence) 6、random.shuffle(x[, random]) 7、random.sample(population, k) 8、random.choices(population, w…

Qml:錨點

import QtQuick import QtQuick.WindowWindow {width: 800height: 600visible: truetitle: qsTr("Test Anchors")///錨點 上下左右Rectangle{id: anchor1width:200height: 150color:"#EEEEEE"Rectangle{id:rect1width:50height:50color: "red"Te…

Ubuntu 20/22 安裝 Jenkins

1. 使用 apt 命令安裝 Java Jenkins 作為一個 Java 應用程序&#xff0c;要求 Java 8 及更高版本&#xff0c;檢查系統上是否安裝了 Java。 sudo apt install -y openjdk-17-jre-headless安裝完成后&#xff0c;再次驗證 Java 是否已安裝 java --version2. 通過官方存儲庫安…

動態地控制kafka的消費速度,從而滿足業務要求

kafka是一個分布式流媒體平臺&#xff0c;它可以處理大規模的數據流&#xff0c;并允許實時消費該數據流。在實際應用中&#xff0c;我們需要動態控制kafka消費速度&#xff0c;以便處理數據流的速率能夠滿足系統和業務的需求。本文將介紹如何在kafka中實現動態控制消費速度的方…

APH-Archives of Public Health

文章目錄 一、期刊簡介二、征稿信息三、期刊表現四、投稿須知五、投稿咨詢 一、期刊簡介 Archives of Public Health是一份范圍廣泛的公共衛生雜志&#xff0c;致力于出版公共衛生領域所有可靠的科學。該雜志旨在更好地了解人群的健康。該雜志有助于公共衛生知識&#xff0c;加…

【考研數學】李林《880》是什么難度水平強化夠用嗎

880是公認的質量高&#xff0c;但要是刷的方法不對&#xff0c;心態直接炸裂&#xff01;&#x1f649; 我24年二戰就是用的 880660 的黃金搭檔&#xff0c;143分逆襲上岸211&#xff01;&#xff08;為什么說逆襲呢&#xff0c;因為我23年一戰數學83&#xff0c;妥妥的菜雞&am…

2024.5.20 學習記錄

1、react 原理&#xff08;jsx的本質、事件機制原理、setState和batch Update、組件渲染更新和diff算法、fiber&#xff09; 2、代碼隨想錄貪心刷題

ArcGIS10.X入門實戰視頻教程(arcgis入門到精通)

點擊學習&#xff1a; ArcGIS10.X入門實戰視頻教程&#xff08;GIS思維&#xff09;https://edu.csdn.net/course/detail/4046?utm_sourceblog2edu 點擊學習&#xff1a; ArcGIS10.X入門實戰視頻教程&#xff08;GIS思維&#xff09;https://edu.csdn.net/course/detail/404…

銀河麒麟操作系統下使用QT連接TiDB數據庫開發步驟

目標:實現項目軟件+硬件都運行在國產化操作系統平臺上。 方法:在虛擬機中安裝麒麟系統V10Sp1+Qt5.14.2+MySql8.0+TiDB軟件,編譯MySql驅動,測試連接TiDB數據庫項目。 步驟: 1、使用虛擬機軟件VMWare安裝銀河麒麟操作系統。 2、在銀河麒麟系統上安裝QT5.14.2軟件。 3、…

Web Server項目實戰3-Web服務器簡介及HTTP協議

Web Server&#xff08;網頁服務器&#xff09; 一個 Web Server 就是一個服務器軟件&#xff08;程序&#xff09;&#xff0c;或者是運行這個服務器軟件的硬件&#xff08;計算機&#xff09;。其主要功能是通過 HTTP 協議與客戶端&#xff08;通常是瀏覽器&#xff08;Brow…

【精品】使用 v-md-editor 上傳圖片

簡介 v-md-editor 是基于 Vue 開發的 markdown 編輯器組件&#xff0c;即支持vue2也支持vue3。 gitee&#xff1a;https://gitee.com/ckang1229/vue-markdown-editor文檔&#xff1a;https://code-farmer-i.github.io/vue-markdown-editor/zh/ 服務器端代碼 RestController…

[Cocos Creator 3.5賽車游戲]第5節 為汽車節點掛載自定義腳本

在前面的章節中您已經學會了如何創建一個汽車節點&#xff0c;這一章我們將會學習如何通過掛載自定義節點的方式讓小車變得可控制&#xff0c;所以通過這一章的學習后&#xff0c;您將實現一個效果&#xff1a;開始運行后&#xff0c;小車每隔一幀就延y軸向上移動一段距離。在這…

cx_Oracle Python 庫連接 Oracle 數據庫時遇到報錯

這個錯誤 DPI-1047: Cannot locate a 64-bit Oracle Client library: "The specified module could not be found" 是在嘗試使用 cx_Oracle Python 庫連接 Oracle 數據庫時遇到的。這個錯誤表明 cx_Oracle 無法找到 Oracle 客戶端庫&#xff08;通常稱為 Instant Cli…