当前位置: 首页 > news >正文

从 UTC 日期时间字符串获取 Unix 时间戳:C 和 C++ 中的挑战与解决方案

在编程世界里,从 UTC 日期时间字符串获取 Unix 时间戳,看似简单,实则暗藏玄机。你以为输入一个像 “Fri, 17 Jan 2025 06:07:07” 这样的 UTC 时间,然后轻松得到 1737094027(从 1970 年 1 月 1 日 00:00:00 UTC 开始经过的秒数)就万事大吉了?事实可没这么简单,这背后涉及到一系列复杂的时间处理问题,还会让你发现 POSIX 时间处理函数在不同 C 库及相关语言中的各种 “意外特性”。今天,咱们就来深入探讨一下这个让人又爱又恨的话题。

一、时间处理的复杂性

时间本身就是一个复杂的概念,要是再把闰秒和相对论这些因素考虑进去,那就更让人头疼了。而人类对时间的记录方式,从模糊不清到精确无比,各不相同。就拿阿姆斯特丹的时间来说,由于夏令时的存在,“2025 年 3 月 30 日 02:20” 这个时间点在当地是不存在的,时间会直接从 01:59:59 跳到 03:00:00。但 “2024 年 10 月 27 日 02:30” 就更让人困惑了,因为夏令时结束时,02:59:59 的下一秒又回到了 02:00:00,这就导致有两个 “02:00” 的时间点。从下面的命令行示例就能看出工具在处理这种情况时的随意性:

$ TZ=Europe/Amsterdam date -d '20241027 01:59:59' +"%Y-%m-%d %H:%M:%S %s %z"
2024-10-27 01:59:59 1729987199 +0200
$ TZ=Europe/Amsterdam date -d '20241027 02:00:00' +"%Y-%m-%d %H:%M:%S %s %z"
2024-10-27 02:00:00 1729990800 +0100

你看,当要求解释 02:00:00 这个时间时,GNU date 工具选择了第二个出现的时间点。而且据我观察,这还和执行命令的时间有关,如果在四月执行,可能就会选择第一个 02:00:00 实例,是不是很让人摸不着头脑?

二、POSIX 时间概念与 struct tm

在 POSIX/Unix 系统中,指定时间的有效方式是用相对于某个 “纪元”(epoch)的秒数。POSIX/Unix 的纪元是 1970 年 1 月 1 日 00:00:00 UTC,GPS 的纪元是 1980 年 1 月 6 日 00:00:00 UTC,伽利略(欧盟的 GPS 系统)的纪元是 1999 年 8 月 21 日 23:59:47 UTC,北斗系统的纪元是 2006 年 1 月 1 日 00:00:00 UTC。其中,GPS、伽利略和北斗系统都明智地忽略了闰秒,把这些麻烦事留给人类去处理。而我们常用的 POSIX/Unix 的 “time_t” 时间戳,除了在闰秒期间可能会有歧义(不过闰秒以后可能也不会再有了),其他时候还是很可靠的。

为了在时间戳和人类可读的时间格式之间进行转换,UNIX 提供了 struct tm 结构体,它包含了年、月、日、时、分、秒等时间信息:

struct tm {int  tm_sec;    /* 秒 [0, 60] */int  tm_min;    /* 分 [0, 59] */int  tm_hour;   /* 时 [0, 23] */int  tm_mday;   /* 一个月中的第几天 [1, 31] */int  tm_mon;    /* 月份 [0, 11] (一月是 0) */int  tm_year;   /* 年份减去 1900 */int  tm_wday;   /* 一周中的第几天 [0, 6] (周日是 0) */int  tm_yday;   /* 一年中的第几天 [0, 365] (1 月 1 日是 0) */int  tm_isdst;  /* 夏令时标志 */long tm_gmtoff; /* 相对于 UTC 的秒数 */const char *tm_zone;   /* 时区缩写 */
};

不过,这个结构体的设计其实有点冗余,像一周中的第几天和一年中的第几天,通过其他字段就能推算出来。而且,tm_gmtofftm_zone 和 tm_isdst 这几个字段的含义不仅定义得不太清晰,理解起来也有难度,并且它们的作用还会根据结构体的使用方式而变化。

