引言

  业务代码中遇到这样需求, 1. 二者是同一天吗, 2. 时间戳和时间串来回转, 3. 其它扩展需求 等.

C写代码同样需要处理这方面时间问题. 本文就是为了解决这个问题. 相比其它时间库, 这里做了一些扩展. 一般而言

一天开始时间为 00:00:00 , 这里 可以配置一天的开始时间.

  举一个实际用的业务例子. 暴雪游戏, 魔兽世界 或者 炉石传说, 每次活动刷新都是以 05:00:00 开始.

这里说明了什么呢, 可以理解为这类游戏世界里, 时间循环的起点就是"05:00:00". 认为是一天的开始.

同样我们的写的sctimeutil.h 接口中有一个配置 一天的开始时间.

当然代码一定是跨平台的. 首先我们看一下 sctimeutil.h 接口设计思路如下:

#ifndef _H_SCTIMEUTIL
#define _H_SCTIMEUTIL #include <time.h>
#include <stdbool.h> // 为Visual Studio导入一些和linux上优质思路
#if defined(_MSC_VER) #include <Windows.h> /*
* 返回当前得到的时间结构体, 高仿linux上调用
* pt : const time_t * , 输入的时间戳指针
* ptm : struct tm * , 输出的时间结构体
* : 返回 ptm 值
*/
#define localtime_r(pt, ptm) localtime_s(ptm, pt), ptm /*
* Linux sys/time.h 中获取时间函数在Windows上一种移植实现
* tv : 返回结果包含秒数和微秒数
* tz : 包含的时区,在window上这个变量没有用不返回
* : 默认返回0
*/
extern int gettimeofday(struct timeval* tv, void* tz); #endif // 定义每天是开始为 0时0分0秒
#define _INT_MINSECOND (60)
#define _INT_HOURSECOND (3600)
#define _INT_DAYSECOND (24UL*_INT_HOURSECOND)
#define _INT_DAYSTART (8UL*_INT_HOURSECOND)
// 定义每天新的开始时间
#define _INT_DAYNEWSTART (0UL*_INT_HOURSECOND + 0*_INT_MINSECOND + 0) // struct tm 中 tm_year, tm_mon 用的偏移量
#define _INT_YEAROFFSET (1900)
#define _INT_MONOFFSET (1) // 定义时间串类型
#define _INT_STULEN (32)
typedef char stime_t[_INT_STULEN]; /*
* 将 [2016-7-10 21:22:34] 格式字符串转成时间戳
* tstr : 时间串分隔符只能是单字节的.
* pt : 返回得到的时间戳
* otm : 返回得到的时间结构体
* : 返回这个字符串转成的时间戳, -1表示构造失败
*/
extern bool stu_gettime(stime_t tstr, time_t * pt, struct tm * otm); /*
* 判断当前时间戳是否是同一天的.
* lt : 判断时间一
* rt : 判断时间二
* : 返回true表示是同一天, 返回false表示不是
*/
extern bool stu_tisday(time_t lt, time_t rt); /*
* 判断当前时间戳是否是同一周的.
* lt : 判断时间一
* rt : 判断时间二
* : 返回true表示是同一周, 返回false表示不是
*/
extern bool stu_tisweek(time_t lt, time_t rt); /*
* 将时间戳转成时间串 [2016-7-10 22:38:34]
* nt : 当前待转的时间戳
* tstr : 保存的转后时间戳位置
* : 返回传入tstr的首地址
*/
extern char * stu_gettstr(time_t nt, stime_t tstr); /*
* 得到当前时间戳 [2016-7-10 22:38:34]
* tstr : 保存的转后时间戳位置
* : 返回传入tstr的首地址
*/
extern char * stu_getntstr(stime_t tstr); /*
* 判断当前时间串是否是同一天的.
* ls : 判断时间一
* rs : 判断时间二
* : 返回true表示是同一天, 返回false表示不是
*/
extern bool stu_sisday(stime_t ls, stime_t rs); /*
* 判断当前时间串是否是同一周的.
* ls : 判断时间一
* rs : 判断时间二
* : 返回true表示是同一周, 返回false表示不是
*/
extern bool stu_sisweek(stime_t ls, stime_t rs); #endif // !_H_SCTIMEUTIL

设计接口了解后, 后面会详细解说. (代码对齐确实不好弄, 要是博客园直接能让VS复制的代码格式, 到富文本框中不改变, 那得多好.)

