SQL Server日期时间函数全解析:从基础概念到高阶应用与性能优化
1. 项目概述为什么你需要一份“最全”的日期时间函数指南干了这么多年数据库开发我发现一个挺有意思的现象无论是新手还是老手但凡涉及到SQL Server里的日期时间处理总免不了要去翻文档或者搜一下某个函数的具体用法。日期时间这个看似基础的数据类型在实际业务里却是“事故”高发区。订单的创建时间、用户的生日、活动的有效期、报表的统计周期……几乎每个关键业务逻辑都绕不开它。但问题在于SQL Server提供的日期时间函数零零散散有二三十个每个函数又有自己特定的参数和返回值格式光靠脑子记难免有疏漏。更让人头疼的是很多网上的资料要么不全只讲几个常用的GETDATE()、DATEADD要么就是直接贴官方文档的翻译缺乏实际场景的串联和避坑指南。结果就是开发时写出来的日期查询逻辑可能在测试环境跑得好好的一到生产环境遇到跨时区、闰年、月末最后一天或者性能瓶颈时就“现原形”了。所以我决定结合自己这些年踩过的坑和积累的经验整理一份真正“最全”且“能用”的SQL Server日期时间函数指南。这份指南的目的不是简单罗列函数而是帮你建立一个清晰的“工具箱”认知知道在什么场景下该用什么工具以及怎么用才最安全、最高效。2. 核心需求解析日期时间处理的四大核心场景在深入每个函数之前我们必须先搞清楚我们到底要用这些函数解决什么问题根据我的经验所有的日期时间操作都可以归结为以下四个核心场景理解了场景函数的学习就事半功倍了。2.1 场景一获取当前时间与服务器时间基准这是最基础的场景但水一点也不浅。核心需求是获取一个可靠的“此刻”时间戳。GETDATE()和SYSDATETIME()是最常用的但你知道它们有什么区别吗GETDATE()返回的是datetime类型精度到3.33毫秒而SYSDATETIME()返回的是datetime2类型精度高达100纳秒。在需要高精度时间戳的场景比如金融交易流水、高频日志记录必须使用SYSDATETIME()。我曾经遇到过因为使用GETDATE()导致两条几乎同时发生的交易记录时间戳完全相同给后续的审计和排序带来了麻烦。-- 获取当前日期和时间 (旧式精度较低) SELECT GETDATE() AS CurrentDateTime; -- 获取当前日期和时间 (高精度推荐用于新系统) SELECT SYSDATETIME() AS CurrentDateTimeHighPrecision; -- 只获取当前日期部分时间部分为00:00:00.000 SELECT CAST(GETDATE() AS DATE) AS Today; SELECT CONVERT(DATE, GETDATE()) AS Today; -- 另一种写法这里有一个非常重要的注意事项这些函数获取的是SQL Server实例所在服务器的系统时间。如果你的应用服务器和数据库服务器分布在不同的地理位置或者服务器时间未同步就会导致“应用层时间”和“数据库记录时间”不一致。对于分布式系统最佳实践是统一使用协调世界时UTC来存储和计算。这时你应该使用GETUTCDATE()或SYSUTCDATETIME()。注意在定义表结构时对于记录创建时间的字段如CreateTime我强烈建议默认值设置为GETUTCDATE()而非GETDATE()。这为未来可能的跨时区业务扩展打下了基础。2.2 场景二日期的“计算”与“推算”业务逻辑中充满了基于时间的推算“三天后发货”、“会员有效期一年”、“统计上个月的销售额”。这就是DATEADD和DATEDIFF函数的主场。DATEADD函数用于向日期添加一个时间间隔。它的语法是DATEADD(datepart, number, date)。关键在于第一个参数datepart它决定了加减的“单位”。常用的有YEAR,QUARTER,MONTH,DAY,WEEK,HOUR,MINUTE,SECOND等。-- 计算明天、下个月和一年后的今天 SELECT DATEADD(DAY, 1, GETDATE()) AS Tomorrow, DATEADD(MONTH, 1, GETDATE()) AS NextMonth, DATEADD(YEAR, 1, GETDATE()) AS NextYear; -- 一个实际案例计算订单的预计最晚发货时间假设下单后3个工作日内发货 -- 这里简化处理直接加3天。实际中可能需要排除周末和节假日。 SELECT OrderID, OrderDate, DATEADD(DAY, 3, OrderDate) AS LatestShipDate FROM Orders;DATEDIFF则用于计算两个日期之间的间隔。语法是DATEDIFF(datepart, startdate, enddate)。这里有一个经典的“坑”计算年龄。很多人会直接用DATEDIFF(YEAR, BirthDate, GETDATE())但这在生日还没到的那天会多算一岁。正确的做法需要结合CASE WHEN进行判断。-- 错误示例计算年龄 SELECT DATEDIFF(YEAR, 1990-02-28, 2023-02-27) AS WrongAge; -- 返回33实际应为32 -- 正确示例计算精确年龄 DECLARE BirthDate DATE 1990-02-28; DECLARE CurrentDate DATE 2023-02-27; SELECT DATEDIFF(YEAR, BirthDate, CurrentDate) - CASE WHEN MONTH(BirthDate) MONTH(CurrentDate) OR (MONTH(BirthDate) MONTH(CurrentDate) AND DAY(BirthDate) DAY(CurrentDate)) THEN 1 ELSE 0 END AS CorrectAge;2.3 场景三日期的“拆解”与“组装”我们经常需要从完整的日期时间中提取出年、月、日、星期几等部分或者反过来用这些部分组合成一个日期。这就是DATEPART、DATENAME和DATEFROMPARTS等函数的用武之地。DATEPART返回代表日期某部分的整数如年2023月8。DATENAME返回日期某部分的字符串名称如星期Friday月份August这个名称依赖于服务器的语言设置。-- 提取日期的各个部分 SELECT GETDATE() AS Now, DATEPART(YEAR, GETDATE()) AS YearPart, DATEPART(MONTH, GETDATE()) AS MonthPart, -- 返回8 DATENAME(MONTH, GETDATE()) AS MonthName, -- 返回August如果服务器语言是英文 DATEPART(WEEKDAY, GETDATE()) AS WeekdayNumber, -- 返回1-7 (周日1) DATENAME(WEEKDAY, GETDATE()) AS WeekdayName; -- 返回Sunday等 -- 根据年月日构建一个日期 (SQL Server 2012) -- 这是避免字符串拼接和隐式转换的推荐做法非常安全。 SELECT DATEFROMPARTS(2023, 8, 15) AS ConstructedDate; -- 2023-08-15 SELECT DATETIMEFROMPARTS(2023, 8, 15, 14, 30, 0, 0) AS ConstructedDateTime; -- 2023-08-15 14:30:00.000在报表开发中按年、月、季度分组统计是高频操作。使用DATEPART可以轻松实现-- 统计2023年每个月的销售额 SELECT DATEPART(MONTH, OrderDate) AS OrderMonth, SUM(OrderAmount) AS TotalAmount FROM SalesOrders WHERE DATEPART(YEAR, OrderDate) 2023 GROUP BY DATEPART(MONTH, OrderDate) ORDER BY OrderMonth;2.4 场景四日期的“格式化”与“解析”这是前端展示和外部数据导入时最常遇到的问题。数据库内部以二进制格式高效存储日期但展示给人看时需要转换成YYYY-MM-DD或DD/MM/YYYY等格式。CONVERT和FORMAT函数负责这项任务。CONVERT函数功能强大但用于日期格式化时主要依赖style参数。这个参数是一个数字代表不同的输出格式。-- 使用CONVERT进行日期格式化 SELECT GETDATE() AS Original, CONVERT(VARCHAR(10), GETDATE(), 120) AS Style_120, -- YYYY-MM-DD HH:MI:SS CONVERT(VARCHAR(10), GETDATE(), 112) AS Style_112, -- YYYYMMDD (纯数字适合排序或作为文件名) CONVERT(VARCHAR(10), GETDATE(), 23) AS Style_23; -- YYYY-MM-DD (ISO标准最推荐)FORMAT函数SQL Server 2012更加强大和直观它使用.NET Framework的格式字符串类似于C#中的ToString方法。-- 使用FORMAT进行更灵活的格式化 SELECT GETDATE() AS Original, FORMAT(GETDATE(), yyyy-MM-dd) AS ISO_Date, -- 2023-08-15 FORMAT(GETDATE(), dd/MM/yyyy) AS UK_Date, -- 15/08/2023 FORMAT(GETDATE(), dddd, MMMM dd, yyyy) AS LongDate; -- Tuesday, August 15, 2023重要提醒FORMAT函数虽然好用但性能开销较大因为它本质上是调用CLR公共语言运行时。在对大结果集数万行以上进行查询或在WHERE、GROUP BY子句中使用FORMAT时可能会引发严重的性能问题。在内部逻辑处理和条件筛选时应优先使用CONVERT或直接对DATEPART进行比较。FORMAT最好仅用于最终结果集的展示层。3. 核心函数库深度解析与实战技巧掌握了核心场景我们就可以系统地梳理SQL Server的日期时间函数库了。我将它们分为几个功能组并附上实战中总结的技巧和避坑点。3.1 获取与截断函数组这个组的函数负责获取时间点或对现有时间进行“修剪”。获取当前时间GETDATE()/CURRENT_TIMESTAMP返回当前datetime。CURRENT_TIMESTAMP是ANSI SQL标准写法。GETUTCDATE()返回当前UTC时间的datetime。SYSDATETIME()/SYSUTCDATETIME()返回高精度的datetime2分别对应本地和UTC时间。SYSDATETIMEOFFSET()返回包含时区偏移量的datetimeoffset类型时间这是处理跨时区数据的终极武器。截断函数CAST(date AS DATE)这是将datetime或datetime2截断至日期部分时间归零的最佳实践性能最好语义最清晰。CONVERT(DATE, date)功能同上是另一种写法。DATETRUNC(datepart, date)(SQL Server 2022 新增)这个新函数非常强大可以截断到指定的日期部分。例如DATETRUNC(MONTH, ‘2023-08-15 14:30:00’)将返回2023-08-01 00:00:00.000。如果你的环境是SQL Server 2022强烈推荐使用它来代替复杂的DATEADD和DATEDIFF组合。实战技巧如何高效地查询“今天”的数据错误做法是在WHERE子句中对字段使用函数这会导致索引失效。-- 错误做法导致全表扫描 SELECT * FROM Orders WHERE CAST(OrderDate AS DATE) CAST(GETDATE() AS DATE); -- 正确做法使用范围查询可以利用索引 SELECT * FROM Orders WHERE OrderDate CAST(GETDATE() AS DATE) AND OrderDate DATEADD(DAY, 1, CAST(GETDATE() AS DATE));3.2 计算与推算函数组这是业务逻辑的核心务必熟练掌握。DATEADD(datepart, number, date)前面已详细介绍。number可以为负数表示向前推算。DATEDIFF(datepart, startdate, enddate)计算两个日期的间隔。注意它计算的是跨越的“边界”数。例如DATEDIFF(DAY, ‘2023-08-15 23:59:59’, ‘2023-08-16 00:00:01’)返回1尽管时间差只有2秒。EOMONTH(start_date [, month_to_add])(SQL Server 2012)神级函数传入一个日期返回该日期所在月份的最后一天。可选参数month_to_add可以推算未来或过去某个月的最后一天。-- 获取本月底、下月底、上月底的日期 SELECT EOMONTH(GETDATE()) AS ThisMonthEnd, -- 2023-08-31 EOMONTH(GETDATE(), 1) AS NextMonthEnd, -- 2023-09-30 EOMONTH(GETDATE(), -1) AS LastMonthEnd; -- 2023-07-31 -- 经典应用生成一个月的日期维度表 DECLARE StartDate DATE 2023-08-01; DECLARE EndDate DATE EOMONTH(StartDate); -- ... 后续可以用循环或递归CTE生成从StartDate到EndDate的所有日期3.3 提取与解析函数组用于从日期中获取特定部件。DATEPART(datepart, date)返回整数。DATENAME(datepart, date)返回字符串。注意其语言依赖性。YEAR(date)/MONTH(date)/DAY(date)DATEPART的快捷方式代码更简洁。组装函数DATEFROMPARTS(year, month, day),DATETIME2FROMPARTS,SMALLDATETIMEFROMPARTS,TIMEFROMPARTS等。在动态构造日期时永远优先使用这些函数而不是字符串拼接可以完全避免格式歧义和转换错误。-- 危险的字符串拼接 DECLARE y INT2023, m INT08, d INT15; SELECT CAST(y AS VARCHAR) - m - d; -- 可能因类型转换失败或格式问题出错 -- 安全的组装方式 SELECT DATEFROMPARTS(y, m, d); -- 2023-08-153.4 验证与判断函数组用于处理脏数据或进行逻辑判断。ISDATE(expression)判断字符串是否可以转换为日期。返回1真或0假。但要注意它的结果受会话语言设置影响例如‘01/02/03’在美国语言下可能是2003-01-02在英国语言下可能是2003-02-01而ISDATE可能都返回1但转换结果不同。日期范围校验SQL Server本身没有直接的“是否在范围内”函数但我们可以轻松组合。-- 判断一个日期是否在本周内 DECLARE TargetDate DATE 2023-08-16; SELECT CASE WHEN TargetDate DATEADD(WEEK, DATEDIFF(WEEK, 0, GETDATE()), 0) -- 本周周一 AND TargetDate DATEADD(WEEK, DATEDIFF(WEEK, 0, GETDATE()) 1, 0) -- 下周一 THEN 在本周内 ELSE 不在本周内 END AS WeekCheck;3.5 格式化与转换函数组CONVERT(data_type, date [, style])功能多样可用于类型转换和格式化。记住几个关键style码112(YYYYMMDD),120(YYYY-MM-DD HH:MI:SS),23(YYYY-MM-DD)。FORMAT(date, format [, culture])功能强大但慎用。culture参数可以指定区域设置如‘en-US’,‘zh-CN’。-- 使用FORMAT进行本地化展示 SELECT FORMAT(GETDATE(), D, zh-CN) AS ChineseLongDate; -- 2023年8月15日 SELECT FORMAT(GETDATE(), d, en-US) AS USShortDate; -- 8/15/20234. 高阶应用与性能优化实战把单个函数用熟只是第一步真正考验功力的是如何将它们组合起来解决复杂的业务问题并保证高性能。4.1 复杂业务场景拆解场景A计算工作日排除周末和节假日这是一个经典需求。我们需要一个“工作日日历表”作为基础。假设我们有一个WorkCalendar表包含所有工作日日期。-- 计算订单从下单到发货的工作日天数 SELECT o.OrderID, o.OrderDate, o.ActualShipDate, (SELECT COUNT(*) FROM WorkCalendar c WHERE c.WorkDate o.OrderDate AND c.WorkDate o.ActualShipDate) AS WorkingDays FROM Orders o WHERE o.ActualShipDate IS NOT NULL;场景B生成连续日期序列用于填充报表缺失日期使用递归公共表表达式CTE是标准做法。DECLARE StartDate DATE 2023-08-01; DECLARE EndDate DATE 2023-08-31; WITH DateSeries AS ( SELECT StartDate AS TheDate UNION ALL SELECT DATEADD(DAY, 1, TheDate) FROM DateSeries WHERE TheDate EndDate ) SELECT TheDate, DATENAME(WEEKDAY, TheDate) AS WeekdayName FROM DateSeries OPTION (MAXRECURSION 365); -- 防止无限递归场景C处理月末最后一天的特殊逻辑DATEADD和DATEDIFF在处理月末时有个“陷阱”DATEADD(MONTH, 1, ‘2023-01-31’)会得到2023-02-28而DATEADD(MONTH, DATEDIFF(MONTH, 0, ‘2023-01-31’), 0)可以得到当月的第一天。结合EOMONTH函数可以更优雅地处理。-- 获取任意日期所在月份的第一天SQL Server 2008通用方法 SELECT DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()), 0) AS FirstDayOfMonth; -- 获取上个月的最后一天使用EOMONTH SELECT EOMONTH(GETDATE(), -1) AS LastDayOfLastMonth;4.2 索引与SARGable原则优化这是性能优化的核心。SARGable指的是查询条件能够利用索引Search Argument Able。在WHERE和JOIN子句中对日期列进行任何函数操作如CONVERT,FORMAT,DATEPART,DATEADD等都会导致索引失效。-- 反例非SARGable无法使用OrderDate上的索引 SELECT * FROM LargeSalesTable WHERE YEAR(OrderDate) 2023 AND MONTH(OrderDate) 8; -- 正例SARGable可以高效利用索引 SELECT * FROM LargeSalesTable WHERE OrderDate 2023-08-01 AND OrderDate 2023-09-01; -- 另一个常见反例查询“过去30天”的数据 SELECT * FROM LogTable WHERE DATEDIFF(DAY, CreateTime, GETDATE()) 30; -- 糟糕 -- 正例 SELECT * FROM LogTable WHERE CreateTime DATEADD(DAY, -30, GETDATE()); -- 优秀对于按年、月、季度分组的统计查询如果WHERE条件中必须使用函数可以考虑创建持久化计算列并为其建立索引。-- 1. 添加计算列 ALTER TABLE Sales ADD SaleYear AS YEAR(OrderDate) PERSISTED; ALTER TABLE Sales ADD SaleMonth AS MONTH(OrderDate) PERSISTED; -- 2. 在计算列上创建索引 CREATE INDEX IX_Sales_YearMonth ON Sales(SaleYear, SaleMonth); -- 3. 查询时直接使用计算列效率极高 SELECT SaleYear, SaleMonth, SUM(Amount) FROM Sales WHERE SaleYear 2023 AND SaleMonth 8 GROUP BY SaleYear, SaleMonth;4.3 时区处理最佳实践对于全球化应用时区是必须严肃对待的问题。我的建议是存储层始终使用UTC时间。使用datetimeoffset类型存储可以保留原始的时区信息但更常见的做法是用datetime2存储UTC时间。业务逻辑层所有内部计算、比较、排序都基于UTC时间进行。展示层在数据最终呈现给用户前根据用户的个人时区设置在应用服务器或数据库查询中使用AT TIME ZONESQL Server 2016进行转换。-- 假设我们以UTC时间存储 CREATE TABLE Events ( EventId INT PRIMARY KEY, EventName NVARCHAR(100), EventTimeUTC DATETIME2 ); -- 插入一条UTC时间记录 INSERT INTO Events VALUES (1, Product Launch, 2023-08-15 09:00:00); -- 查询时转换为美国东部时间夏令时 SELECT EventName, EventTimeUTC AT TIME ZONE UTC AT TIME ZONE Eastern Standard Time AS EventTimeEST FROM Events; -- 查询今天美国东部时间的事件 DECLARE TodayEST DATE CAST(SYSDATETIMEOFFSET() AT TIME ZONE Eastern Standard Time AS DATE); SELECT * FROM Events WHERE CAST(EventTimeUTC AT TIME ZONE UTC AT TIME ZONE Eastern Standard Time AS DATE) TodayEST;注意AT TIME ZONE转换依赖于SQL Server服务器上的时区数据。确保你的服务器操作系统时区数据是最新的特别是对于夏令时规则可能变化的地区。5. 常见疑难杂症与避坑指南在实际开发中你一定会遇到下面这些问题。我把它们和解决方案记录下来希望能帮你节省大量排查时间。5.1 日期格式歧义与转换失败这是最经典的“坑”。‘01/02/2023’是1月2日还是2月1日这取决于服务器的DATEFORMAT或语言设置。根本原因当使用CONVERT或CAST从字符串隐式或显式转换为日期时SQL Server会尝试根据当前会话的设置去解析。如果字符串格式不明确就可能出错或得到意外结果。解决方案使用标准格式对于字面量使用YYYYMMDD或YYYY-MM-DDTHH:MM:SS这类无歧义的ISO格式。SQL Server总能正确解析它们。SELECT CAST(20230815 AS DATE); -- 安全 SELECT CAST(2023-08-15T14:30:00 AS DATETIME2); -- 安全使用CONVERT并明确指定style参数如果你必须处理非标准格式字符串使用CONVERT并指定第三参数style码。SELECT CONVERT(DATE, 15/08/2023, 103); -- 指定为dd/mm/yyyy格式 (style 103)使用PARSE函数 (SQL Server 2012)PARSE可以配合区域性设置更智能地解析但性能比CONVERT差。SELECT PARSE(August 15, 2023 AS DATE USING en-US);在应用层统一转换最彻底的做法是在代码C#, Java等中将日期格式化为无歧义的字符串如ISO 8601再传递给数据库。5.2 时间类型的精度与溢出问题datetime类型范围1753-01-01到9999-12-31精度3.33毫秒。不要用它存储1753年以前的日期如历史数据。datetime2类型范围0001-01-01到9999-12-31精度可指定最高100纳秒。对于新项目无脑选择datetime2就对了。smalldatetime类型范围1900-01-01到2079-06-06精度到分钟。存储空间小但范围有限且精度低现代系统已很少使用。date类型仅存储日期无时间部分。存储生日、纪念日等非常合适。time类型仅存储时间无日期部分。避坑点在进行日期计算时要注意类型的隐式转换和可能的数据截断。例如将datetime2的高精度值赋给datetime列会损失精度。5.3 日期函数在WHERE子句中的性能陷阱如前所述在WHERE子句中对索引列使用函数是性能杀手。这里再强调几个隐蔽的陷阱隐式转换如果WHERE子句中比较的两个值数据类型不同SQL Server会进行隐式转换也可能导致索引失效。-- 假设OrderDate是datetime类型 DECLARE SearchDate VARCHAR(20) 2023-08-15; SELECT * FROM Orders WHERE OrderDate SearchDate; -- 发生隐式转换索引可能失效 -- 应改为 SELECT * FROM Orders WHERE OrderDate CAST(SearchDate AS DATETIME);使用BETWEEN处理日期范围BETWEEN是包含边界的。对于带有时间的datetime字段BETWEEN ‘2023-08-15’ AND ‘2023-08-15’查不到任何数据因为‘2023-08-15’被当作‘2023-08-15 00:00:00.000’。更推荐使用和的组合。5.4 特定函数在不同版本间的差异FORMAT和EOMONTH是SQL Server 2012引入的。DATETRUNC是SQL Server 2022引入的。AT TIME ZONE是SQL Server 2016引入的。在编写通用脚本或为不同版本环境提供支持时要注意函数的兼容性。可以使用IF语句判断版本或者准备替代方案。-- 模拟DATETRUNC功能用于SQL Server 2012-2019 DECLARE InputDate DATETIME2 GETDATE(); DECLARE DatePart VARCHAR(10) MONTH; SELECT CASE DatePart WHEN YEAR THEN DATEFROMPARTS(YEAR(InputDate), 1, 1) WHEN MONTH THEN DATEFROMPARTS(YEAR(InputDate), MONTH(InputDate), 1) WHEN DAY THEN CAST(InputDate AS DATE) -- ... 其他部分 END AS TruncatedDate;5.5 星期与工作日计算的区域性差异DATEPART(WEEKDAY, date)的返回值受SET DATEFIRST设置影响。DATEFIRST定义了每周的第一天是星期几美国是周日7欧洲多是周一1。这会导致按周分组统计时结果不一致。解决方案在需要跨区域一致性的查询中显式设置DATEFIRST或者使用更复杂的计算来标准化星期数。-- 将周一作为每周的第一天并返回1-7周一到周日 SET DATEFIRST 1; SELECT DATEPART(WEEKDAY, GETDATE()) AS MondayBasedWeekday; -- 或者使用一个不依赖DATEFIRST的计算方法 SELECT (DATEPART(WEEKDAY, GETDATE()) DATEFIRST - 2) % 7 1 AS ConsistentWeekday;处理日期时间本质上是在处理业务规则的具象化。这份指南里的每一个函数、每一个技巧背后都是无数个需求、无数个坑堆出来的经验。我最深的体会是在数据库设计之初就明确日期时间字段的用途是纯日期、时间戳还是带时区选择正确的数据类型并坚持使用UTC时间存储能为后续开发省去至少一半的麻烦。当遇到复杂的日期逻辑时别急着写一堆嵌套函数先拆解步骤用CTE或者临时表把中间结果理清楚代码的可读性和可维护性会高很多。最后性能问题往往出现在最不起眼的地方养成在WHERE子句中避免对索引列进行函数操作的习惯是写出高效SQL的基本素养。

