(C语言) time库-日期和时间工具

文章目录

  • ⏰介绍
  • ⏰常量
    • ⏱️`CLOCKS_PER_SEC`
  • ⏰类型
    • ⏱️`tm`
    • ⏱️`time_t`
    • ⏱️`clock_t`
    • ⏱️`timespec` (C11)
  • ⏰函数-时间操作
    • ⏲️`time`
    • 🏷️返回纪元开始经过的当前系统日历时间
    • ⏲️`clock`
    • 🏷️返回未加工的程序启动时开始经过的处理器时间
    • ⏲️`difftime`
    • 🏷️计算时间差
  • ⏰函数-格式转换-类型转换
    • ⏲️`gmtime`
    • 🏷️将从纪元开始的时间转换成以协调世界时(UTC)表示的日历时间
    • 🏷️time_t -> tm
    • ⏲️`localtime`
    • 🏷️将从纪元开始的时间转换成以本地时间表示的日历时间
    • 🏷️time_t -> tm
    • ⏲️`mktime`
    • 🏷️将日历时间转换成纪元开始经过的时间
    • 🏷️tm -> time_t
  • ⏰函数-格式转换-文本表示
    • ⏲️`asctime`
    • 🏷️将 `struct tm` 对象转换成文本表示
    • 🏷️tm -> str
    • ⏲️`ctime`
    • 🏷️将 `struct time_t` 对象转换成文本表示
    • 🏷️time_t -> str
    • ⏲️`strftime`
    • 🏷️将 `struct tm` 对象转换成自定义文本表示
    • 🏷️time_t -> copyToStr
  • ⏰格式
    • 🧮`Www Mmm dd hh:mm:ss yyyy\n`
  • ⏰应用
    • ✍️力扣[1185. 一周中的第几天](https://leetcode.cn/problems/day-of-the-week/)
    • ✍️力扣[1154. 一年中的第几天](https://leetcode.cn/problems/day-of-the-year/)
  • END

⏰介绍

日期和时间工具 - cppreference.com

<time.h> 是在C语言中的日期与时间工具。其中主要有三大模块,常量,类型和函数。

在C++中推荐写成<ctime>,基本都是继承.h中的东西。

函数主要分为两类,时间操作函数和格式转换函数。

本文主要为C语言中的标准操作,其中在C11和C23又添加和废弃了许多内容,但这块不会本文着重讲解。

UTC 协调世界时

纪元(地球纪元)

夏令时

⏰常量

⏱️CLOCKS_PER_SEC

  • CLOCKS_PER_SEC - cppreference.com
  • (宏常量)
  • 处理器每秒的时间计数
  • 一般来说都是数值1000
#include <stdio.h>
#include <time.h>

int main(void) {
    clock_t beg = clock();
    clock_t end = clock();
    printf("Use time:%lf\n", 1.0 * (end - beg) / CLOCKS_PER_SEC);
}

⏰类型

⏱️tm

  • tm - cppreference.com

  • (结构体)

  • 日历时间类型

struct tm {
    int tm_sec;    // [秒 [0, 61] (C89) [0, 60] (C99)] seconds after the minute
    int tm_min;    // [分 [0, 59]] minutes after the hour
    int tm_hour;   // [时 [0, 23]] hours since midnight
    int tm_mday;   // [日 [1, 31]] day of the month
    int tm_mon;    // [月 [0, 11]] months since January
    int tm_year;   // [年 [1900:0]] years since 1900
    int tm_wday;   // [周 [0, 6]] days since Sunday
    int tm_yday;   // [第几天 [0, 365]] days since January 1
    int tm_isdst;  // [夏时令标签] daylight savings time flag
};
#include <stdio.h>
#include <time.h>

int main(void) {
    struct tm start = {.tm_mday = 1};
    mktime(&start);
    // Sun Jan 01 00:00:00 1900
    printf("%s\n", asctime(&start));
}

⏱️time_t

  • time_t - cppreference.com
  • (typedef)
  • 从纪元开始的日历时间类型

⏱️clock_t

  • clock_t - cppreference.com
  • (typedef)
  • 从时点开始的处理器时间类型

⏱️timespec (C11)

  • timespec - cppreference.com
  • (结构体)
  • 单位为秒和纳秒的时间
// 保有时间间隔的结构体,将其拆分成秒数和纳秒数。
struct timespec {
    time_t tv_sec;   // [秒 >= 0] Seconds 
    long   tv_nsec;  // [纳秒 [0, 999999999]] Nanoseconds
};

timespec_get()

C11 返回基于给定时间基底的日历时间

#include <stdint.h>
#include <stdio.h>
#include <time.h>

int main(void) {
    struct timespec ts;
    // C11 函数
    // 修改 ts 所指向的 struct timespec 对象
    // 以保有以时间基底 base 表示的当前日历时间。
#ifdef TIME_UTC
    timespec_get(&ts, TIME_UTC);
#endif

    char buff[100];
    strftime(buff, sizeof buff, "%D %T", gmtime(&ts.tv_sec));
    printf("Current time: %s.%09ld UTC\n", buff, ts.tv_nsec);
    printf("Raw timespec.time_t: %jd\n", (intmax_t)ts.tv_sec);
    printf("Raw timespec.tv_nsec: %09ld\n", ts.tv_nsec);
}

⏰函数-时间操作

⏲️time

time - cppreference.com

🏷️返回纪元开始经过的当前系统日历时间

time_t time( time_t *arg );
  • 运行失败
    • return -1
  • 运行成功
    • 入参,返回值数值一致
#include <stdio.h>
#include <time.h>

int main(void) {
    time_t in;
    time_t out = time(&in);
    // >success:    out == in
    // >error:      -1
    // 1709276388 = time(1709276388)
    printf("%ld = time(%ld)\n", out, in);
    return 0;
}

⏲️clock

clock - cppreference.com

🏷️返回未加工的程序启动时开始经过的处理器时间

clock_t clock(void);

最经典的应用就是计时器了。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define ARR_LEN (100000)

// return (arg1 > arg2) - (arg1 < arg2); // 可行的简写
// return arg1 - arg2; // 错误的简写(若给出 INT_MIN 则会失败)
int cmp(const void* a, const void* b) {
    int arg1 = *(const int*)a;
    int arg2 = *(const int*)b;

    if (arg1 < arg2) {
        return -1;
    }
    if (arg1 > arg2) {
        return 1;
    }
    return 0;
}

int main(void) {
    int arr[ARR_LEN];
    
    clock_t beg = clock();
    qsort(arr, sizeof(arr) / sizeof(*arr), sizeof(int), cmp);
    clock_t end = clock();
    printf("Use time:%lf\n", 1.0 * (end - beg) / CLOCKS_PER_SEC);
}

⏲️difftime

difftime - cppreference.com

🏷️计算时间差

double difftime( time_t time_end, time_t time_beg );

简单测了下和直接相减效果一样。可能是为了统一接口和适配器模式。

#include <stdio.h>
#include <time.h>

int main(void) {
    time_t now = time(NULL);
    time_t beg = {0};

    // 计算时间差
    double during = difftime(now, beg);
    printf("Now:\t %lf\n", 1.0 * now);
    printf("During:\t %lf\n", during);
}

⏰函数-格式转换-类型转换

⏲️gmtime

gmtime, gmtime_r, gmtime_s - cppreference.com

🏷️将从纪元开始的时间转换成以协调世界时(UTC)表示的日历时间

🏷️time_t -> tm

注意,这里存储的是一个全局的静态对象。

函数 gmtime 可能不是线程安全的。

struct tm *gmtime  ( const time_t *timer );
#include <stdio.h>
#include <time.h>

int main(void) {
    time_t t = time(NULL);

    struct tm *tm_p1 = gmtime(&t);
    struct tm *tm_p2 = gmtime(&t);
    // 指向同一个静态对象
    printf("First  struct tm* = %p\n", tm_p1);
    printf("Second struct tm* = %p\n", tm_p2);

    printf("UTC:   %s", asctime(gmtime(&t)));
    printf("local: %s", asctime(localtime(&t)));
}

⏲️localtime

localtime, localtime_r, localtime_s - cppreference.com

🏷️将从纪元开始的时间转换成以本地时间表示的日历时间

🏷️time_t -> tm

注意,这里存储的是一个全局的静态对象。

函数 localtime 可以不是线程安全的。

struct tm *localtime  ( const time_t *timer );
#include <stdio.h>
#include <time.h>

int main(void) {
    time_t t = time(NULL);

    struct tm *tm_p1 = localtime(&t);
    struct tm *tm_p2 = localtime(&t);
    // 指向同一个静态对象
    printf("First  struct tm* = %p\n", tm_p1);
    printf("Second struct tm* = %p\n", tm_p2);

    printf("UTC:   %s", asctime(gmtime(&t)));
    printf("local: %s", asctime(localtime(&t)));
}

⏲️mktime

mktime - cppreference.com

🏷️将日历时间转换成纪元开始经过的时间

🏷️tm -> time_t

time_t mktime( struct tm *time );
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(void) {
    time_t now = time(NULL);
    // 获取当前时间,并加一天
    struct tm tmm = *localtime(&now);
    tmm.tm_mday += 1;
    time_t nexDay = mktime(&tmm);

    printf("Now:\t%ld\n", now);
    printf("NexDay:\t%ld\n", nexDay);
    printf("OneDayTime:\t%lf\n", difftime(nexDay, now));
    printf("24*60*60=\t%d\n", 24 * 60 * 60);
}

⏰函数-格式转换-文本表示

⏲️asctime

asctime, asctime_s - cppreference.com

🏷️将 struct tm 对象转换成文本表示

🏷️tm -> str

asctime 返回指向静态数据的指针从而不是线程安全的。

char* asctime( const struct tm* time_ptr );
#include <stdio.h>
#include <time.h>

int main(void) {
    struct tm tm = *localtime(&(time_t){time(NULL)});
    printf("%s\n", asctime(&tm));

    printf("%p\n", asctime(&tm));
    printf("%p\n", asctime(&tm));
}

⏲️ctime

ctime, ctime_s - cppreference.com

🏷️将 struct time_t 对象转换成文本表示

🏷️time_t -> str

char* ctime( const time_t* timer );
#include <stdio.h>
#include <time.h>

int main(void) {
    time_t result = time(NULL);
    printf("%s\n", ctime(&result));

    printf("%p\n", ctime(&result));
    printf("%p\n", ctime(&result));
}

⏲️strftime

strftime - cppreference.com

🏷️将 struct tm 对象转换成自定义文本表示

🏷️time_t -> copyToStr

size_t strftime(char* str, 
                size_t count, 
                const char* format,
                const struct tm* time);
#include <stdio.h>
#include <time.h>

int main(void) {
    struct tm now_tm = *localtime(&(time_t){time(NULL)});

    char buff[1024];
    // >strftime():Friday 03/01/24 19:41:24
    if (strftime(buff, sizeof buff, ">strftime():%A %c", &now_tm)) {
        puts(buff);
    } else {
        puts("strftime failed");
    }
}

⏰格式

🧮Www Mmm dd hh:mm:ss yyyy\n

// `asctime() & ctime()`以下固定的 25 字符表示形式: `Www Mmm dd hh:mm:ss yyyy\n`
errno_t asctime_s( char* buf, rsize_t bufsz, const struct tm* time_ptr );
errno_t ctime_s( char *buf, rsize_t bufsz, const time_t* timer );
  • Www ——来自 time_ptr->tm_wday星期之日的三字母英文缩写, MonTueWedThuFriSatSun 之一。
  • Mmm ——来自 time_ptr->tm_mon名的三字母英文缩写, JanFebMarAprMayJunJulAugSepOctNovDec 之一。
  • dd ——来自 timeptr->tm_mday 的 2 位月之日,如同由 sprintf 以 %2d 打印
  • hh ——来自 timeptr->tm_hour 的 2 位,如同由 sprintf 以 %.2d 打印
  • mm ——来自 timeptr->tm_min 的 2 位,如同由 sprintf 以 %.2d 打印
  • ss ——来自 timeptr->tm_sec 的 2 位,如同由 sprintf 以 %.2d 打印
  • yyyy ——来自 timeptr->tm_year + 1900 的 4 位,如同由 sprintf 以 %4d 打印

若是非法入参则行为未定义,如:

  • *time_ptr 的任何成员在其正常范围外则行为未定义

  • time_ptr->tm_year 所指示的历年拥有多于 4 位数或小于 1000 年则行为未定义。


自定义格式函数:

strftime()的格式:strftime - cppreference.com

⏰应用

下面两份是使用C++代码表示。

其中主要用到的是<ctime>的类型,还有一些别的库中对时间操作的函数。

✍️力扣1185. 一周中的第几天

给你一个日期,请你设计一个算法来判断它是对应一周中的哪一天。

输入为三个整数:daymonthyear,分别表示日、月、年。

您返回的结果必须是这几个值中的一个 {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}

static const std::string weekDays[] = { 
    "Sunday",   
    "Monday", 
    "Tuesday", 
    "Wednesday", 
    "Thursday", 
    "Friday", 
    "Saturday" 
};

class Solution {
public:
    std::string dayOfTheWeek(int day, int month, int year) {
        std::tm ctm{};
        ctm.tm_year = year - 1900;
        ctm.tm_mon = month - 1;
        ctm.tm_mday = day;
        // a timestamp
        std::time_t ctime_t = std::mktime(&ctm);
        // return a static ret
        ctm = *std::localtime(&ctime_t);
        return weekDays[ctm.tm_wday];
    }
};

✍️力扣1154. 一年中的第几天

给你一个字符串 date ,按 YYYY-MM-DD 格式表示一个 现行公元纪年法 日期。返回该日期是当年的第几天。

class Solution {
public:
    int dayOfYear(string date) {
        std::tm dt;
        std::istringstream(date) >> std::get_time(&dt, "%Y-%m-%d");
        return dt.tm_yday + 1;
    }
};



END

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/420440.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

28.HarmonyOS App(JAVA)多页签的实现(Tab)

HarmonyOS App(JAVA)多页签的实现&#xff08;Tab&#xff09; 页面可左右滑动&#xff0c;点击界面1,2,3切换到对应界面 PageSlider的创建和使用 在layout目录下的xml文件中创建PageSlider。 <PageSlider ohos:id"$id:page_slider" ohos:height"300vp&…

Java编程实战:小区管理系统的设计与实现

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

MySQL之索引详解

华子目录 索引概述优缺点 索引的原理索引的设计原则索引结构B-tree&#xff08;多路平衡查找树&#xff09;BtreeHash 为什么InnoDB存储引擎选择Btree&#xff1f;索引分类聚集索引选取规则 单列索引和多列索引前缀索引创建索引1.创建表时创建索引2.在已经存在的表上创建索引3.…

Muduo库核心代码及优秀编程细节剖析

一、前言&#xff1a; Muduo库是陈硕个人开发的Tcp网络编程库&#xff0c;支持Reactor模型。这篇博文对Muduo库中的Multi-reactor架构代码进行逻辑梳理&#xff0c;同时认真剖析了作者每一处精妙的代码设计思想。 目前我只重构并剖析了Muduo库中的核心部分&#xff0c;即Mult…

了解处理器

了解处理器 摘要写在前面1. 计算机简介1.1.计算机发展简史1.2.计算机分类1.3.PC机结构 2.初识处理器2.1.处理器的硬件模型2.2.处理器的编程模型2.3.处理器的分层模型2.4.如何选择处理器 3.指令集体系结构3.1.处理器编程模型3.2.指令集发展历程3.3.指令集分类3.4.汇编语言格式3.…

第三百七十六回

文章目录 1 .概念介绍2. 实现方法3. 示例代码 我们在上一章回中介绍了在页面之间共传递数据相关的内容&#xff0c;本章回中将介绍如何拦截路由.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1 .概念介绍 本章回中介绍的路由拦截是指在路由运行过程中&#xff0c;对路由做…

Java进阶(锁)——锁的升级,synchronized与lock锁区别

目录 引出Java中锁升级synchronized与lock锁区别 缓存三兄弟&#xff1a;缓存击穿、穿透、雪崩缓存击穿缓存穿透缓存雪崩 总结 引出 Java进阶&#xff08;锁&#xff09;——锁的升级&#xff0c;synchronized与lock锁区别 Java中锁升级 看一段代码&#xff1a; public class…

Python学习 day06(类、对象、构造方法、私有方法、继承

类 程序中数据的组织多种多样&#xff0c;如果我们简单用变量来记录&#xff0c;就会混乱、不统一&#xff0c;如下所示&#xff1a; 类比现实中的表格&#xff0c;我们可以用类来组织数据&#xff0c;如下&#xff1a; 类的定义和使用 类中的变量叫做成员变量&#xff0c;类中…

mysql,for循环执行sql

遇到一个问题&#xff0c;我需要模拟上百万数据来优化sql&#xff0c;线上数据down不下来&#xff0c;测试库又没有&#xff0c;写代码执行要么慢要么就是sql语句太长。 于是&#xff0c;直接用mysql自带的功能去实现&#xff01; 简单而简单 mysql可以for循环&#xff1f;没…

python中版本,操作系统等问题汇总

1. linux源码部署到windows 1.1ModuleNotFoundError: No module named pwd 这个问题&#xff0c;是因为源码是给linux的。这里在windows中&#xff0c;没有该命令。 解决方法之一&#xff0c;在相应的环境目录中&#xff0c;如图中<MetaGPTenv>虚拟环境中&#xff0c;在…

Unity 预制体与变体

预制体作用&#xff1a; 更改预制体&#xff0c;则更改全部的以预制体复制出的模型。 生成预制体&#xff1a; 当你建立好了一个模型&#xff0c;从层级拖动到项目中即可生成预制体。 预制体复制模型&#xff1a; 将项目中的预制体拖动到层级中即可复制。或者选择物体复制粘贴。…

可用于智能客服的完全开源免费商用的知识库项目

介绍 FastWiki项目是一个高性能、基于最新技术栈的知识库系统&#xff0c;专为大规模信息检索和智能搜索设计。利用微软Semantic Kernel进行深度学习和自然语言处理&#xff0c;结合.NET 8和MasaBlazor前端框架&#xff0c;后台采用.NET 8MasaFrameworkSemanticKernel&#xff…

微信小程序云开发教程——墨刀原型工具入门(安装以及基础使用教程)

引言 作为一个小白&#xff0c;小北要怎么在短时间内快速学会微信小程序原型设计&#xff1f; “时间紧&#xff0c;任务重”&#xff0c;这意味着学习时必须把握微信小程序原型设计中的重点、难点&#xff0c;而非面面俱到。 要在短时间内理解、掌握一个工具的使用&#xf…

IO-DAY2

用发write、fread将一张随意图片修改成德国国旗 #include<stdio.h> #include<string.h> #include<stdlib.h> #include<unistd.h> int main(int argc, char *argv[]) {FILE* fpfopen("./122.bmp","r");int w 0,h 0;fseek(fp,18,…

队列的结构概念和实现

文章目录 一、队列的结构和概念二、队列的实现三、队列的实现函数四、队列的思维导图 一、队列的结构和概念 什么是队列&#xff1f; 队列就是只允许在一端进行插入数据操作&#xff0c;在另一端进行删除数据操作的特殊线性表&#xff0c;队列具有先进先出 如上图所示&#x…

经典文献阅读之--CamMap(基于SLAM地图对不共视相机进行外参标定)

0. 简介 由于多相机之间通常存在有限或无重叠的视场&#xff0c;因此在估计外参相机参数时面临着一定的挑战&#xff0c;为了解决这个问题&#xff0c;本文提出了CamMap&#xff1a;一种新颖的6自由度外参标定流程。根据三个操作规则&#xff0c;使一个多相机系统单独捕捉一些…

《Spring Security 简易速速上手小册》第4章 授权与角色管理(2024 最新版)

文章目录 4.1 理解授权4.1.1 基础知识详解授权的核心授权策略方法级安全动态权限检查 4.1.2 主要案例&#xff1a;基于角色的页面访问控制案例 Demo 4.1.3 拓展案例 1&#xff1a;自定义投票策略案例 Demo测试自定义投票策略 4.1.4 拓展案例 2&#xff1a;使用方法级安全进行细…

MyBatis 学习(三)之 MyBatis 全局配置文件

目录 1 MyBatis 全局配置文件 2 properties 元素 3 setting 设置 4 typeAlianses 别名处理器 5 typeHandler 类型处理器 6 objectFacotry 对象工厂&#xff08;了解&#xff09; 7 plugins 插件&#xff08;了解&#xff09; 8 environments 运行环境 9 databaseIdPro…

cpp基础学习笔记03:类型转换

static_cast 静态转换 用于类层次结构中基类和派生类之间指针或者引用的转换。up-casting (把派生类的指针或引用转换成基类的指针或者引用表示)是安全的&#xff1b;down-casting(把基类指针或引用转换成子类的指针或者引用)是不安全的。用于基本数据类型之间的转换&#xff…

ORACLE 基础

一.ORACLE简介 1.1什么是oracle ORACLE 数据库系统是美国 ORACLE 公司&#xff08;甲骨文&#xff09;提供的以分布式数据库为核心的一组软件产品&#xff0c;是目前最流行的客户/服务器(CLIENT/SERVER)或 B/S 体系结构的数据库之一。 ORACLE 通常应用于大型系统的数据库产品。…