设计师才是王道.

前言

  先看宏配置, 主要的就是

// 定义每天新的开始时间
#define _INT_DAYNEWSTART (0UL*_INT_HOURSECOND + 0*_INT_MINSECOND + 0)

假如需要设置一天开始为05:00:00, 那就将第一个0变成5就可以了.  后面还定义了时间串类型

// 定义时间串类型
#define _INT_STULEN (32)
typedef char stime_t[_INT_STULEN];

默认就是 char [32]长度的字符串. 统一类型在栈上并节省一个长度参数, 否则一般得到时间串 至少 char [], int 两个参数.

其它的变量宏, 都是为了去掉魔法数字用的.  最前面有段为VS导入扩展功能的宏

// 为Visual Studio导入一些和linux上优质思路
#if defined(_MSC_VER) #include <Windows.h> /*
* 返回当前得到的时间结构体, 高仿linux上调用
* pt : const time_t * , 输入的时间戳指针
* ptm : struct tm * , 输出的时间结构体
* : 返回 ptm 值
*/
#define localtime_r(pt, ptm) localtime_s(ptm, pt), ptm /*
* Linux sys/time.h 中获取时间函数在Windows上一种移植实现
* tv : 返回结果包含秒数和微秒数
* tz : 包含的时区,在window上这个变量没有用不返回
* : 默认返回0
*/
extern int gettimeofday(struct timeval* tv, void* tz); #endif

这两个''声明''在跨平台C代码中出现频率比较高. 第一个是安全可重入的将时间戳变成时间结构体. 第二个是得到更高精度的时间表示.

这里分析一下对于linux上 有这么定义

struct tm *localtime_r(const time_t *timep, struct tm *result);

window 上是下面定义的

static __inline errno_t __CRTDECL localtime_s(struct tm * _Tm, const time_t * _Time)
{
return _localtime32_s(_Tm, _Time);
}

简单的理解为, 位置颠倒了. 其实而言, 细节上还是有不同. 扯一点二者平台都有优点,

但从这个api上而言, 我觉得linux上localtime_r 更自然些, 返回值放在最后面. 随着工作深入也发现,

有些api window设计也很出彩. 但是总的而言, 如果二选一, 还是觉得linux 设计的比window漂亮, 精妙, 自然.

扯回来, 上面为了更大程度上兼容linux, 就在window上采用linux函数设计思路. 是不是有点意思.(另外一种跨平台宏设计思路)

对于 gettimeofday window源码实现如下

// 为Visual Studio导入一些和linux上优质思路
#if defined(_MSC_VER) /*
* Linux sys/time.h 中获取时间函数在Windows上一种移植实现
* tv : 返回结果包含秒数和微秒数
* tz : 包含的时区,在window上这个变量没有用不返回
* : 默认返回0
*/
int
gettimeofday(struct timeval* tv, void* tz) {
struct tm st;
SYSTEMTIME wtm; GetLocalTime(&wtm);
st.tm_year = wtm.wYear - _INT_YEAROFFSET;
st.tm_mon = wtm.wMonth - _INT_MONOFFSET; // window的计数更好些
st.tm_mday = wtm.wDay;
st.tm_hour = wtm.wHour;
st.tm_min = wtm.wMinute;
st.tm_sec = wtm.wSecond;
st.tm_isdst = -; // 不考虑夏令时 tv->tv_sec = (long)mktime(&st); // 32位使用数据强转
tv->tv_usec = wtm.wMilliseconds * ; // 毫秒转成微秒 return ;
} #endif

上面两个宏, 分别是 1900和1, 这个是 struct tm 特性决定的, 这点window api功能设计的好.

#ifndef _TM_DEFINED
struct tm {
int tm_sec; /* seconds after the minute - [0,59] */
int tm_min; /* minutes after the hour - [0,59] */
int tm_hour; /* hours since midnight - [0,23] */
int tm_mday; /* day of the month - [1,31] */
int tm_mon; /* months since January - [0,11] */
int tm_year; /* years since 1900 */
int tm_wday; /* days since Sunday - [0,6] */
int tm_yday; /* days since January 1 - [0,365] */
int tm_isdst; /* daylight savings time flag */
};
#define _TM_DEFINED
#endif