struct tm 的一个重要作用是作为 mktime() 函数的输入,mktime() 会把 “根据本地时区拆分的时间” 转换为 Unix 时间戳。但它的功能可不止这一个,它还会对传入的 struct tm 进行标准化处理。比如说,如果你想把当前时间往后调一周,你可能会直接给 time_t 时间戳加上 604800 秒(一周的秒数),但如果这个调整跨越了夏令时的边界,你原本下午 2 点的约会可能就会变成下周下午 1 点或 3 点,这可不是我们想要的结果。而 mktime() 就能帮你处理这种情况,即使你传入像 “3 月 35 日” 这样不合理的日期,它也能帮你修正。不过,使用 mktime() 时也有一些需要注意的地方,下面我们就来详细说说。

三、mktime() 的使用与注意事项

先来看个例子:

struct tm tm = {.tm_hour=14, .tm_mday = 28,
.tm_mon = 2, .tm_year = 2025 - 1900,
.tm_isdst = -1};  // <- 注意这里的 -1
time_t t = mktime(&tm);
cout << "original:         "<< ctime(&t);
tm.tm_mday += 7;
t = mktime(&tm);
cout << "mktime adjusted:  "<< ctime(&t);

在欧洲 / 阿姆斯特丹时区,这段代码的输出结果是:

original:        Fri Mar 28 14:00:00 2025
mktime adjusted: Fri Apr  4 15:00:00 2025

为什么我们的约会时间会偏移一个小时呢?问题就出在 tm.tm_isdst 这个字段上。mktime() 要求你明确指定时间是否处于夏令时,或者让它自己去判断(我们一开始把 tm.tm_isdst 设置为 -1 就是让它自己判断)。当我们第一次调用 mktime() 时,它发现初始时间不在夏令时,就把 tm_isdst 设置为 0。第二次调用时,这个设置没有改变,但新的时间其实是处于夏令时的,所以就出现了时间偏移的情况。解决办法就是在第二次调用 mktime() 之前,把 tm_isdst 重新设置为 -1。

另外,使用 mktime() 处理 UTC 时间时也有个大坑。mktime() 会把传入的时间当作 “本地时间” 来处理,所以如果你要处理 UTC 时间,就需要在调用 mktime() 之前把时区设置为 UTC。但如果你的程序有其他线程在运行,修改整个应用程序的时区可能会产生副作用。不过,多线程程序本来就不能随意更改环境变量,所以这个方法也行不通。

还好,有一个非标准但广泛可用的函数 timegm() 能很好地解决 UTC 时间的处理问题。从 IEEE Std 1003.1 - 2024 标准中可知,“未来的标准版本预计会添加一个 timegm() 函数,它与 mktime() 类似,但 timeptr 指向的 tm 结构体包含的是协调世界时(UTC)的拆分时间”。在 Windows 系统上,timegm() 对应的函数是 mkgmtime()。如果你的系统是 AIX,没有 timegm() 函数,也可以在特定的地方找到独立的实现。

总结一下使用 mktime() 和 timegm()(或 mkgmtime())的要点:

  • 使用 mktime() 处理本地时间时,把 tm_isdst 设置为 -1,这通常符合人们的预期,但在夏令时切换时,可能会随机得到两个 “02:30”(或类似时间点)中的一个。

  • 在填充 struct tm 之前,最好先把其他字段清零,以防万一。

  • 要知道 mktime() 会修改传入的 struct tm,可能会产生副作用,所以在重复使用 struct tm 之前,至少要重置 tm_isdst

  • 不管你怎么设置 tm_gmtoffset 或 tm_zonemktime() 都会使用当前时区。如果你想让它把 struct tm 当作 UTC 时间处理,就需要设置 TZ 环境变量为 UTC,但这会影响其他做时间操作的线程。所以,能使用 timegm() 或 mkgmtime() 就尽量用它们。

四、解析 UTC 时间字符串

我们都希望能把像 “Fri, 17 Jan 2025 06:07:07 GMT” 这样的时间字符串直接传入 strptime() 函数,然后得到一个合理的 struct tm 结构体。但 Linux glibc 的 strptime() 手册中关于 %z 和 %Z 这两个时区格式说明符的描述含糊不清,让人摸不着头脑。很多人可能会期望用 strptime() 结合 %Z(用于解析 “GMT”),再配合 mktime() 就能把 UTC 时间字符串转换为 Unix 时间戳,但实际上 mktime() 根本不会看 tm_gmtoffset 和 tm_zone 这两个字段,所以即使 strptime() 做对了,也无法实现我们的目标,而且它还真就做不对。

