微信小程序----日期时间选择器(自定义时间精确到分秒)

news/2024/9/22 6:29:16/

目录

页面效果

代码实现 

注意事项


页面效果

代码实现 

js 

Component({/*** 组件的属性列表*/properties: {pickerShow: {type: Boolean,},config: Object,},/*** 组件的初始数据*/data: {pickerReady: false,// pickerShow:true// limitStartTime: new Date().getTime()-1000*60*60*24*30,// limitEndTime: new Date().getTime(),// yearStart:2000,// yearEnd:2100},detached: function () {this.setData({pickerReady: false,});},attached: function () {this.readConfig();this.initPick(this.data.config || null);this.setData({startValue: this.data.startValue,endValue: this.data.endValue,pickerReady: true,});},ready: function () {},/*** 组件的方法列表*/methods: {/*** 读取并处理配置中的时间限制信息* 此函数用于初始化或更新时间选择器的限制范围,以及配置中的其他时间相关参数*/readConfig() {// 获取当前时间的时间戳,最大选的范围let limitEndTime = new Date().getTime();// 计算30天前的时间戳,最小可选择的范围let limitStartTime = new Date().getTime() - 1000 * 60 * 60 * 24 * 30;// 检查是否存在配置信息if (this.data.config) {let conf = this.data.config;// 如果配置中指定了日期限制,当为数字n时,范围是当前时间的最近n天if (typeof conf.dateLimit == "number") {limitStartTime =new Date().getTime() - 1000 * 60 * 60 * 24 * conf.dateLimit;}// 如果配置中指定了最小可选,则将其转换为时间戳if (conf.limitStartTime) {limitStartTime = new Date(conf.limitStartTime.replace(/-/g, "/")).getTime();}// 如果配置中指定了最大可选,则将其转换为时间戳if (conf.limitEndTime) {limitEndTime = new Date(conf.limitEndTime.replace(/-/g, "/")).getTime();}// 设置数据,包括年份范围、结束日期标志、日期限制和时间列的显示状态this.setData({yearStart: conf.yearStart || 2000, // 默认开始年份为2000yearEnd: conf.yearEnd || 2100, // 默认结束年份为2100endDate: conf.endDate || false, // 默认不启用结束日期dateLimit: conf.dateLimit || false, // 默认不设置日期限制hourColumn:conf.column == "hour" ||conf.column == "minute" ||conf.column == "second", // 根据配置决定是否显示小时列minColumn: conf.column == "minute" || conf.column == "second", // 根据配置决定是否显示分钟列secColumn: conf.column == "second", // 根据配置决定是否显示秒列});}// 将时间限制的时间戳格式化数组方便循环let limitStartTimeArr = formatTime(limitStartTime);let limitEndTimeArr = formatTime(limitEndTime);// 更新数据,包括时间限制的时间戳和格式化后的时间数组this.setData({limitStartTime, // 开始时间限制limitStartTimeArr, // 开始时间限制数组limitEndTime, // 结束时间限制limitEndTimeArr, //结束时间限制数组});},//滚动开始handlePickStart: function (e) {this.setData({isPicking: true,});},//滚动结束handlePickEnd: function (e) {this.setData({isPicking: false,});},onConfirm: function () {//滚动未结束时不能确认if (this.data.isPicking) {return;}let startTime = new Date(this.data.startPickTime.replace(/-/g, "/"));let endTime = new Date(this.data.endPickTime.replace(/-/g, "/"));if (startTime <= endTime || !this.data.endDate) {this.setData({startTime,endTime,});let startArr = formatTime(startTime).arr;let endArr = formatTime(endTime).arr;let format0 = function (num) {return num < 10 ? "0" + num : num;};let startTimeBack =startArr[0] +"-" +format0(startArr[1]) +"-" +format0(startArr[2]) +" " +(this.data.hourColumn ? format0(startArr[3]) : "00") +":" +(this.data.minColumn ? format0(startArr[4]) : "00") +":" +(this.data.secColumn ? format0(startArr[5]) : "00");let endTimeBack =endArr[0] +"-" +format0(endArr[1]) +"-" +format0(endArr[2]) +" " +(this.data.hourColumn ? format0(endArr[3]) : "00") +":" +(this.data.minColumn ? format0(endArr[4]) : "00") +":" +(this.data.secColumn ? format0(endArr[5]) : "00");let time = {startTime: startTimeBack,endTime: endTimeBack,};//触发自定义事件this.triggerEvent("setPickerTime", time);this.triggerEvent("hidePicker", {});} else {wx.showToast({icon: "none",title: "时间不合理",});}},hideModal: function () {this.triggerEvent("hidePicker", {});},changeStartDateTime: function (e) {let val = e.detail.value;this.compareTime(val, "start");},changeEndDateTime: function (e) {let val = e.detail.value;this.compareTime(val, "end");},/*** 比较时间是否在指定范围内* @param {Array} val_ 时间数组,包含年、月、日、时、分、秒的数值* @param {string} type 类型指示符,"start"表示开始时间,"end"表示结束时间* @description 该函数用于比较给定的时间是否在系统或用户设定的时间范围内* 根据比较结果,设置开始时间或结束时间*/compareTime(val_, type) {// 将时间数组中的每个元素转换为字符串const val = val_.map((it) => it.toString());// 获取小时、分钟、秒的字符串表示,如果不存在则默认为"00"let h = val[3] ? this.data.HourList[val[3]] : "00";let m = val[4] ? this.data.MinuteList[val[4]] : "00";let s = val[5] ? this.data.SecondList[val[5]] : "00";// 构造完整的时间字符串let time =this.data.YearList[val[0]] +"-" +this.data.MonthList[val[1]] +"-" +this.data.DayList[val[2]] +" " +h +":" +m +":" +s;// 获取系统或用户设定的开始和结束时间let start = this.data.limitStartTime;let end = this.data.limitEndTime;// 将输入的时间字符串转换为时间戳let timeNum = new Date(time.replace(/-/g, "/")).getTime();// 用于存储限制日期的各部分let year, month, day, hour, min, sec, limitDate;let tempArr = [];// 根据不同的条件计算限制日期if (!this.data.dateLimit) {// 如果没有设定日期限制,则直接使用输入的日期limitDate = [this.data.YearList[val[0]],this.data.MonthList[val[1]],this.data.DayList[val[2]],this.data.HourList[val[3]],this.data.MinuteList[val[4]],this.data.SecondList[val[5]],];} else if (type == "start" &&timeNum > new Date(this.data.endPickTime.replace(/-/g, "/")) &&this.data.config.endDate) {// 如果是开始时间且输入时间晚于结束选择时间,则使用结束选择时间limitDate = formatTime(this.data.endPickTime).arr;} else if (type == "end" &&timeNum < new Date(this.data.startPickTime.replace(/-/g, "/"))) {// 如果是结束时间且输入时间早于开始选择时间,则使用开始选择时间limitDate = formatTime(this.data.startPickTime).arr;} else if (timeNum < start) {// 如果输入时间早于系统或用户设定的开始时间,则使用设定的开始时间limitDate = this.data.limitStartTimeArr.arr;} else if (timeNum > end) {// 如果输入时间晚于系统或用户设定的结束时间,则使用设定的结束时间limitDate = this.data.limitEndTimeArr.arr;} else {// 如果输入时间在系统或用户设定的范围内,则直接使用输入的日期limitDate = [this.data.YearList[val[0]],this.data.MonthList[val[1]],this.data.DayList[val[2]],this.data.HourList[val[3]],this.data.MinuteList[val[4]],this.data.SecondList[val[5]],];}// 将限制日期的各部分分配给相应的变量year = limitDate[0];month = limitDate[1];day = limitDate[2];hour = limitDate[3];min = limitDate[4];sec = limitDate[5];// 根据类型指示符设置开始时间或结束时间if (type == "start") {this.setStartDate(year, month, day, hour, min, sec);} else if (type == "end") {this.setEndDate(year, month, day, hour, min, sec);}},/*** 获取指定月份的天数** 此函数根据给定的年份和月份,返回该月份的天数。特别地,对于二月份,* 该函数考虑了闰年的情况,确保返回准确的天数。** @param {number} year - 指定的年份,用于计算二月份的天数是否为29天(闰年)* @param {number} month - 指定的月份,用于确定该月的天数* @returns {number} 返回指定月份的天数*/getDays: function (year, month) {// 定义一个数组,包含除二月外各月份的天数let daysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];// 如果是二月份if (month === 2) {// 判断是否为闰年,如果是闰年则返回29天,否则返回28天return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0? 29: 28;} else {// 非二月份则直接返回对应月份的天数return daysInMonth[month - 1];}},/*** 初始化选择器* @param {Object} initData - 初始化数据对象* 初始化startTime和endTime,如果传入的initData对象中包含initStartTime和initEndTime属性,* 则使用这些属性值作为时间选择器的初始值,否则使用当前时间作为默认值*/initPick: function (initData) {// 初始化开始时间选择器默认时间(默认为当前时间)const date = initData.initStartTime? new Date(initData.initStartTime.replace(/-/g, "/")): new Date();// 初始化结束时间选择器默认时间 (默认为当前时间)const endDate = initData.initEndTime? new Date(initData.initEndTime.replace(/-/g, "/")): new Date();const startDate = date;// 从date中提取年月日时分秒信息const startYear = date.getFullYear();const startMonth = date.getMonth() + 1;const startDay = date.getDate();const startHour = date.getHours();const startMinute = date.getMinutes();const startSecond = date.getSeconds();// 从endDate中提取年月日时分秒信息const endYear = endDate.getFullYear();const endMonth = endDate.getMonth() + 1;const endDay = endDate.getDate();const endHour = endDate.getHours();const endMinute = endDate.getMinutes();const endSecond = endDate.getSeconds();// 定义各个时间单位的列表let YearList = [];let MonthList = [];let DayList = [];let HourList = [];let MinuteList = [];let SecondList = [];// 设置年份列表,范围从开始年份到结束年份for (let i = this.data.yearStart; i <= this.data.yearEnd; i++) {YearList.push(i);}// 设置月份列表,从1月到12月for (let i = 1; i <= 12; i++) {MonthList.push(i);}// 设置日期列表,从1日到31日for (let i = 1; i <= 31; i++) {DayList.push(i);}// 设置小时列表,从00到23for (let i = 0; i <= 23; i++) {if (0 <= i && i < 10) {i = "0" + i;}HourList.push(i);}// 设置分钟和秒列表,从00到59for (let i = 0; i <= 59; i++) {if (0 <= i && i < 10) {i = "0" + i;}MinuteList.push(i);SecondList.push(i);}// 将构建好的时间列表数据绑定到组件的数据对象中this.setData({YearList,MonthList,DayList,HourList,MinuteList,SecondList,});// 设置开始日期和结束日期this.setStartDate(startYear,startMonth,startDay,startHour,startMinute,startSecond);this.setEndDate(endYear, endMonth, endDay, endHour, endMinute, endSecond);// 注释掉的setTimeout可能用于解决某些异步问题或界面更新,但此处未实际使用// setTimeout(() => {//   this.setStartDate(nowYear, nowMonth, nowDay, nowHour, nowMinute)//   this.setEndDate(nowYear, nowMonth, nowDay, nowHour, nowMinute)// }, 0);},/*** 设置选择器日期数组* 根据给定的年、月、日、时、分、秒来设置日期选择器的数组* @param {string} type - 类型指示符,可以是"start"或"end"* @param {number} year - 指定的年份* @param {number} month - 指定的月份* @param {number} day - 指定的日期* @param {number} hour - 指定的小时* @param {number} minute - 指定的分钟* @param {number} second - 指定的秒数* @returns {Object} 返回一个对象,包含各个日期组件在选择器中的索引*/setPickerDateArr(type, year, month, day, hour, minute, second) {// 初始化各个日期组件的索引变量let yearIdx = 0;let monthIdx = 0;let dayIdx = 0;let hourIdx = 0;let minuteIdx = 0;let secondIdx = 0;// 查找年份在年份列表中的索引this.data.YearList.map((v, idx) => {if (parseInt(v) === year) {yearIdx = idx;}});// 查找月份在月份列表中的索引this.data.MonthList.map((v, idx) => {if (parseInt(v) === month) {monthIdx = idx;}});// 重新设置日期列表 (根据月份计算天数)let DayList = [];for (let i = 1; i <= this.getDays(year, month); i++) {DayList.push(i);}// 查找日期在日期列表中的索引DayList.map((v, idx) => {if (parseInt(v) === day) {dayIdx = idx;}});// 根据类型更新开始或结束的日期列表if (type == "start") {this.setData({ startDayList: DayList });} else if (type == "end") {this.setData({ endDayList: DayList });}// 查找小时在小时列表中的索引this.data.HourList.map((v, idx) => {if (parseInt(v) === parseInt(hour)) {hourIdx = idx;}});// 查找分钟在分钟列表中的索引this.data.MinuteList.map((v, idx) => {if (parseInt(v) === parseInt(minute)) {minuteIdx = idx;}});// 查找秒数在秒数列表中的索引this.data.SecondList.map((v, idx) => {if (parseInt(v) === parseInt(second)) {secondIdx = idx;}});// 返回包含所有日期组件索引的对象return {yearIdx,monthIdx,dayIdx,hourIdx,minuteIdx,secondIdx,};},/*** 设置开始日期函数** 此函数的作用是根据传入的年、月、日、时、分、秒参数,生成一个可用于选择器的日期数组,* 并更新组件的数据,以在界面上显示选择的开始日期。它首先调用了一个辅助函数来处理日期数组的生成,* 然后使用setData方法更新了多个与日期选择器相关的数据属性,包括年、月、时、分、秒的列表,* 以及选择器的默认值和显示的日期格式字符串。** @param {number} year - 传入的年份* @param {number} month - 传入的月份,注意JavaScript中月份是从0开始的,所以这里传入的值需要减1* @param {number} day - 传入的日* @param {number} hour - 传入的小时* @param {number} minute - 传入的分钟* @param {number} second - 传入的秒*/setStartDate: function (year, month, day, hour, minute, second) {// 调用辅助函数处理日期数组let pickerDateArr = this.setPickerDateArr("start",year,month,day,hour,minute,second);// 更新界面数据,设置日期选择器的列表和默认选中值this.setData({startYearList: this.data.YearList, // 年份列表startMonthList: this.data.MonthList, // 月份列表// startDayList: this.data.DayList,startHourList: this.data.HourList, // 小时列表startMinuteList: this.data.MinuteList, // 分钟列表startSecondList: this.data.SecondList, // 秒钟列表startValue: [// 设置日期选择器的默认选中值pickerDateArr.yearIdx,pickerDateArr.monthIdx,pickerDateArr.dayIdx,pickerDateArr.hourIdx,pickerDateArr.minuteIdx,pickerDateArr.secondIdx,],// 构造日期时间字符串用于界面显示startPickTime:this.data.YearList[pickerDateArr.yearIdx] +"-" +this.data.MonthList[pickerDateArr.monthIdx] +"-" +this.data.DayList[pickerDateArr.dayIdx] +" " +this.data.HourList[pickerDateArr.hourIdx] +":" +this.data.MinuteList[pickerDateArr.minuteIdx] +":" +this.data.SecondList[pickerDateArr.secondIdx],});},setEndDate: function (year, month, day, hour, minute, second) {let pickerDateArr = this.setPickerDateArr("end",year,month,day,hour,minute,second);this.setData({endYearList: this.data.YearList,endMonthList: this.data.MonthList,// endDayList: this.data.DayList,endHourList: this.data.HourList,endMinuteList: this.data.MinuteList,endSecondList: this.data.SecondList,endValue: [pickerDateArr.yearIdx,pickerDateArr.monthIdx,pickerDateArr.dayIdx,pickerDateArr.hourIdx,pickerDateArr.minuteIdx,pickerDateArr.secondIdx,],endPickTime:this.data.YearList[pickerDateArr.yearIdx] +"-" +this.data.MonthList[pickerDateArr.monthIdx] +"-" +this.data.DayList[pickerDateArr.dayIdx] +" " +this.data.HourList[pickerDateArr.hourIdx] +":" +this.data.MinuteList[pickerDateArr.minuteIdx] +":" +this.data.SecondList[pickerDateArr.secondIdx],});},},
});function formatTime(date) {if (typeof date == "string" || "number") {try {date = date.replace(/-/g, "/"); //兼容ios} catch (error) {}date = new Date(date);}const year = date.getFullYear();const month = date.getMonth() + 1;const day = date.getDate();const hour = date.getHours();const minute = date.getMinutes();const second = date.getSeconds();return {str:[year, month, day].map(formatNumber).join("-") +" " +[hour, minute, second].map(formatNumber).join(":"),arr: [year, month, day, hour, minute, second],};
}
function formatNumber(n) {n = n.toString();return n[1] ? n : "0" + n;
}

wxml

<!-- components/timePicker/timePicker.wxml -->
<!-- 自定义时间筛选器 -->
<view wx:if="{{pickerShow&&pickerReady}}"><view class="picker-container {{pickerShow?'show_picker':'hide_picker'}}"><view class="btn-box"><view class="pick_btn" bind:tap="hideModal">取消</view><view class='pick_btn' style="color: #19f" bind:tap="onConfirm">确定</view></view><view><picker-view class='sensorTypePicker' indicator-style='height: 35px;' bindchange="changeStartDateTime" value="{{startValue}}" style="height: {{endDate?'120px':'250px'}};" bindpickstart="handlePickStart" bindpickend="handlePickEnd" data-type="start"><picker-view-column style="min-width: 70px;flex-shrink: 0"><view class='picker-item' wx:for="{{startYearList}}" wx:key='*this'>{{item}}年</view></picker-view-column><picker-view-column><view class='picker-item' wx:for="{{startMonthList}}" wx:key='*this'>{{item}}月</view></picker-view-column><picker-view-column><view class='picker-item' wx:for="{{startDayList}}" wx:key='*this'>{{item}}日</view></picker-view-column><picker-view-column hidden="{{!hourColumn}}"><view class='picker-item' wx:for="{{startHourList}}" wx:key='*this'>{{item}}时</view></picker-view-column><picker-view-column hidden="{{!minColumn}}"><view class='picker-item' wx:for="{{startMinuteList}}" wx:key='*this'>{{item}}分</view></picker-view-column><picker-view-column hidden="{{!secColumn}}"><view class='picker-item' wx:for="{{startSecondList}}" wx:key='*this'>{{item}}秒</view></picker-view-column></picker-view></view><view wx:if="{{endDate}}"><view class='to' style='margin-top: 4px;margin-bottom: 4px;'>至</view><picker-view class='sensorTypePicker' indicator-style='height: 35px;' bindchange="changeEndDateTime" bindpickstart="handlePickStart" bindpickend="handlePickEnd" value="{{endValue}}"><picker-view-column style="min-width: 70px;flex-shrink: 0"><view class='picker-item' wx:for="{{endYearList}}" wx:key='*this' style="min-width: 70px;">{{item}}年</view></picker-view-column><picker-view-column><view class='picker-item' wx:for="{{endMonthList}}" wx:key='*this'>{{item}}月</view></picker-view-column><picker-view-column><view class='picker-item' wx:for="{{endDayList}}" wx:key='*this'>{{item}}日</view></picker-view-column><picker-view-column hidden="{{!hourColumn}}"><view class='picker-item' wx:for="{{endHourList}}" wx:key='*this'>{{item}}时</view></picker-view-column><picker-view-column hidden="{{!minColumn}}"><view class='picker-item' wx:for="{{endMinuteList}}" wx:key='*this'>{{item}}分</view></picker-view-column><picker-view-column hidden="{{!secColumn}}"><view class='picker-item' wx:for="{{startSecondList}}" wx:key='*this'>{{item}}秒</view></picker-view-column></picker-view></view><!-- <view class='sure' bindtap="onConfirm">确定</view> --></view><!-- 遮罩 --><view class="sensorType-screen" bind:tap="hideModal" />
</view>

wxss

/* components/timePicker/timePicker.wxss */.picker-item{line-height: 50px;  display: flex;justify-content: center;align-items: center;
}/* 自定义时间 */
.picker-container {display: flex;flex-direction: column;/* justify-content: center; */align-items: center;width: 100%;overflow: hidden;position: fixed;bottom: 0rpx;left: 0;height: 0;transition: height 0.5s;z-index: 2000;background: white;border-top: 1px solid #EFEFF4;
}
.sensorType-screen{width: 100vw;/* height:400rpx; */position: fixed;top: 0;right: 0;bottom: 0;left: 0;background:#000;opacity: 0.7;overflow: hidden;z-index: 1999;color: #fff;
}
.sensorTypePicker{width: 690rpx;height: 120px;/* padding: 45px 0; */
}
.picker-item{line-height: 50px;  display: flex;justify-content: center;align-items: center;font-size: 16px;/* overflow: hidden; */
}
.box{padding: 0 10px; 
}/* 至 */
.to{width:100%;display: flex;justify-content: center;align-items: center;color:rgb(138,138,138);/* font-size:30rpx; */
}/* 确定 */
.sure{width:100%;height:45px;border-top: 1px solid #EFEFF4;display: flex;justify-content: center;align-items: center;color: rgb(36,123,255);font-size:16px;
}.btn-box{width: 100%;display: flex;justify-content: space-between;align-items: center;border-bottom: 1px solid #eee;
}
.pick_btn{padding: 7px 15px;color: #ccc;/* background-color: #159; */
}.show_picker{height: 320px;
}
.hide_picker{height: 0;
}

json

{"component": true,"usingComponents": {}}

注意事项

小程序>微信小程序自定义时间选择器,支持多种自定义功能。

在开发工具中浏览: https://developers.weixin.qq.com/s/N9EdArmQ7a6j
复制链接在浏览器中打开

配置项

pickerConfig: {endDate: true,                          // 是否需要结束时间,为true时显示开始时间和结束时间两个pickercolumn: "second",                       //可选的最小时间范围day、hour、minute、secenddateLimit: true,                        //是否现在时间可选范围,false时可选任意时间;当为数字n时,范围是当前时间的最近n天initStartTime:'2019-01-01 12:32:44',    //picker初始时间,默认当前时间initEndTime: "2019-12-01 12:32:44",     //picker初始结束时间,默认当前时间limitStartTime: "2015-05-06 12:32:44",  //最小可选时间limitEndTime: "2055-05-06 12:32:44"     //最大可选时间 
}
其他限制条件可修改组件中的compareTime函数定义

endDate: true

endDate: false

pickerReady 为了保证加载顺序初始化正常 Skyline 模式下初始化会触发change 导出初始化异常

未解决 用户快速滚动会造成页面卡死 有思路的大佬可以留言解决方案


http://www.ppmy.cn/news/1528712.html

相关文章

Go进阶概览 -【7.1 反射机制与动态编程】

7.1 反射机制与动态编程 反射是Go语言的一项强大特性&#xff0c;使得程序可以在运行时检查和修改自身的结构和行为。 反射机制的使用在一些动态编程场景中非常重要&#xff0c;但同时也带来了一定的性能开销。 本节我们将深入解析Go的反射机制&#xff0c;探讨其在动态编程…

大数据-141 - ClickHouse 集群 副本和分片 Zk 的配置 Replicated MergeTree原理详解

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…

react:组件通信

组件通信 父组件向子组件通信 function App() {return (<div><div>这是父组件</div><Child name"这是子组件" /></div>); }// 子组件 function Child(props) {return <div>{props.name}</div>; }props说明 props可以传…

[数据集][目标检测]葡萄成熟度检测数据集VOC+YOLO格式1123张3类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;1123 标注数量(xml文件个数)&#xff1a;1123 标注数量(txt文件个数)&#xff1a;1123 标注…

Java面试篇-AOP专题(什么是AOP、AOP的几个核心概念、AOP的常用场景、使用AOP记录操作日志、Spring中的事务是如何实现的)

文章目录 1. 什么是AOP2. AOP的几个核心概念3. AOP的常用场景4. 使用AOP记录操作日志4.1 准备工作4.1.1 引入Maven依赖4.1.2 UserController.java4.1.3 User.java4.1.4 UserService.java 4.2 具体实现&#xff08;以根据id查询用户信息为例&#xff09;4.2.1 定义切面类&#x…

《C++高效字符串拼接之道:解锁性能与优雅的完美结合》

在 C编程中&#xff0c;字符串拼接是一项常见的操作。然而&#xff0c;如果不采用合适的方法&#xff0c;字符串拼接可能会导致性能低下和代码繁琐。本文将深入探讨如何在 C中进行高效的字符串拼接&#xff0c;带你解锁性能与优雅的完美结合。 一、C中字符串拼接的常见方法及问…

【实战篇】MySQL是怎么保证主备一致的?

MySQL 主备的基本原理 如图 1 所示就是基本的主备切换流程。 在状态 1 中&#xff0c;客户端的读写都直接访问节点 A&#xff0c;而节点 B 是 A 的备库&#xff0c;只是将 A 的更新都同步过来&#xff0c;到本地执行。这样可以保持节点 B 和 A 的数据是相同的。 当需要切换的…

工控一体机在高精度玻璃检测机中的应用

工控一体机在高精度玻璃检测机中的应用主要体现在以下几个方面&#xff1a; 一、数据采集与处理 工控一体机作为工业控制计算机&#xff0c;能够高效采集来自高精度玻璃检测机中各种传感器和执行器的数据。这些数据包括但不限于玻璃表面的图像信息、厚度、温度、光学特性等。…