First Day

作者开始研究SDL,认为其中文文档简单,使用灵活但功能可能稍差。展示了第一个SDL程序代码,编译时遇到重复定义的问题,通过屏蔽LIBCMTD.lib解决。作者使用的是VC.NET 2003,后续打算更换为2005。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天开始用了用SDL。其实都看了好多天了,中文文档好简单。看起来SDL有些太简单,用起来会比较灵活,但是功能是不是会稍差呢(-?-)。还是抱着研究的心态继续吧。

第一个程序sdl_test

#include <stdlib.h>
#include "SDL.h"

int main(int argc, char *argv[])
{
    if ( SDL_Init(SDL_INIT_AUDIO|SDL_INIT_VIDEO) < 0 ) {
        fprintf(stderr, "无法初始化SDL: %s/n", SDL_GetError());
        exit(1);
    }
    atexit(SDL_Quit);
    return 1;
}

嘿嘿,其实就是中文文档的《初始化SDL库》的例子了。不过编译的时候还是遇到点小问题:

MSVCRT.lib(MSVCR71.dll) : error LNK2005: _exit 已经在 LIBCMTD.lib(crt0dat.obj) 中定义
MSVCRT.lib(MSVCR71.dll) : error LNK2005: _strncpy 已经在 LIBCMTD.lib(strncpy.obj) 中定义
MSVCRT.lib(MSVCR71.dll) : error LNK2005: _fclose 已经在 LIBCMTD.lib(fclose.obj) 中定义
MSVCRT.lib(MSVCR71.dll) : error LNK2005: __isctype 已经在 LIBCMTD.lib(isctype.obj) 中定义

不知道这个是不是VC管的太多~~~不管3 7 21,把LIBCMTD.lib屏蔽了先。呵呵,倒是过了。看来一切顺利,先到这里吧,下班回家~~

PS:偶用的是VC.NET 2003,改天换个2005