上面就是 struct tm 结构体实现. 时间操作还是比较不统一, 需要一定经验, 多趟坑. 这里时间默认从1900起计算, 也有1970起计算的. 例如(man 手册中内容)

       The ctime(), gmtime() and localtime() functions all take an argument of data type time_t which represents cal‐
       endar  time.   When  interpreted  as an absolute time value, it represents the number of seconds elapsed since
       00:00:00 on January 1, 1970, Coordinated Universal Time (UTC).

需要用到的时候再弄清楚吧. 推荐一定要用可重入的, 否则程序跑起来只能头大了.

正文

  现在准备剖析一下特定的代码, 最后也会贴一下全部代码. 运行一个测试demo. 首先看时间串得到时间戳时间结构体的接口实现

/*
* 将 [2016-7-10 21:22:34] 格式字符串转成时间戳
* tstr : 时间串分隔符只能是单字节的.
* pt : 返回得到的时间戳
* otm : 返回得到的时间结构体
* : 返回这个字符串转成的时间戳, -1表示构造失败
*/
bool
stu_gettime(stime_t tstr, time_t * pt, struct tm * otm) {
time_t t;
struct tm st; if(NULL == tstr)
return false; int rt = sscanf(tstr, "%d%*c%d%*c%d%*c%d%*c%d%*c%d",
&st.tm_year, &st.tm_mon, &st.tm_mday,
&st.tm_hour, &st.tm_min, &st.tm_sec);
if( != rt)
return false; st.tm_year -= _INT_YEAROFFSET;
st.tm_mon -= _INT_MONOFFSET;
// 得到时间戳, 失败返回false
if((t = mktime(&st)) == - )
return false; // 返回最终结果
if(pt)
*pt = t;
if(otm)
*otm = st; return true;
}

思路很清晰, 解析时间串, 得到年月日时分秒, 最后通过mktime得到想要的. 期间需要注意的是 struct tm 必须 year 1900起, mon 从0开始记.

执行mktime之后会补充玩 st 时间结构体 并且返回当前时间戳.

判断两个时间戳是否是同一天也很巧妙

/*
* 判断当前时间戳是否是同一天的.
* lt : 判断时间一
* rt : 判断时间二
* : 返回true表示是同一天, 返回false表示不是
*/
bool
stu_tisday(time_t lt, time_t rt) {
// 得到是各自第几天的
lt = (lt + _INT_DAYSTART - _INT_DAYNEWSTART) / _INT_DAYSECOND;
rt = (rt + _INT_DAYSTART - _INT_DAYNEWSTART) / _INT_DAYSECOND;
return lt == rt;
}

这里用到一个宏

#define _INT_DAYSTART        (8UL*_INT_HOURSECOND)

这个由来是咱们通过mktime 得到的是 标准时区时间, 而中国是东八区, 快了它8h. 详细科普可以看下下面资料

GMT(Greenwich Mean Time)  格林威治时间
即本初子午线的时间,一般作为全球时间的基准参考时间。据说是以格林威治天文台命名的。
UTC(Universal Time Coordinated) 世界标准时间或世界协调时间
协调世界时是以原子时秒长为基础,在时刻上尽量接近于世界时的一种时间计量系统。
UTC时间和GMT时间其实是同一个时间,只不过UTC时间的单位是秒。定期会进行校准,校准的方式是发布闰秒,
即有两个同样的秒。记住,UTC是GMT的以秒为单位的计时。
CST(China Standard Time) 中国标准时间
可以认为新闻联播嘟嘟嘟的时间。也就是东八区的时间。当GMT为0点的时候,我们已经8点了。
我们的时间需要在GMT的时间上加八个小时

有了这些知识, 后面 将两个时间戳变成中国的时间戳. 再除以一天的秒数, 得到当前多少天了. 这里需要注意一下, 这是服务器级别的时间判断.

如果对于军工级别, 宇宙飞船等级别, 真不行, 因为一年民用要么365要么366, 其实一年 查了粗略资料有

地球围绕太阳公转一周(即360度)的时间应该为365日6时9分10秒,即为一个恒星年。

地球的某点获得两次两次直射的间隔是365日5时48分46秒(更加精确:365天5小时48分45.975456秒),即为一个回归年。

总而言之, 计算机还是离散数学级别, 精度只能大致算算, 因此咱们精度到天, 上面算法是可以得了, 对于特别意外的那就看脸了.

(时间判断也是程序国际化会遇到的一个坑, 必遇到滴~~)

从这里觉得软件开发还是偏艺术些, 科学是严谨的, 是符合一切数学规律的, 误差是可以详细分析的.