相关新闻

B站视频下载终极指南:三步解锁大会员4K高清视频

B站视频下载终极指南:三步解锁大会员4K高清视频

B站视频下载终极指南:三步解锁大会员4K高清视频 【免费下载链接】bilibili-downloader B站视频下载,支持下载大会员清晰度4K,持续更新中 项目地址: https://gitcode.com/gh_mirrors/bil/bilibili-downloader 还在为B站上的精彩视频无法…

2026/10/13 23:02:39 阅读更多 →
软件设计的一些感想

软件设计的一些感想

软件设计的一些感想 做了十几年软件,写过无数行代码,也重构过无数个深夜。回头看,软件设计这件事,最难的从来不是技术选型或者算法优化,而是如何在复杂中保持简单,在变化中守住稳定。今天不聊高深的理论&am…

2026/10/13 23:02:10 阅读更多 →
Unity渲染优化:DrawCall、Batch与SetPassCall核心概念与性能优化实战

Unity渲染优化:DrawCall、Batch与SetPassCall核心概念与性能优化实战

1. 项目概述:从性能瓶颈说起 做Unity开发,尤其是涉及复杂UI、大型场景或者移动平台项目时,性能优化是绕不开的话题。你肯定听过团队里有人喊“DrawCall太高了,得合批!”,或者在看Profiler窗口时&#xff0c…