截至 2024 年,虽然 Open Group 对 strptime() 有了更详细的规范,但里面也都是些让人无奈的消息。strptime() 对 %z 没有明确的行为定义,这个原本应该用来处理 “+0200” 这种偏移标识符的符号,现在根本靠不住。对于 %Z,虽然有一些说明,但作用也非常有限。只有在特定的本地化设置下,它才可能设置 tm_isdst 的正确值,而且像 “EST” 这样的字符串,由于没有明确的定义,也很难通过 %Z 来解析。

不过,既然我们知道了 timegm() 这个好帮手,就可以忽略 %z 和 %Z 了。

五、strptime() 与本地化问题

在很多情况下,我们需要解析包含英文日期和月份名称的时间字符串,并且希望 strptime() 能正确处理。但 IEEE/Open Group 标准规定,strptime() 的转换操作是由当前本地化设置的 LC_TIME 类别决定的。这里有个容易忽略的点,C 和 C++ 程序默认使用的是 “C” 本地化,这实际上就是美式英语。这对于解析数据中的时间字符串来说通常是好事,因为这些字符串大多是英文的。

但如果你的程序调用了 setlocale() 函数,设置了非 “C” 的本地化,那你的程序可能就只能处理特定语言(比如荷兰语)的时间字符串了,这可就麻烦了。你可能会想在调用 strptime() 之前把本地化设置为 “C”,用完再改回来,但 setlocale() 在多线程程序中调用并不安全(除了在线程启动之前),而且即使安全调用,也可能会影响其他线程的输出。

所以,一般来说,如果你需要解析特定的时间字符串并且想用 strptime(),一定要确保程序处于你期望的本地化环境中。虽然有 strftime_l() 函数可以指定格式化时间时使用的本地化,但并没有官方可用的 strptime_l() 函数。

当然,你也可以自己解析像 “17 Jan 2025 06:07:07” 这样的字符串,填充 struct tm 结构体,然后让 mktime() 来计算 Unix 时间戳,这也是一种可行的办法。

六、用 C++ 解决本地化问题及 C++20 的强大时间处理功能

C++ 的输入输出流(iostreams)在处理本地化方面比 C/POSIX 做得更好。在 C++ 中,你可以为每个输入输出流设置本地化。下面是一个 C++ 辅助函数,如果你在设置了本地化的 C 程序中需要解析任意 UTC 时间字符串,可以调用这个函数:

extern "C"
int utcstr2epoch(const char* timestr, const char* fmtstr, struct tm* output)
{std::tm t = {}; // tm_isdst = 0, 不用考虑夏令时,这是 UTC 时间std::istringstream ss(timestr);ss.imbue(std::locale()); // "LANG=C", 但本地化设置是本地的ss >> std::get_time(&t, fmtstr);if (ss.fail())return -1;// 修正星期几、一年中的第几天等字段t.tm_isdst = 0; // 不用考虑夏令时t.tm_wday = -1;if(mktime(&t) == -1 && t.tm_wday == -1) // "真正的错误"return -1;*output = t;return 0;
}

这个函数还展示了如何处理 mktime() 的错误。当 mktime() 处理 1969 年 12 月 31 日 23:59 这样的时间时,会返回 -1 作为错误代码。我们可以用 tm_wday 作为标志来判断是否有数据被处理,以此确定是否发生了错误。

另外,还有一个基于 C 的小示例程序,它可以解析英文的 UTC 时间戳,并使用调用环境的本地化设置来打印时间:

$ LC_TIME="nl_NL.utf-8" ./utcparse "1 Jan 1970 00:00:00" "%d %b %Y %H:%M:%S"
UTC Time: donderdag,  1 januari 1970 00:00:00, day of year 001
time_t:   0

到了 C++20 及更高版本,更是引入了强大的时区数据库。虽然这个功能还没有在所有编译器上都可用,但预标准化版本可以单独使用。比如下面这个超酷的例子:

auto meet_nyc = make_zoned("America/New_York",
date::local_days{Monday[1]/May/2016} + 9h);
auto meet_lon = make_zoned("Europe/London",    meet_nyc);
auto meet_syd = make_zoned("Australia/Sydney", meet_nyc);
cout << "The New York meeting is " << meet_nyc << '\n';
cout << "The London   meeting is " << meet_lon << '\n';
cout << "The Sydney   meeting is " << meet_syd << '\n';

这段代码选择了 “2016 年 5 月的第一个星期一,纽约当地时间上午 9 点”,然后轻松地将其转换为另外两个时区的时间:

The New York meeting is 2016-05-02 09:00:00 EDT
The London   meeting is 2016-05-02 14:00:00 BST
The Sydney   meeting is 2016-05-02 23:00:00 AEST

更厉害的是,这个时区库不仅可以使用操作系统的时区数据库(可能缺少关键的闰秒细节),还能直接从 IANA tzdb 获取数据。这意味着你可以精确计算 1978 年一次航班飞行的实际时长,即使这次飞行跨越了夏令时变化和闰秒,也不在话下。

在 C 和 C++ 中从 UTC 日期时间字符串获取 Unix 时间戳确实充满挑战,但只要掌握了正确的方法,也能轻松应对。希望今天的分享能让你在处理时间相关的编程问题时更加得心应手。

科技脉搏,每日跳动。

与敖行客 Allthinker一起,创造属于开发者的多彩世界。

图片

- 智慧链接 思想协作 -

相关文章:

从 UTC 日期时间字符串获取 Unix 时间戳:C 和 C++ 中的挑战与解决方案

在编程世界里&#xff0c;从 UTC 日期时间字符串获取 Unix 时间戳&#xff0c;看似简单&#xff0c;实则暗藏玄机。你以为输入一个像 “Fri, 17 Jan 2025 06:07:07” 这样的 UTC 时间&#xff0c;然后轻松得到 1737094027&#xff08;从 1970 年 1 月 1 日 00:00:00 UTC 开始经…...

[Spring] Gateway详解

&#x1f338;个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 &#x1f3f5;️热门专栏: &#x1f9ca; Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm1001.2014.3001.5482 &#x1f355; Collection与…...

计数排序算法

基本思想 先确定待排序数组的最大值&#xff08;Max&#xff09;和最小值&#xff08;Min&#xff09;&#xff0c;随后创建Max - Min 1个长度的数组称为计数数组&#xff0c;计数数组的索引对应着待排序数组中元素的值&#xff0c;数组的值表示该元素的出现次数。通过从前往…...

Spring--基于注解的声明式事务

基于注解的声明式事务 1.选择一个合适的事务管理器实现加入到ioc容器 2.使用注解指定哪些方法需要添加事务即可 1.事务属性&#xff1a;只读 // readOnly true把当前事务设置为只读 默认是false! Transactional(readOnly true)Transactional注解放在类上 生效原则 如果一…...

SQL-leetcode—1164. 指定日期的产品价格

1164. 指定日期的产品价格 产品数据表: Products ---------------------- | Column Name | Type | ---------------------- | product_id | int | | new_price | int | | change_date | date | ---------------------- (product_id, change_date) 是此表的主键&#xff08;具…...

微服务搭建----springboot接入Nacos2.x

springboot接入Nacos2.x nacos之前用的版本是1.0的&#xff0c;现在重新搭建一个2.0版本的&#xff0c;学如逆水行舟&#xff0c;不进则退&#xff0c;废话不多说&#xff0c;开搞 1、 nacos2.x搭建 1&#xff0c;首先第一步查询下项目之间的版本对照&#xff0c;不然后期会…...

JavaEE:多线程进阶

JavaEE&#xff1a;多线程进阶 一、对比不同锁策略之间的应用场景及其区别1. 悲观锁 和 乐观锁1.1 定义和原理1.2 应用场景1.3 示例代码 2. 重量级锁 和 轻量级锁2.1 定义和原理2.2 应用场景2.3 示例代码 3. 挂起等待锁 和 自旋锁3.1 定义和原理3.2 应用场景3.3 示例代码 4. 几…...

软件测试 —— jmeter(2)