再看看另一个设计, 比较简单, 时间戳得到时间串

/*
* 将时间戳转成时间串 [2016-7-10 22:38:34]
* nt : 当前待转的时间戳
* tstr : 保存的转后时间戳位置
* : 返回传入tstr的首地址
*/
char * stu_gettstr(time_t nt, stime_t tstr) {
struct tm st;
localtime_r(&nt, &st);
strftime(tstr, sizeof(stime_t), "%F %X", &st);
return tstr;
}

思路很直白吧,最后解释测试一波了. 首先看main.c

#include <stdio.h>
#include <stdlib.h>
#include "sctimeutil.h" static void _sctime_puts(stime_t tstr) {
printf("sizeof tstr = %lu, %lu\n", sizeof tstr, sizeof(stime_t));
} /*
* 处理时间 time 的测试主函数
*
*/
int main(int argc, char * argv[]) {
bool rt;
time_t t;
struct tm tm;
stime_t ts; rt = stu_gettime("2016-7-12 11:27:00", &t, &tm);
printf("tm.tm_year = %d, tm.tm_yday = %d\n", tm.tm_year, tm.tm_yday); // 测试数组长度
_sctime_puts(NULL); rt = stu_sisweek("2016-7-11 20:59:59", "2016-7-17 23:59:59");
printf("rt = %d\n", rt); rt = stu_sisweek("2016-7-11 0:0:0", "2016-7-18 0:0:0");
printf("rt = %d\n", rt); // 输出当前时间量
puts(stu_getntstr(ts)); return ;
}

附加代码文件

sctimeutil.h

#ifndef _H_SCTIMEUTIL
#define _H_SCTIMEUTIL #include <time.h>
#include <stdbool.h> // 为Visual Studio导入一些和linux上优质思路
#if defined(_MSC_VER) #include <Windows.h> /*
* 返回当前得到的时间结构体, 高仿linux上调用
* pt : const time_t * , 输入的时间戳指针
* ptm : struct tm * , 输出的时间结构体
* : 返回 ptm 值
*/
#define localtime_r(pt, ptm) localtime_s(ptm, pt), ptm /*
* Linux sys/time.h 中获取时间函数在Windows上一种移植实现
* tv : 返回结果包含秒数和微秒数
* tz : 包含的时区,在window上这个变量没有用不返回
* : 默认返回0
*/
extern int gettimeofday(struct timeval* tv, void* tz); #endif // 定义每天是开始为 0时0分0秒
#define _INT_MINSECOND (60)
#define _INT_HOURSECOND (3600)
#define _INT_DAYSECOND (24UL*_INT_HOURSECOND)
#define _INT_DAYSTART (8UL*_INT_HOURSECOND)
// 定义每天新的开始时间
#define _INT_DAYNEWSTART (0UL*_INT_HOURSECOND + 0*_INT_MINSECOND + 0) // struct tm 中 tm_year, tm_mon 用的偏移量
#define _INT_YEAROFFSET (1900)
#define _INT_MONOFFSET (1) // 定义时间串类型
#define _INT_STULEN (32)
typedef char stime_t[_INT_STULEN]; /*
* 将 [2016-7-10 21:22:34] 格式字符串转成时间戳
* tstr : 时间串分隔符只能是单字节的.
* pt : 返回得到的时间戳
* otm : 返回得到的时间结构体
* : 返回这个字符串转成的时间戳, -1表示构造失败
*/
extern bool stu_gettime(stime_t tstr, time_t * pt, struct tm * otm); /*
* 判断当前时间戳是否是同一天的.
* lt : 判断时间一
* rt : 判断时间二
* : 返回true表示是同一天, 返回false表示不是
*/
extern bool stu_tisday(time_t lt, time_t rt); /*
* 判断当前时间戳是否是同一周的.
* lt : 判断时间一
* rt : 判断时间二
* : 返回true表示是同一周, 返回false表示不是
*/
extern bool stu_tisweek(time_t lt, time_t rt); /*
* 将时间戳转成时间串 [2016-7-10 22:38:34]
* nt : 当前待转的时间戳
* tstr : 保存的转后时间戳位置
* : 返回传入tstr的首地址
*/
extern char * stu_gettstr(time_t nt, stime_t tstr); /*
* 得到当前时间戳 [2016-7-10 22:38:34]
* tstr : 保存的转后时间戳位置
* : 返回传入tstr的首地址
*/
extern char * stu_getntstr(stime_t tstr); /*
* 判断当前时间串是否是同一天的.
* ls : 判断时间一
* rs : 判断时间二
* : 返回true表示是同一天, 返回false表示不是
*/
extern bool stu_sisday(stime_t ls, stime_t rs); /*
* 判断当前时间串是否是同一周的.
* ls : 判断时间一
* rs : 判断时间二
* : 返回true表示是同一周, 返回false表示不是
*/
extern bool stu_sisweek(stime_t ls, stime_t rs); #endif // !_H_SCTIMEUTIL