2026/10/12 19:35:53 阅读更多 →

最新新闻

AI合规不止于模型:ISO/IEC 42001:2023 管理体系要点解析

AI合规不止于模型:ISO/IEC 42001:2023 管理体系要点解析

简介:《ISO/IEC 42001:2023》是ISO与IEC联合发布的首个人工智能管理体系国际标准,为各类组织在使用或开发AI产品与服务时建立、执行、维护并持续改进AI管理系统(AIMS)提供了权威框架。这份PDF文档内含完整正文和附录,共…

2026/10/13 23:02:16 阅读更多 →
openpyxl读取Excel实战:从单元格到大文件性能优化

openpyxl读取Excel实战:从单元格到大文件性能优化

接过一个统计报表的活儿,要在一堆 Excel 里提取数据并汇总。刚开始我图省事,直接用 pandas 一把梭,后来发现需求越来越细:要判断单元格格式、要区分公式和结果、要处理合并单元格和文本型数字,还得在大文件场景下控内存…

2026/10/13 23:02:16 阅读更多 →
计算机二级C语言备考攻略:吃透题库与操作题是关键

计算机二级C语言备考攻略:吃透题库与操作题是关键

计算机二级C语言,大概是全国计算机等级考试里报名量最大的一科。我身边有不少人抱着“多一个证总没坏处”的心态报了名,然后备考方式就是借一本C语言教材从第一页开始啃,啃到指针就放弃,最后上考场,选择题靠直觉&#…