软件测试 —— jmeter&#xff08;2&#xff09; HTTP默认请求头&#xff08;元件&#xff09;元件作用域和取样器作用域HTTP Cookie管理器同步定时器jmeter插件梯度压测线程组&#xff08;Stepping Thread Group&#xff09;参数解析总结 Response Times over TimeActive Thre…...

[java] 面向对象进阶篇1--黑马程序员

目录 static 静态变量及其访问 实例变量及其访问 静态方法及其访问 实例方法及其访问 总结 继承 作用 定义格式 示例 总结 子类不能继承的内容 继承后的特点 成员变量 成员变量不重名 成员变量重名 super访问父类成员变量 成员方法 成员方法不重名 成员方法…...

openstack单机安装

openstack单机安装 网卡配置安装依赖开启虚拟环境修改配置文件 部署openstack部署openstack客户端访问可视化界面Horizon补充 本篇主要讲述Ubuntu2204单机安装openstackstable/2024.2。其他版本的Linux系统或者openstack版本&#xff0c;请参考openstack官网。 网卡配置 需要配…...

OFD、PDF 电子签章系统处理流程

在C#中实现电子签章系统的处理流程&#xff0c;可以参考以下步骤和技术实现&#xff1a; 1. 电子签章系统的基本流程 电子签章系统的核心流程包括以下几个步骤&#xff1a; 密钥生成&#xff1a;生成公钥和私钥对&#xff0c;私钥由签章人保管&#xff0c;公钥用于验证签名。…...

「 机器人 」系统辨识实验浅谈

前言 系统辨识实验是一种通过实验和数据分析的方法,用于建立物理系统的数学模型的技术。系统辨识是控制工程和系统科学中的重要环节,尤其是在模型未知或复杂的情况下。以下是系统辨识实验的详细介绍: 1. 系统辨识实验的目的 1.1 建模 为动态系统(如机械系统、电气系统或生…...

15.7k!DISM++一款快捷的系统优化工具

软件介绍 链接 软件介绍 dism是一款由初雨团队开发的win系统优化工具&#xff0c;可当作是微软系统命令行工具dism的GUI版本。可用作系统垃圾清除、启动项管理、程序卸载、驱动管理、系统优化等 该工具个人感觉最重要的就是系统优化选项&#xff0c;它将一些实用、无用或者没…...

Windows10安装MySQL找不到MSVCR120.dll和MSVCP120.dll问题解决

个人博客地址&#xff1a;Windows10安装MySQL找不到MSVCR120.dll和MSVCP120.dll问题解决 | 一张假钞的真实世界 msvcp120.dll、msvcr120.dll、vcomp120.dll属于VC2013版中的动态链接库&#xff0c;如果丢失重新安装VC2013即可。下载地址&#xff1a;https://www.microsoft.com…...

Vue 3 30天精进之旅:Day 03 - Vue实例

引言 在前两天的学习中&#xff0c;我们成功搭建了Vue.js的开发环境&#xff0c;并创建了我们的第一个Vue项目。今天&#xff0c;我们将深入了解Vue的核心概念之一——Vue实例。通过学习Vue实例&#xff0c;你将理解Vue的基础架构&#xff0c;掌握数据绑定、模板语法和指令的使…...

被遮挡QT窗口置顶

问题描述 开发环境&#xff1a;windows QT 需求&#xff1a; 单击托盘将桌面窗口在被遮挡的情况下置顶解决方案 方案1 资料链接 代码实现 Qt::WindowFlags flags windowFlags(); this->setWindowFlags((flags | Qt::WindowStaysOnTopHint)); this->showMaximized();…...

Apache Flink 概述学习笔记

一、引言 在大数据处理领域&#xff0c;Apache Flink 是一个极具影响力的开源流批一体化计算框架&#xff0c;它以其独特的架构和强大的功能&#xff0c;为大规模数据处理提供了高效、灵活的解决方案。 二、基本概念 Flink 是什么&#xff1a;Flink 是一个分布式流批处理框架…...

系统思考—复杂问题的根源分析

在企业中&#xff0c;许多问题看似简单&#xff0c;背后却潜藏着复杂的因果关系。传统的思维方式往往只能看到表面&#xff0c;而无法深入挖掘问题的真正根源。我们常常通过“表面解决”来应对眼前的症状&#xff0c;但这往往只是治标不治本。 比如&#xff0c;销量下降时&…...

Python 之 Excel 表格常用操作

示例文件 test.xlsx 将各个表单拆分成单独的 Excel 文件 import os.pathimport openpyxl import pandasdef handle_excel(file_path):dirname os.path.dirname(file_path)basename os.path.basename(file_path).split(".")[0]wb openpyxl.load_workbook(file_pat…...

《用DOTS解决实际需求》集锦

去年作者发布了一篇《DOTS-ECS系列课程》&#xff0c;深受同学们的好评&#xff01;前期课程是基于0.51版本录制的&#xff0c;DOTS升级至1.0版本后&#xff0c;同学们纷纷希望能使用DOTS 1.0版本录制实战课程。 今年作者带着DOTS 1.0版本的实战课程回来啦&#xff01;&#x…...

【MySQL】存储引擎有哪些?区别是什么?

频率难度60%⭐⭐⭐⭐ 这个问题其实难度并不是很大&#xff0c;只是涉及到的相关知识比较繁杂&#xff0c;比如事务、锁机制等等&#xff0c;都和存储引擎有关系。有时还会根据场景选择不同的存储引擎。 下面笔者将会根据几个部分尽可能地讲清楚 MySQL 中的存储引擎&#xff0…...

ios打包:uuid与udid

ios的uuid与udid混乱的网上信息 新人开发ios&#xff0c;发现uuid和udid在网上有很多帖子里是混淆的&#xff0c;比如百度下&#xff0c;就会说&#xff1a; 在iOS中使用UUID&#xff08;通用唯一识别码&#xff09;作为永久签名&#xff0c;通常是指生成一个唯一标识&#xf…...

Jadx动态调试安卓逆向

adb shell su ls 找到default.prop cat default.prop ro.debuggable0(代表没有调试权限) adb shell getprop ro.debuggable # 检查设备是否可调试&#xff08;1可调试&#xff09; adb shell getprop ro.product.cpu.abi # 获取设备 CPU 架构&#xff08;如 arm64-v…...

在Ubuntu上使用Apache+MariaDB安装部署Nextcloud并修改默认存储路径

一、前言 Nextcloud 是一款开源的私有云存储解决方案&#xff0c;允许用户轻松搭建自己的云服务。它不仅支持文件存储和共享&#xff0c;还提供了日历、联系人、任务管理、笔记等丰富的功能。本文将详细介绍如何在 Ubuntu 22.04 LTS 上使用 Apache 和 MariaDB 安装部署 Nextcl…...

FPGA实现任意角度视频旋转(二)视频90度/270度无裁剪旋转

本文主要介绍如何基于FPGA实现视频的90度/270度无裁剪旋转&#xff0c;关于视频180度实时旋转&#xff0c;请见本专栏前面的文章&#xff0c;旋转效果示意图如下&#xff1a; 为了实时对比旋转效果&#xff0c;采用分屏显示进行处理&#xff0c;左边代表旋转前的视频在屏幕中…...

六、深入了解DI

依赖注入是⼀个过程&#xff0c;是指IoC容器在创建Bean时,去提供运⾏时所依赖的资源&#xff0c;⽽资源指的就是对象. 在上⾯程序案例中&#xff0c;我们使⽤了 Autowired 这个注解&#xff0c;完成了依赖注⼊的操作. 简单来说,就是把对象取出来放到某个类的属性中。 关于依赖注…...

kotlin内联函数——let,run,apply,also,with的区别

一、概述 为了帮助您根据使用场景选择合适的作用域函数&#xff08;scope function&#xff09;&#xff0c;我们将对它们进行详细描述并提供使用建议。从技术上讲&#xff0c;许多情况下范围函数是可以互换使用的&#xff0c;因此示例中展示了使用它们的约定俗成的做法。 1.…...

火语言RPA—超级鹰打码

&#x1f6a9;【组件功能】&#xff1a;通过传入图像返回图像中的文字或结果信息 针对不同类型图片形式的验证码&#xff0c;提交至平台api&#xff0c;以字符串形式返回图片识别结果。 配置预览 配置说明 文件路径 支持T或# 默认FLOW输入项 待识别本地图片的完整路径。 用…...

C#新语法

目录 顶级语句&#xff08;C#9.0&#xff09; using 全局using指令&#xff08;C#10.0&#xff09; using资源管理问题 using声明&#xff08;C#8.0&#xff09; using声明陷阱 错误写法 正确写法 文件范围的命名空间声明&#xff08;C#10.0&#xff09; 可空引用类型…...

Cloudflare通过代理服务器绕过 CORS 限制:原理、实现场景解析

第一部分&#xff1a;问题背景 1.1 错误现象复现 // 浏览器控制台报错示例 Access to fetch at https://chat.qwenlm.ai/api/v1/files/ from origin https://ocr.doublefenzhuan.me has been blocked by CORS policy: Response to preflight request doesnt pass access con…...

lightgbm做分类

python import pandas as pd#导入csv文件的库 import numpy as np#进行矩阵运算的库 import json#用于读取和写入json数据格式#model lgb分类模型,日志评估,早停防止过拟合 from lightgbm import LGBMClassifier,log_evaluation,early_stopping #metric from sklearn.metrics …...

下载Visual Studio Community 2019

官方链接如下&#xff1a;Visual Studio Community 2019下载链接 https://learn.microsoft.com/zh-cn/visualstudio/releases/2019/system-requirements#download 目前官方仅建议2022版&#xff0c;已经关闭vs2019等旧版本&#xff0c;哪天开放了&#xff0c;记得踢我一下。 …...

深入理解MySQL事务(万字详)

文章目录 什么是事务为什么会出现事务事务的版本支持事务的提交方式事务常见操作方式正常演示 - 证明事务的开始与回滚非正常演示1 - 证明未commit&#xff0c;客户端崩溃&#xff0c;MySQL自动会回滚&#xff08;隔离级别设置为读未提交&#xff09;非正常演示2 - 证明commit了…...

FFPlay命令全集合

FFPlay是以FFmpeg框架为基础&#xff0c;外加渲染音视频的库libSDL构建的媒体文件播放器。 ffplay工具下载并播放视频&#xff0c;可以辅助卡看流信息。 官网下载地址&#xff1a;http://ffmpeg.org/download.html#build-windows 下载build好的exe程序&#xff1a; 此处下载…...

AI编程工具使用技巧:在Visual Studio Code中高效利用阿里云通义灵码

AI编程工具使用技巧&#xff1a;在Visual Studio Code中高效利用阿里云通义灵码 前言一、通义灵码介绍1.1 通义灵码简介1.2 主要功能1.3 版本选择1.4 支持环境 二、Visual Studio Code介绍1.1 VS Code简介1.2 主要特点 三、安装VsCode3.1下载VsCode3.2.安装VsCode3.3 打开VsCod…...

开源的Text-to-SQL工具WrenAI

WrenAI是一个开源的Text-to-SQL工具&#xff0c;旨在通过自然语言交互界面&#xff0c;帮助用户更便捷地查询数据库。以下是对WrenAI的详细介绍&#xff1a; 一、主要功能 自然语言交互&#xff1a;用户可以通过对话方式提出问题&#xff0c;WrenAI能够理解和解析复杂的查询需…...

python创建一个httpServer网页上传文件到httpServer

一、代码 1.server.py import os from http.server import SimpleHTTPRequestHandler, HTTPServer import cgi # 自定义请求处理类 class MyRequestHandler(SimpleHTTPRequestHandler):# 处理GET请求def do_GET(self):if self.path /:# 响应200状态码self.send_response(2…...

Linux中page、buffer_head、bio的关系

在Linux中&#xff0c;page、buffer_head、bio这三个概念紧密相关&#xff0c;共同构成了块设备I/O和内存管理的重要部分&#xff0c;它们的联系主要体现在以下方面&#xff1a; page与buffer_head 基于page构建&#xff1a;buffer_head通常是基于page来构建的&#xff0c;一…...

C++11新特性之decltype

1.decltype的作用 decltype是C11新增的一个关键字&#xff0c;与auto的功能一样&#xff0c;都是在编译期间推导变量类型的。不了解auto的可以转到——C11新特性之auto。 为什么引入decltype&#xff1f;看过上边那篇博客的读者应该知道auto在有些场景中并不适用,所以引入declt…...

对神经网络基础的理解

目录 一、《python神经网络编程》 二、一些粗浅的认识 1&#xff09; 神经网络也是一种拟合 2&#xff09;神经网络不是真的大脑 3&#xff09;网络构建需要反复迭代 三、数字图像识别的实现思路 1&#xff09;建立一个神经网络类 2&#xff09;权重更新的具体实现 3&am…...

后端开发Web

Maven Maven是apache旗下的一个开源项目&#xff0c;是一款用于管理和构建java项目的工具 Maven的作用 依赖管理 方便快捷的管理项目依赖的资源&#xff08;jar包&#xff09;&#xff0c;避免版本冲突问题 统一项目结构 提供标准、统一的项目结构 项目构建 标准跨平台(…...

QT 通过ODBC连接数据库的好方法:

效果图&#xff1a; PWD使用自己的&#xff0c;我的这是自己的&#xff0c;所以你用不了。 以下是格式。 // 1. 设置数据库连接 QSqlDatabase db QSqlDatabase::addDatabase("QODBC");// 建立和QMYSQL数据库的连接 // 设置数据库连接名称&#xff08;DSN&am…...

【Feature Scaling】:加速梯度下降法的利器

目录 特征缩放的目的常见的特征缩放方法1. 最小-最大缩放&#xff08;Min-Max Scaling&#xff09;2. 标准化&#xff08;Standardization 或 Z-Score Normalization&#xff09;3. 最大绝对值缩放&#xff08;Max Abs Scaling&#xff09; Rescale的使用场景结论 在机器学习中…...

QT:控件属性及常用控件(3)-----输入类控件(正则表达式)

输入类控件既可以进行显示&#xff0c;也能让用户输入一些内容&#xff01; 文章目录 1.Line Edit1.1 用户输入个人信息1.2 基于正则表达式的文本限制1.3 验证两次输入的密码是否一致1.4 让输入的密码可以被查看 2.Text Edit2.1 输入和显示同步2.1 其他信号出发情况 3.ComboBox…...

计算机网络 (59)无线个人区域网WPAN

前言 无线个人区域网&#xff08;WPAN&#xff0c;Wireless Personal Area Network&#xff09;是一种以个人为中心&#xff0c;采用无线连接方式的个人局域网。 一、定义与特点 定义&#xff1a;WPAN是以个人为中心&#xff0c;实现活动半径小、业务类型丰富、面向特定群体的无…...

Python Typing: 实战应用指南

文章目录 1. 什么是 Python Typing&#xff1f;2. 实战案例&#xff1a;构建一个用户管理系统2.1 项目描述2.2 代码实现 3. 类型检查工具&#xff1a;MyPy4. 常见的 typing 用法5. 总结 在 Python 中&#xff0c;静态类型检查越来越受到开发者的重视。typing 模块提供了一种方式…...

Redis存储③Redis基本命令+内部编号和架构

目录 1. Redis 命令行客户端 1.1 与 Redis 服务器交互 1.2 set 和 get 命令 2. 基本全局命令 2.1 keys 2.2 exists 2.3 del 2.4 expire 2.5 ttl 2.6 type 3. 数据结构和内部编码 4. 单线程架构 本篇完。 1. Redis 命令行客户端 1.1 与 Redis 服务器交互 根据上篇…...

Vivado生成X1或X4位宽mcs文件并固化到flash

1.生成mcs文件 01.在vivado里的菜单栏选择"tools"工具栏 02.在"tools"里选择"生成内存配置文件" 03.配置参数 按照FPGA板上的flash型号进行选型&#xff0c;相关配置步骤可参考下图。 注意&#xff1a;Flash数据传输位宽如果需要选择X4位宽&am…...

07 区块链安全技术

概述 区块链的安全特性 区块链解决了在不可靠网络上可靠地传输信息的难题&#xff0c;由于不依赖与中心节点的认证和管理&#xff0c;因此防止了中心节点被攻击造成的数据泄露和认证失败的风险。 区块链安全防护的三大特点 共识机制代替中心认证机制数据篡改“一发动全身”…...

第84期 | GPTSecurity周报

GPTSecurity是一个涵盖了前沿学术研究和实践经验分享的社区&#xff0c;集成了生成预训练Transformer&#xff08;GPT&#xff09;、人工智能生成内容&#xff08;AIGC&#xff09;以及大语言模型&#xff08;LLM&#xff09;等安全领域应用的知识。在这里&#xff0c;您可以找…...