sctimeutil.c

#include "sctimeutil.h"
#include <stdio.h> // 为Visual Studio导入一些和linux上优质思路
#if defined(_MSC_VER) /*
* Linux sys/time.h 中获取时间函数在Windows上一种移植实现
* tv : 返回结果包含秒数和微秒数
* tz : 包含的时区,在window上这个变量没有用不返回
* : 默认返回0
*/
int
gettimeofday(struct timeval* tv, void* tz) {
struct tm st;
SYSTEMTIME wtm; GetLocalTime(&wtm);
st.tm_year = wtm.wYear - _INT_YEAROFFSET;
st.tm_mon = wtm.wMonth - _INT_MONOFFSET; // window的计数更好些
st.tm_mday = wtm.wDay;
st.tm_hour = wtm.wHour;
st.tm_min = wtm.wMinute;
st.tm_sec = wtm.wSecond;
st.tm_isdst = -; // 不考虑夏令时 tv->tv_sec = (long)mktime(&st); // 32位使用数据强转
tv->tv_usec = wtm.wMilliseconds * ; // 毫秒转成微秒 return ;
} #endif /*
* 将 [2016-7-10 21:22:34] 格式字符串转成时间戳
* tstr : 时间串分隔符只能是单字节的.
* pt : 返回得到的时间戳
* otm : 返回得到的时间结构体
* : 返回这个字符串转成的时间戳, -1表示构造失败
*/
bool
stu_gettime(stime_t tstr, time_t * pt, struct tm * otm) {
time_t t;
struct tm st; if(NULL == tstr)
return false; int rt = sscanf(tstr, "%d%*c%d%*c%d%*c%d%*c%d%*c%d",
&st.tm_year, &st.tm_mon, &st.tm_mday,
&st.tm_hour, &st.tm_min, &st.tm_sec);
if( != rt)
return false; st.tm_year -= _INT_YEAROFFSET;
st.tm_mon -= _INT_MONOFFSET;
// 得到时间戳, 失败返回false
if((t = mktime(&st)) == - )
return false; // 返回最终结果
if(pt)
*pt = t;
if(otm)
*otm = st; return true;
} /*
* 判断当前时间戳是否是同一天的.
* lt : 判断时间一
* rt : 判断时间二
* : 返回true表示是同一天, 返回false表示不是
*/
bool
stu_tisday(time_t lt, time_t rt) {
// 得到是各自第几天的
lt = (lt + _INT_DAYSTART - _INT_DAYNEWSTART) / _INT_DAYSECOND;
rt = (rt + _INT_DAYSTART - _INT_DAYNEWSTART) / _INT_DAYSECOND;
return lt == rt;
} /*
* 判断当前时间戳是否是同一周的.
* lt : 判断时间一
* rt : 判断时间二
* : 返回true表示是同一周, 返回false表示不是
*/
bool
stu_tisweek(time_t lt, time_t rt) {
time_t mt;
struct tm st; lt -= _INT_DAYNEWSTART;
rt -= _INT_DAYNEWSTART; if(lt < rt) { //得到最大时间, 保存在lt中
mt = lt;
lt = rt;
rt = mt;
} // 得到lt 表示的当前时间
localtime_r(&lt, &st); // 得到当前时间到周一起点的时间差
st.tm_wday = == st.tm_wday ? : st.tm_wday;
mt = (st.tm_wday - ) * _INT_DAYSECOND + st.tm_hour * _INT_HOURSECOND
+ st.tm_min * _INT_MINSECOND + st.tm_sec; // [min, lt], lt = max(lt, rt) 就表示在同一周内
return rt >= lt - mt;
} /*
* 将时间戳转成时间串 [2016-7-10 22:38:34]
* nt : 当前待转的时间戳
* tstr : 保存的转后时间戳位置
* : 返回传入tstr的首地址
*/
char * stu_gettstr(time_t nt, stime_t tstr) {
struct tm st;
localtime_r(&nt, &st);
strftime(tstr, sizeof(stime_t), "%F %X", &st);
return tstr;
} /*
* 得到当前时间戳 [2016-7-10 22:38:34]
* tstr : 保存的转后时间戳位置
* : 返回传入tstr的首地址
*/
char * stu_getntstr(stime_t tstr) {
return stu_gettstr(time(NULL), tstr);
} /*
* 判断当前时间串是否是同一天的.
* ls : 判断时间一
* rs : 判断时间二
* : 返回true表示是同一天, 返回false表示不是
*/
bool
stu_sisday(stime_t ls, stime_t rs) {
time_t lt, rt;
// 解析失败直接返回结果
if(!stu_gettime(ls, &lt, NULL) || !stu_gettime(rs, &rt, NULL))
return false; return stu_tisday(lt, rt);
} /*
* 判断当前时间串是否是同一周的.可以优化
* ls : 判断时间一
* rs : 判断时间二
* : 返回true表示是同一周, 返回false表示不是
*/
bool
stu_sisweek(stime_t ls, stime_t rs) {
time_t lt, rt;
// 解析失败直接返回结果
if(!stu_gettime(ls, &lt, NULL) || !stu_gettime(rs, &rt, NULL))
return false; return stu_tisweek(lt, rt);
}