内容概要:该研究通过在黑龙江省某示范村进行24小时实地测试,比较了燃煤炉具与自动/手动进料生物质炉具的污染物排放特征。结果显示,生物质炉具相比燃煤炉具显著降低了PM2.5、CO和SO2的排放(自动进料分别降低41.2%、54.3%、40.0%;手动进料降低35.3%、22.1%、20.0%),但NOx排放未降低甚至有所增加。研究还发现,经济性和便利性是影响生物质炉具推广的重要因素。该研究不仅提供了实际排放数据支持,还通过Python代码详细复现了排放特征比较、减排效果计算和结果可视化,进一步探讨了燃料性质、动态排放特征、碳平衡计算以及政策建议。 适合人群:从事环境科学研究的学者、政府环保部门工作人员、能源政策制定者、关注农村能源转型的社会人士。 使用场景及目标:①评估生物质炉具在农村地区的推广潜力;②为政策制定者提供科学依据,优化补贴政策;③帮助研究人员深入了解生物质炉具的排放特征和技术改进方向;④为企业研发更高效的生物质炉具提供参考。 其他说明:该研究通过大量数据分析和模拟,揭示了生物质炉具在实际应用中的优点和挑战,特别是NOx排放增加的问题。研究还提出了多项具体的技术改进方向和政策建议,如优化进料方式、提高热效率、建设本地颗粒厂等,为生物质炉具的广泛推广提供了可行路径。此外,研究还开发了一个智能政策建议生成系统,可以根据不同地区的特征定制化生成政策建议,为农村能源转型提供了有力支持。
<think>我们需要获取本月的第一天,并且将时间设置为00:00:00.000(即午夜),然后转换为ISO字符串,并截取前19个字符(即去掉时区部分,保留到秒)。 原代码中,我们创建了一个Date对象,然后将其设置为当月的第一天(setDate(1)),接着将小时、分钟、秒和毫秒都设置为0(setHours(0,0,0,0))。 然后使用toISOString()将其转换为ISO格式的字符串(例如:"2024-06-01T00:00:00.000Z"),再用slice(0,19)截取前19个字符(即"2024-06-01T00:00:00"),最后加上'Z'表示UTC时间?但是原代码没有加,实际上toISOString()返回的是UTC时间,并且末尾会带有一个'Z'。而slice(0,19)会去掉毫秒和后面的'Z',所以得到的是一个不包含时区信息的字符串,但表示的是UTC时间。 但是,请注意:原代码中firstDayISO得到的是一个没有时区标识的字符串,但实际上是UTC时间。如果我们想要本地时间的ISO格式,但又不带时区,可能不是标准的做法。 根据需求,我们可能需要的是本地时间的当月第一天零点。原代码使用new Date()创建的是本地时间,然后setDate(1)也是基于本地时间的,setHours(0,0,0,0)也是本地时间的零点。但是toISOString()会将其转换为UTC时间(即会加上或减去时区偏移,然后表示为UTC时间)。所以如果我们的当前时区不是UTC,那么转换后的时间可能就不是我们想要的本地时间零点,而是前一天的某个时间(如果时区为正)或者当天的某个时间(如果时区为负)。 因此,如果我们想要本地时间的字符串,应该使用其他方法。 我们可以这样: 1. 获取本地时间的年月日时分秒,然后组合成ISO格式的字符串,但是这样比较麻烦。 2. 使用toISOString会转换为UTC,所以如果我们想要本地时间的表示,且不带时区,我们可以使用toLocaleString等,但格式控制复杂。 或者,我们可以这样:先得到本地时间当天的零点(即00:00:00.000),然后格式化为我们需要的字符串。 但原代码要求输出ISO格式的字符串(不带时区),但实际上ISO格式是包含时区的,如果不带时区,严格来说不是ISO格式。不过,我们有时会省略时区,表示本地时间。 根据问题,改写获取本月的第一天日期和时间(本地时间),并格式化为类似ISO的字符串(即"YYYY-MM-DDTHH:mm:ss"),但不带时区。 我们可以这样实现: 方法一:使用Date对象的方法获取本地时间的各个部分,然后拼成字符串。 方法二:使用toISOString,然后调整时区偏移(比较复杂)。 但是,由于toISOString总是返回UTC时间,所以如果我们想要本地时间的字符串,并且格式为ISO格式(不带时区),我们可以先计算出时区偏移,然后调整时间,再用toISOString得到我们想要的本地时间字符串?这有点绕。 实际上,我们可以这样: 步骤: 1. 获取当前日期的本地时间,并设置为本月第一天,时间为00:00:00.000。 2. 获取这个时间对象的UTC时间表示(通过getTime(),即时间戳)。 3. 然后根据时区偏移调整时间戳,得到本地时间对应的UTC时间(实际上就是时间戳减去时区偏移分钟数),然后用这个时间戳创建一个新的Date对象,这个新的Date对象用toISOString()就会得到我们想要的本地时间字符串(因为减去了时区偏移,所以toISOString()得到的字符串中的时间正好是原来的本地时间)。 但是,这样有点复杂。而且,我们也可以直接提取本地时间的各个部分,然后格式化为字符串。 这里我们采用直接格式化的方法: 例如: ```javascript const firstDay = new Date(); firstDay.setDate(1); firstDay.setHours(0, 0, 0, 0); // 获取本地时间的各个部分 const year = firstDay.getFullYear(); const month = String(firstDay.getMonth() + 1).padStart(2, '0'); // 月份从0开始,所以+1 const day = String(firstDay.getDate()).padStart(2, '0'); const hours = String(firstDay.getHours()).padStart(2, '0'); const minutes = String(firstDay.getMinutes()).padStart(2, '0'); const seconds = String(firstDay.getSeconds()).padStart(2, '0'); // 组合成ISO格式的字符串(不含时区) const firstDayISO = `${year}-${month}-${day}T${hours}:${minutes}:${seconds}`; ``` 但是,由于我们已经将时间设置为0,0,0,0,所以小时、分钟、秒都是0,所以可以简写为: ```javascript const firstDay = new Date(); firstDay.setDate(1); firstDay.setHours(0, 0, 0, 0); const year = firstDay.getFullYear(); const month = String(firstDay.getMonth() + 1).padStart(2, '0'); const day = String(firstDay.getDate()).padStart(2, '0'); const firstDayISO = `${year}-${month}-${day}T00:00:00`; ``` 但是,这样得到的字符串是本地时间,但没有时区信息。如果后续使用这个字符串时,需要知道它是本地时间,否则可能会被误解为UTC时间。 另一种方法是使用toLocaleString,但我们需要指定格式,并且要确保格式为ISO格式。 考虑到原代码使用了toISOString().slice(0,19),这得到的是UTC时间的字符串。如果原意就是要UTC时间,那么原代码没有问题。但问题描述是“获取本月的第一天日期和时间”,没有说明是UTC还是本地时间。 根据问题描述,原代码使用new Date()创建的是本地时间,然后设置为本月第一天,然后设置为0点,然后转换为ISO字符串(UTC时间)。所以如果需求是获取当月的第一天UTC时间的0点,那么原代码就是正确的。 所以,我们需要明确:需求是获取本地时间的当月第一天零点,还是UTC时间的当月第一天零点? 问题没有明确,但原代码中使用了toISOString,所以它返回的是UTC时间。而原代码的意图可能是获取UTC时间的当月第一天零点。 但是,原代码中new Date()返回的是本地时间,然后setDate(1)和setHours(0,0,0,0)都是基于本地时间的。所以,这个Date对象表示的是本地时间当月的第一天零点。然后toISOString()会把这个本地时间转换成UTC时间(即减去时区偏移),所以结果可能不是当月的第一天零点(如果时区偏移为正,那么UTC时间会提前,比如在UTC+8时区,本地时间6月1日00:00:00对应的UTC时间是5月31日16:00:00)。 因此,原代码的逻辑可能并不是获取当月的第一天UTC时间零点,而是获取本地时间当月第一天零点对应的UTC时间。 如果需求是获取当前时区的当月第一天零点,并且以ISO格式(带时区)表示,我们可以使用toISOString,但是这样会转换为UTC时间,所以不是我们想要的本地时间零点。 所以,如果需求是获取本地时间当月第一天零点,并且格式化为类似ISO格式的字符串(但不带时区),那么我们可以使用上述的格式化方法。 如果需求是获取UTC时间的当月第一天零点,那么我们应该这样: ```javascript const firstDayUTC = new Date(); firstDayUTC.setUTCDate(1); firstDayUTC.setUTCHours(0, 0, 0, 0); const firstDayISO = firstDayUTC.toISOString().slice(0,19); // 或者直接取前19个字符 ``` 这样得到的是UTC时间当月的第一天零点。 由于问题描述是“改写获取本月的第一天日期和时间”,没有明确是本地时间还是UTC时间,但原代码是获取本地时间当月第一天零点,然后转换为UTC时间字符串。所以,我们根据原代码的意图,可能是想得到UTC时间字符串。但原代码的转换会导致时间偏移。 因此,我们需要明确需求。这里我假设需求是:获取本地时间的当月第一天零点,并格式化为ISO格式的字符串(不带时区,即"YYYY-MM-DDTHH:mm:ss")。 所以,改写如下: ```javascript const firstDay = new Date(); firstDay.setDate(1); firstDay.setHours(0, 0, 0, 0); // 格式化为ISO格式的本地时间字符串(不带时区) const year = firstDay.getFullYear(); const month = String(firstDay.getMonth() + 1).padStart(2, '0'); const day = String(firstDay.getDate()).padStart(2, '0'); const firstDayISO = `${year}-${month}-${day}T00:00:00`; ``` 但是,如果需求是UTC时间,那么应该用另一种方法。 考虑到问题中使用了toISOString,可能原意是想要UTC时间,那么正确的获取UTC时间当月第一天零点的方法应该是: ```javascript const now = new Date(); const firstDayUTC = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), 1, 0, 0, 0, 0)); const firstDayISO = firstDayUTC.toISOString().slice(0, 19); ``` 或者 ```javascript const firstDay = new Date(); firstDay.setUTCDate(1); firstDay.setUTCHours(0,0,0,0); const firstDayISO = firstDay.toISOString().slice(0,19); ``` 但是,注意:setUTCDate(1)设置的是UTC日期为1,那么本地时间可能会变化(比如在UTC+8时区,当本地时间为6月1日12:00时,UTC时间是6月1日4:00,设置UTC日期为1,那么UTC时间变成6月1日00:00:00,本地时间就是6月1日08:00:00,这显然不是我们想要的本地时间当月的第一天)。 所以,如果需求是UTC时间当月第一天零点,那么应该用Date.UTC来构造一个UTC时间。 鉴于问题描述不明确,我将提供两种方案: 方案一:获取本地时间当月第一天零点,并格式化为本地时间字符串(不带时区): ```javascript const firstDay = new Date(); firstDay.setDate(1); firstDay.setHours(0,0,0,0); const year = firstDay.getFullYear(); const month = String(firstDay.getMonth() + 1).padStart(2, '0'); const day = String(firstDay.getDate()).padStart(2, '0'); const firstDayISO = `${year}-${month}-${day}T00:00:00`; ``` 方案二:获取UTC时间当月第一天零点,并格式化为ISO字符串(UTC时间,带Z): ```javascript const now = new Date(); // 获取UTC时间的当月第一天 const firstDayUTC = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), 1, 0, 0, 0, 0)); const firstDayISO = firstDayUTC.toISOString().slice(0,19) + 'Z'; // 或者不加Z,因为toISOString()返回的字符串包含Z,但我们slice(0,19)后去掉了Z,所以这里我们可以加上 // 但原代码没有加,所以如果我们想要和原代码一样的格式(不带Z),那么就是slice(0,19) // 原代码是slice(0,19),所以没有Z ``` 但是,原代码没有Z,所以方案二可以写成: ```javascript const firstDayUTC = new Date(Date.UTC(new Date().getUTCFullYear(), new Date().getUTCMonth(), 1)); const firstDayISO = firstDayUTC.toISOString().slice(0,19); ``` 或者更简洁的,直接使用: ```javascript const firstDayISO = new Date(Date.UTC(new Date().getUTCFullYear(), new Date().getUTCMonth(), 1)).toISOString().slice(0,19); ``` 由于问题中要求“改写”,并且原代码是获取本地时间然后转换为UTC时间字符串,但这样转换的结果并不是UTC时间当月的第一天零点,而是本地时间当月第一天零点对应的UTC时间(可能跨月)。所以,我猜测原代码可能是有问题的,需要根据实际需求来定。 如果原意是获取本地时间当月第一天零点,并转换为UTC时间字符串,那么原代码就是正确的,但这样得到的字符串并不是当月的第一天零点(在UTC时间下),而是上个月的最后一天(如果时区为正)或者当月的第一天(如果时区为负)的某个时间。 所以,请根据实际需求选择。 鉴于问题没有明确,我将按照最常见的需求:获取本地时间当月第一天零点,并格式化为本地时间字符串(ISO格式,不带时区)来改写。 改写后的代码: ```javascript const firstDay = new Date(); firstDay.setDate(1); firstDay.setHours(0, 0, 0, 0); // 格式化为 YYYY-MM-DDTHH:mm:ss 格式的字符串(本地时间) const pad = (num) => String(num).padStart(2, '0'); const year = firstDay.getFullYear(); const month = pad(firstDay.getMonth() + 1); const day = pad(firstDay.getDate()); const hours = pad(firstDay.getHours()); const minutes = pad(firstDay.getMinutes()); const seconds = pad(firstDay.getSeconds()); const firstDayISO = `${year}-${month}-${day}T${hours}:${minutes}:${seconds}`; // 由于我们设置了小时、分钟、秒为0,所以也可以直接写死00:00:00 // 但为了通用,我们按照实际值格式化 ``` 由于我们设置了小时、分钟、秒为0,所以可以简化为: ```javascript const firstDay = new Date(); firstDay.setDate(1); firstDay.setHours(0, 0, 0, 0); const pad = (num) => String(num).padStart(2, '0'); const year = firstDay.getFullYear(); const month = pad(firstDay.getMonth() + 1); const day = pad(firstDay.getDate()); const firstDayISO = `${year}-${month}-${day}T00:00:00`; ``` 但是,这样写死也可以,因为我们明确设置了时间为00:00:00。 所以,最终改写代码(本地时间,不带时区): ```javascript const firstDay = new Date(); firstDay.setDate(1); firstDay.setHours(0, 0, 0, 0); const year = firstDay.getFullYear(); const month = String(firstDay.getMonth() + 1).padStart(2, '0'); const day = String(firstDay.getDate()).padStart(2, '0'); const firstDayISO = `${year}-${month}-${day}T00:00:00`; ``` 如果需求是UTC时间,那么改写为: ```javascript const now = new Date(); const year = now.getUTCFullYear(); const month = now.getUTCMonth(); // 月份0-11 const firstDayUTC = new Date(Date.UTC(year, month, 1, 0, 0, 0)); const firstDayISO = firstDayUTC.toISOString().slice(0, 19); ``` 或者更简洁的: ```javascript const firstDay = new Date(); firstDay.setUTCDate(1); firstDay.setUTCHours(0,0,0,0); const firstDayISO = firstDay.toISOString().slice(0,19); ``` 但是,请注意:setUTCDate(1)会设置UTC日期为1,然后setUTCHours(0,0,0,0)设置UTC小时为0,这样得到的是UTC时间当月第一天零点。然后toISOString()得到的是UTC时间字符串,例如"2024-06-01T00:00:00.000Z",我们slice(0,19)得到"2024-06-01T00:00:00"。 所以,请根据实际需求选择。 由于问题描述为“改写”,我假设原代码的意图是获取本地时间当月第一天零点,但转换为ISO字符串(UTC时间)是不正确的,所以可能需求是本地时间,因此我选择第一种(本地时间,不带时区)作为答案。 但是,原代码使用了toISOString,这通常是用于获取UTC时间,所以也可能需求是UTC时间,那么应该用第二种(UTC时间)并去掉后面的.000Z,只保留到秒。 因此,我提供两种方案,并解释。 方案一(本地时间,不带时区): ```javascript const firstDay = new Date(); firstDay.setDate(1); firstDay.setHours(0, 0, 0, 0); const year = firstDay.getFullYear(); const month = String(firstDay.getMonth() + 1).padStart(2, '0'); const day = String(firstDay.getDate()).padStart(2, '0'); const firstDayISO = `${year}-${month}-${day}T00:00:00`; ``` 方案二(UTC时间,不带时区标识,但实际是UTC时间): ```javascript const firstDay = new Date(); // 设置为UTC时间当月的第一天零点 firstDay.setUTCDate(1); firstDay.setUTCHours(0,0,0,0); const firstDayISO = firstDay.toISOString().slice(0, 19); ``` 方案二的结果字符串是UTC时间,例如在UTC+8时区,如果今天是2024年6月15日,那么方案一得到的是"2024-06-01T00:00:00",而方案二得到的是"2024-06-01T00:00:00"(注意:这个时间实际上是UTC时间,和本地时间2024-06-01T08:00:00+08:00是同一时刻)。 所以,请根据需求选择。 如果需求不明确,我建议使用方案一,因为原代码中使用了new Date()的本地时间设置,所以可能需求是本地时间。 最终,我给出方案一的代码,并解释。 代码:</think>以下是获取本月第一天日期和时间的正确实现,包括本地时间和UTC时间两种方案: ### 方案一:获取本地时间的当月第一天(推荐) ```javascript // 获取当前日期(本地时间) const now = new Date(); // 创建本月第一天对象(本地时间) const firstDay = new Date(now.getFullYear(), now.getMonth(), 1, 0, 0, 0, 0); // 格式化为ISO字符串(不含时区信息) const year = firstDay.getFullYear(); const month = String(firstDay.getMonth() + 1).padStart(2, '0'); const day = String(firstDay.getDate()).padStart(2, '0'); const firstDayISO = `${year}-${month}-${day}T00:00:00`; console.log(firstDayISO); // 示例输出: "2023-06-01T00:00:00" ``` ### 方案二:获取UTC时间的当月第一天 ```javascript // 获取当前日期(UTC时间) const now = new Date(); // 创建本月第一天对象(UTC时间) const firstDayUTC = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), 1, 0, 0, 0, 0)); // 获取ISO字符串并截取到秒 const firstDayISO = firstDayUTC.toISOString().slice(0, 19); console.log(firstDayISO); // 示例输出: "2023-06-01T00:00:00" ``` ### 关键区别说明: 1. **本地时间方案**: - 使用`new Date(year, month, day)`构造函数 - 直接获取用户所在时区的当月第一天 - 手动拼接字符串确保格式正确 2. **UTC时间方案**: - 使用`Date.UTC()`和`new Date()`组合 - 通过`toISOString()`获取标准UTC时间 - `slice(0, 19)`移除毫秒和时区标识 ### 原代码问题分析: ```javascript // 原代码问题: const firstDay = new Date(); firstDay.setDate(1); // ✅ 设置为本月第一天 firstDay.setHours(0, 0, 0, 0); // ✅ 时间归零 // 问题在这里 ↓ const firstDayISO = firstDay.toISOString().slice(0, 19); ``` - `toISOString()`总是返回UTC时间,会使用时区偏移转换 - 例如北京时间(UTC+8)的"2023-06-01T00:00:00"会变成"2023-05-31T16:00:00" - 使用`.slice(0, 19)`只是移除毫秒,无法解决时区转换问题 ### 何时使用哪种方案: - 需要用户本地时间(如日历显示) → **方案一** - 需要统一存储UTC时间(如数据库记录) → **方案二**
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值