2026/10/13 23:02:16 阅读更多 →
破解版资源不可取:如何合规分享技术资源与实战笔记

破解版资源不可取:如何合规分享技术资源与实战笔记

简介:Evp破解版工具是一款面向服务端开发、部署及运维人员的实用资源,主要解决服务端文件的解压与修改问题。根据页面描述,该工具在服务端场景中具有不可替代性——常规解压软件可能无法正确识别或处理服务端特殊文件结构,必须借助…

2026/10/13 23:02:16 阅读更多 →
C++/WinRT 文件处理实战:从 StorageFile 到异步读写与流式处理

C++/WinRT 文件处理实战:从 StorageFile 到异步读写与流式处理

如果你刚从 Win32 转过来写 C/WinRT,第一件需要适应的就是“文件不再是一个句柄”。过去我打开文件拿到 HFILE,然后 ReadFile、WriteFile,一套组合拳打完收工。到了 C/WinRT 里,文件被封装成了StorageFile对象,读文件不…

2026/10/13 23:02:16 阅读更多 →
Django+LLM+遗传算法:打造AI驱动的旅游路线规划与推荐系统

Django+LLM+遗传算法:打造AI驱动的旅游路线规划与推荐系统

每年毕业设计的选题库里,“旅游网站”几乎是大热门,但说实话,十个里面至少有八个做成了标准的增删改查演示——用户注册登录、景点列表、后台维护,顶多再加一个关键字搜索。答辩的时候老师问一句“技术亮点在哪里”,很…

2026/10/13 23:01:16 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 22:01:27 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →