C基础 时间业务实战代码

引言

  业务代码中遇到这样需求, 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 = -1; // 不考虑夏令时

    tv->tv_sec = (long)mktime(&st); // 32位使用数据强转
    tv->tv_usec = wtm.wMilliseconds * 1000; // 毫秒转成微秒

    return 0;
}

#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(6 != rt)
        return false;

    st.tm_year -= _INT_YEAROFFSET;
    st.tm_mon -= _INT_MONOFFSET;
    // 得到时间戳, 失败返回false
    if((t = mktime(&st)) == -1 )
        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 0;
}

附加代码文件

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 = -1; // 不考虑夏令时

    tv->tv_sec = (long)mktime(&st); // 32位使用数据强转
    tv->tv_usec = wtm.wMilliseconds * 1000; // 毫秒转成微秒

    return 0;
}

#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(6 != rt)
        return false;

    st.tm_year -= _INT_YEAROFFSET;
    st.tm_mon -= _INT_MONOFFSET;
    // 得到时间戳, 失败返回false
    if((t = mktime(&st)) == -1 )
        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 = 0 == st.tm_wday ? 7 : st.tm_wday;
    mt = (st.tm_wday - 1) * _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上测试也一样. 有兴趣的可以将思路用在自己的项目中. 思路比代码有底蕴. 软件开发, 马龙还是无法简单的表达咱们职业的.

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

后记

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

  

时间: 2024-11-05 18:55:50

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

新书:Scala语言基础与开发实战

大数据科学丛书系列的最新一本<Scala语言基础与开发实战>即将面市,预计月底上架.内容还是不错的,文笔简介,内容实用,值得学.用. 大数据资深培训师王家林新作. 详细介绍大数据开发语言Scala及其在分布式框架Akka和Kafka中的应用. 秉承"实战"类图书特点,解析大量代码的编写操作,具有较强的可操作性,便于读者学习和理解. 算上再过几个月出版的<Spark内核解析及性能调优>,一年时间,大数据科学丛书系列之Spark的小套系基本形成了:从学习Spark的

mysql 时间函数实战

mysql 时间函数实战 MySQL日期数据类型.MySQL时间类型使用总结,需要的朋友可以参考下. MySQL 日期类型:日期格式.所占存储空间.日期范围 比较. 日期类型 存储空间       日期格式                 日期范围 ------------ ---------   ---------------------    ----------------------------------------- datetime         8 bytes   YYYY-M

C#反射基础知识和实战应用

首先来说一下什么是反射? 反射提供了封装程序集.模块和类型的对象(Type类型) 可以使用反射动态的创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型,然后,可以调用类型的方法或访问其字段和属性 . 总之,有了反射,以前很多实现不了的功能都可以实现. 下面先来写一个小例子,体验一下反射是怎么一回事: 打开VS2010,新建一个控制台应用程序,在program.cs里面写代码 首先引入命名空间: using System.Reflection; 下如下代码: PropertyInfo l

Hadoop大数据零基础高端实战培训视频

<Hadoop大数据零基础高端实战培训系列配文本挖掘项目(七大亮点.十大目标)> 课程讲师:迪伦 课程分类:大数据 适合人群:初级 课时数量: 300课时 用到技术:部署Hadoop集群 涉及项目:京东商城.百度.阿里巴巴 咨询QQ:779591710 下载地址: 链接:http://pan.baidu.com/share/link?shareid=3299239734&uk=3289559542 密码:8tkb 第一阶段:Hadoop基础篇(50课时) - 千里之行,始于足下(赠送课

下载云计算Docker从零基础到专家实战教程【第一季】

云计算.大数据,移动技术的快速发展,加之企业业务需求的不断变化,导致企业架构要随时更改以适合业务需求,跟上技术更新的步伐.毫无疑问,这些重担都将压在企业开发人员身上:团队之间如何高效协调,快速交付产品,快速部署应用,以及满足企业业务需求,是开发人员亟需解决的问题.Docker技术恰好可以帮助开发人员解决这些问题. 云计算Docker从零基础到专家实战教程[第一季],刚刚入手,转一注册文件,视频的确不错,可以先下载看看:http://pan.baidu.com/s/1hsO74Gk 密码:g58j

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

第1章 课程介绍 本章主要介绍课程的知识大纲,学习前提,讲授方式及预期收获. 第2章 Vue 起步 本章将快速讲解部分 Vue 基础语法,通过 TodoList 功能的编写,在熟悉基础语法的基础上,扩展解析 MVVM 模式及前端组件化的概念及优势. 第3章 Vue 基础精讲 本章通过精挑细选的案例,精讲 Vue 中的基础知识,包括实例.生命周期.指令.计算属性.方法.侦听器,表单等部分内容. 第4章 深入理解 Vue 组件 本章将深入讲解 Vue 组件使用的细节点,从父子组件的参数传递及校验入手

大数据从基础到项目实战(一站式全链路最佳学习路径)

大数据从基础到项目实战(一站式全链路最佳学习路径)课程链接:https://pan.baidu.com/s/1HC9zqxwUFNBJHT9zP1dlvg 密码:xdgd 本课程为就业课程,以完整的实战项目为主线,项目各个环节既深入讲解理论知识,又结合项目业务进行实操,从而达到一站式学习,让你快速达到就业水平. 全真企业项目全流程演示: 大数据生产->采集->存储->处理->计算->分析(离线+实时)->抽取(离线+实时)->Java接口->可视化Web展示

不要相信程序员在加班时间写的代码

不要相信一个程序员在加班时间写出来的代码. (软件工程的学说表明,连正常时间好好写的代码,也不要太相信.不过这不是本文的重点,略过不提.) (不懂代码的人,看到本文中的Java代码可以略过,不影响理解.) 创造力的时限 写代码,与写文章.绘画.思考复杂问题,并没有本质上的区别,都是创造性的活动. 每个人的创造力,都会随着身体状态而波动.广为人知的是,一个人年老体衰后,相比年富力强时,创造力会急剧下降.其实,人每天的状态起伏,也同样会剧烈影响这一点. 如果是拧螺丝,那么在精疲力尽.拧不动以前,身体

vbs获取当前时间日期的代码

vbs获取当前时间日期的代码,文章来源:脚本学堂. 获取当前日期方法一: Currentdate1=date()msgbox Currentdate1 获取当前日期方法二:Currentdate2=year(Now)&"-"&Month(Now)&"-"&day(Now)msgbox Currentdate2 获取当前时间:CurrentTime=Hour(Now)&":"&Minute(Now)&