编译命令

gcc -Wall -ggdb2 -o main.out main.c sctimeutil.c

测试结果 达到预期

window上测试也一样. 有兴趣的可以将思路用在自己的项目中. 思路比代码有底蕴. 软件开发, 马龙还是无法简单的表达咱们职业的.

设计师觉得更贴切些. 用双手描绘色彩务实的人们.

后记

  错误是难免的, 欢迎吐槽, 再打补丁修复~~

附加 :

  晚上将代码加入simplec框架中, 创造了更有意思的代码, 真心值得学习研究 . 万能时间转换函数. 性能也好了许多. 抛弃了sscanf 这种大块头函数.

// 从时间串中提取出来年月日时分秒
static bool _stu_gettm(stime_t tstr, struct tm * otm) {
int * py, * es;
char c;
int sum; if ((!tstr) || !(c = *tstr) || c < '' || c > '')
return false; py = &otm->tm_year;
es = &otm->tm_sec;
sum = ;
while ((c = *tstr) && py >= es) {
if (c >= '' && c <= '') {
sum = * sum + c - '';
++tstr;
continue;
} *py-- = sum;
sum = ; // 去掉特殊字符, 一直找到下一个数字
while ((c = *++tstr) && (c<'' || c>''))
;
}
// 非法, 最后解析出错
if (py != es)
return false; *es = sum; // 保存最后秒数据
return true;
} /*
* 将 [2016-7-10 21:22:34] 格式字符串转成时间戳
* tstr : 时间串分隔符只能是单字节的.
* pt : 返回得到的时间戳
* otm : 返回得到的时间结构体
* : 返回这个字符串转成的时间戳, -1表示构造失败
*/
bool
stu_gettime(stime_t tstr, time_t * pt, struct tm * otm) {
time_t t;
struct tm st; // 先解析年月日时分秒
if (!_stu_gettm(tstr, &st))
return false; st.tm_year -= _INT_YEAROFFSET;
st.tm_mon -= _INT_MONOFFSET;
// 得到时间戳, 失败返回false
if ((t = mktime(&st)) == -)
return false; // 返回最终结果
if (pt)
*pt = t;
if (otm)
*otm = st; return true;
}

  

C基础 时间业务实战代码的更多相关文章

  1. DOM基础操作实战代码

    对于已经讲解给大家的DOM实战,我今天给大家几个实战代码,可以让大家加深对此的理解! 1.用DOM动态生成这样一个结构: <div class=”example”> <p class ...

  2. L013-linux基础正则表达式手把手实战讲解小节

    L013-linux基础正则表达式手把手实战讲解小节 这么一看又有10天没更新博客了,最近也一直在学就是时间比较闲散,再加上做上次老师留的十多道题,所以时间比较紧张,本来做完题准备直接先看L014讲解 ...

  3. 极客时间 Mysql实战45讲 07讲行锁功过:怎么减少行锁对性能的影响笔记 极客时间

    极客时间 Mysql实战45讲 07讲行锁功过:怎么减少行锁对性能的影响笔记 极客时间极客时间 Mysql实战45讲 07讲行锁功过:怎么减少行锁对性能的影响笔记 极客时间 笔记体会: 方案一,事务相 ...

  4. ASP.NET Core & Docker & Jenkins 零基础持续集成实战

    原文:ASP.NET Core & Docker & Jenkins 零基础持续集成实战 一.本系列教程说明 源代码管理工具:Gogs 持续集成工具:Jenkins 容器:Docker ...

  5. HtmlAgilityPack实战代码

    C#采集代理服务器ip并设置IE代理--HtmlAgilityPack实战代码 今天在博客园看到一篇文章,说是C#采集某某的数据,其实做采集小软件很久了, 用的最好的还是HtmlAgilityPack ...

  6. 看完让你彻底理解 WebSocket 原理,附完整的实战代码(包含前端和后端)

    1.前言 最近有同学问我有没有做过在线咨询功能.同时,公司也刚好让我接手一个 IM 项目.所以今天抽时间记录一下最近学习的内容.本文主要剖析了 WebSocket 的原理,以及附上一个完整的聊天室实战 ...

  7. Vue2.5开发去哪儿网App 从零基础入门到实战项目

    第1章 课程介绍本章主要介绍课程的知识大纲,学习前提,讲授方式及预期收获. 1-1 课程简介 试看第2章 Vue 起步本章将快速讲解部分 Vue 基础语法,通过 TodoList 功能的编写,在熟悉基 ...

  8. 零基础入门Python实战:四周实现爬虫网站 Django项目视频教程

    点击了解更多Python课程>>> 零基础入门Python实战:四周实现爬虫网站 Django项目视频教程 适用人群: 即将毕业的大学生,工资低工作重的白领,渴望崭露头角的职场新人, ...

  9. 【视频合集】极客时间 react实战进阶45讲 【更新中】

    https://up2.v.sharedaka.com/video/ochvq0AVfpa71A24bmugS5EewhFM1553702519936.mp4 01 React出现的历史背景及特性介绍 ...

随机推荐

  1. (六)Redis有序集合Sorted set操作

     Sorted set全部命令如下: zadd key score1 member1 score2 member2 ... # 将一个或多个member元素及其score值加入到有序集合key当中 z ...

  2. 史上最简单的 MySQL 教程(十五)「列属性 之 自动增长」

    自动增长 自动增长:auto_increment,当对应的字段,不给值,或者是默认值,或者是null的时候,就会自动的被系统触发,系统会从当前字段中取已有的最大值再进行+1操作,得到新的字段值. 自增 ...

  3. C++STL简介

    本文仅仅是个人学习的过程中结合网上博文,对STL的整理,也仅仅是简介.仅为个人学习笔记. 一.STL简介(摘自:晨光(Morning)) STL(Standard Template Library), ...

  4. [Leetcode] Binary tree inorder traversal二叉树中序遍历

    Given a binary tree, return the inorder traversal of its nodes' values. For example:Given binary tre ...

  5. 洛谷 P2657 [SCOI2009]windy数 解题报告

    P2657 [SCOI2009]windy数 题目描述 \(\tt{windy}\)定义了一种\(\tt{windy}\)数.不含前导零且相邻两个数字之差至少为\(2\)的正整数被称为\(\tt{wi ...

  6. Markdown资料收集

    教程介绍 原生Markdown不支持表格,表格属于扩展Markdown语法 快速入门:https://github.com/riku/Markdown-Syntax-CN/blob/master/ba ...

  7. 实例——简单的Samba共享

    服务端配置 # 临时停止iptables service iptables stop # 临时禁用SELinux setenforce 0 # 禁止iptables开机自动启动 chkconfig i ...

  8. STL使用总结

    转载于http://blog.csdn.net/daisy_chenting/article/details/6898184 1.    概述 泛型编程思想最早缘于A.Stepanov提出的部分算法可 ...

  9. nginx 服务器启动、终止、重启

    启动 在linux系统下输入命令: nginx地址 -c nginx配置文件 就可启动nginx eg:/usr/local/nginx/sbin/nginx -c /usr/local/nginx/ ...

  10. Maven命令行窗口指定settings.xml

    maven命令行窗口指定特定settings.xml 在命令行界面指定settings.xml,命令如下: mvn install --settings c:\user\settings.xml 例如 ...