js日期格式化(字符串转日期<-->日期转字符串)

本文介绍了一种使用JavaScript将字符串格式的日期转换为日期对象的方法。通过正则表达式匹配日期字符串中的年、月、日等元素,并将其转换为JavaScript Date对象。此外,还提供了一个验证日期字符串格式是否正确的函数。
js字符串转日期型



/** year : /yyyy/ */
var _y4 = "([0-9]{4})";
/** year : /yy/ */
var _y2 = "([0-9]{2})";
/** index year */
var _yi = -1;
/** month : /MM/ */
var _M2 = "(0[1-9]|1[0-2])";
/** month : /M/ */
var _M1 = "([1-9]|1[0-2])";
/** index month */
var _Mi = -1;
/** day : /dd/ */
var _d2 = "(0[1-9]|[1-2][0-9]|30|31)";
/** day : /d/ */
var _d1 = "([1-9]|[1-2][0-9]|30|31)";
/** index day */
var _di = -1;
/** hour : /HH/ */
var _H2 = "([0-1][0-9]|20|21|22|23)";
/** hour : /H/ */
var _H1 = "([0-9]|1[0-9]|20|21|22|23)";
/** index hour */
var _Hi = -1;
/** minute : /mm/ */
var _m2 = "([0-5][0-9])";
/** minute : /m/ */
var _m1 = "([0-9]|[1-5][0-9])";
/** index minute */
var _mi = -1;
/** second : /ss/ */
var _s2 = "([0-5][0-9])";
/** second : /s/ */
var _s1 = "([0-9]|[1-5][0-9])";
/** index month */
var _si = -1;
var regexp;
function getDate(dateString, formatString) {
if (validateDate(dateString, formatString)) {
var now = new Date();
var vals = regexp.exec(dateString);
var index = validateIndex(formatString);
var year = index[0] >= 0 ? vals[index[0] + 1] : now.getFullYear();
var month = index[1] >= 0 ? (vals[index[1] + 1] - 1) : now.getMonth();
var day = index[2] >= 0 ? vals[index[2] + 1] : now.getDate();
var hour = index[3] >= 0 ? vals[index[3] + 1] : "";
var minute = index[4] >= 0 ? vals[index[4] + 1] : "";
var second = index[5] >= 0 ? vals[index[5] + 1] : "";
var validate;
if (hour == "") {
validate = new Date(year, month, day);
} else {
validate = new Date(year, month, day, hour, minute, second);
}
if (validate.getDate() == day) {
return validate;
}
}
alert("wrong date");
}
function validateDate(dateString, formatString) {
var dateString = trim(dateString);
if (dateString == "") {
return;
}
var reg = formatString;
reg = reg.replace(/yyyy/, _y4);
reg = reg.replace(/yy/, _y2);
reg = reg.replace(/MM/, _M2);
reg = reg.replace(/M/, _M1);
reg = reg.replace(/dd/, _d2);
reg = reg.replace(/d/, _d1);
reg = reg.replace(/HH/, _H2);
reg = reg.replace(/H/, _H1);
reg = reg.replace(/mm/, _m2);
reg = reg.replace(/m/, _m1);
reg = reg.replace(/ss/, _s2);
reg = reg.replace(/s/, _s1);
reg = new RegExp("^" + reg + "$");
regexp = reg;
return reg.test(dateString);
}
function validateIndex(formatString) {
var ia = new Array();
var i = 0;
_yi = formatString.search(/yyyy/);
if (_yi < 0) {
_yi = formatString.search(/yy/);
}
if (_yi >= 0) {
ia[i] = _yi;
i++;
}
_Mi = formatString.search(/MM/);
if (_Mi < 0) {
_Mi = formatString.search(/M/);
}
if (_Mi >= 0) {
ia[i] = _Mi;
i++;
}
_di = formatString.search(/dd/);
if (_di < 0) {
_di = formatString.search(/d/);
}
if (_di >= 0) {
ia[i] = _di;
i++;
}
_Hi = formatString.search(/HH/);
if (_Hi < 0) {
_Hi = formatString.search(/H/);
}
if (_Hi >= 0) {
ia[i] = _Hi;
i++;
}
_mi = formatString.search(/mm/);
if (_mi < 0) {
_mi = formatString.search(/m/);
}
if (_mi >= 0) {
ia[i] = _mi;
i++;
}
_si = formatString.search(/ss/);
if (_si < 0) {
_si = formatString.search(/s/);
}
if (_si >= 0) {
ia[i] = _si;
i++;
}
var ia2 = new Array(_yi, _Mi, _di, _Hi, _mi, _si);
for (i = 0; i < ia.length - 1; i++) {
for (j = 0; j < ia.length - 1 - i; j++) {
if (ia[j] > ia[j + 1]) {
temp = ia[j];
ia[j] = ia[j + 1];
ia[j + 1] = temp;
}
}
}
for (i = 0; i < ia.length; i++) {
for (j = 0; j < ia2.length; j++) {
if (ia[i] == ia2[j]) {
ia2[j] = i;
}
}
}
return ia2;
}
function trim(str) {
return str.replace(/(^\s*)|(\s*$)/g, "");
}


日期型格式化

Date.prototype.format = function(format)
{
var o = {

"M+" : this.getMonth()+1, //month
"d+" : this.getDate(),//day
"h+" : this.getHours(), //hour
"m+" : this.getMinutes(), //minute
"s+" : this.getSeconds(), //second
"q+" : Math.floor((this.getMonth()+3)/3), //quarter
"S" : this.getMilliseconds() //millisecond
}

if(/(y+)/.test(format))
format = format.replace(RegExp.$1,(this.getFullYear()+"").substr(4 - RegExp.$1.length));
for(var k in o)
if(new RegExp("("+ k +")").test(format))
format = format.replace(RegExp.$1,RegExp.$1.length==1 ? o[k] :("00"+ o[k]).substr((""+ o[k]).length));
return format;
}
<div v-else-if="field.field.fieldViewType == fieldViewTypeEnum.DateTime && field.field.displayType !== displayTypeEnum.Hidden"> <label> <span class="text-red-8" v-if="field.mandatory">*</span> {{ field.label }} </label> <q-input outlined dense :value="formatDateTimeWithTranslation(scriptContext.formContext.currentRecord[field.field.customId])" :disable="fieldValueDisable(field.field, scriptContext.formContext.currentRecord)" :rules="[(val) => validateField(val, field.field)]" @update:model-value="(val) => fieldChanged(val, field.field)"> <!-- 日期选择器(保持默认绑定,不修改mask) --> <template v-slot:prepend> <q-icon name="event" class="cursor-pointer"> <q-popup-proxy cover transition-show="scale" transition-hide="scale"> <q-date v-model="scriptContext.formContext.currentRecord[field.field.customId]" mask="YYYY/MM/DD" > <div class="row items-center justify-end"> <q-btn v-close-popup :label="t('common.close')" color="primary" flat /> </div> </q-date> </q-popup-proxy> </q-icon> </template> <!-- 时间选择器(保持12小时制) --> <template v-slot:append> <q-icon name="access_time" class="cursor-pointer"> <q-popup-proxy cover transition-show="scale" transition-hide="scale"> <q-time v-model="scriptContext.formContext.currentRecord[field.field.customId]" :format24h="false" > <div class="row items-center justify-end"> <q-btn v-close-popup :label="t('common.close')" color="primary" flat /> </div> </q-time> </q-popup-proxy> </q-icon> </template> </q-input> {{"时间"+formatDateTimeWithTranslation(scriptContext.formContext.currentRecord[field.field.customId])}} </div>所以这个时间换的代码如何修改呢,让数据直接格式
最新发布
08-14
<think>好的,我现在需要帮助用户解决他们在Vue组件中处理日期时间格式的问题。用户提供的代码片段显示他们使用了Quasar框架的q-date和q-time组件,并且通过formatDateTimeWithTranslation函数来格式化日期时间。用户希望修改代码,让数据直接格式化存储,而不是仅仅在显示时换。 首先,我需要理解当前的实现。当前的代码中,q-input的value属性使用了formatDateTimeWithTranslation函数来显示格式化的时间,但实际存储在scriptContext.formContext.currentRecord[field.field.customId]中的可能是一个Date对象或者未格式化字符串。当用户选择日期或时间时,fieldChanged函数会被触发,处理值的变更。但数据存储的可能不是格式化后的字符串,导致后续使用时需要再次换。 用户的需求是让数据直接以格式化后的字符串存储,这样在后续操作中不需要每次都换。因此,需要修改日期和时间选择器的绑定逻辑,使得当用户选择日期或时间时,存储的值已经是格式化后的字符串,而不是原始的Date对象。 接下来,我需要考虑如何修改代码。首先,q-date和q-time组件通常绑定到一个变量,当用户选择日期或时间时,这个变量会被更新为Date对象或字符串,具体取决于组件的配置。当前的代码中,q-date和q-time都绑定到scriptContext.formContext.currentRecord[field.field.customId],这可能导致存储的是Date对象,而需要的是格式化后的字符串。 因此,解决方案可能是在绑定的时候就进行格式化,或者在选择器的更新事件中处理。可能需要使用计算属性或者在事件处理函数中手动格式化时间。 另外,用户提到的formatDateTimeWithTranslation函数可能用于将Date对象换为特定格式的字符串。需要确保这个函数在数据存储时也被调用,而不仅仅是在显示时。 可能的步骤包括: 1. 修改q-date和q-time的绑定方式,使其在更新时存储格式化后的字符串。 2. 使用计算属性来处理v-model绑定,将Date对象换为格式化字符串。 3. 在fieldChanged函数中处理格式化,确保传入的值已经是正确的格式。 需要注意的是,直接修改绑定的值可能会影响组件的正常运行,比如q-date和q-time可能需要Date对象来进行正确的显示和选择。因此,可能需要使用中间变量来存储Date对象,而在提交或处理数据时换为格式化字符串,或者在每次选择器更新时立即换。 例如,可以使用一个计算属性来处理v-model绑定,这样当选择器更新Date对象时,计算属性会自动将其换为格式化字符串存储到currentRecord中。或者,在@update:model-value事件中处理格式化,确保传入的值已经是正确的格式。 此外,用户可能希望保留原始的Date对象用于组件内部的状态管理,同时在表单数据中存储格式化后的字符串。这可能需要使用双绑定,并在中间换。 需要检查当前的绑定逻辑,确认currentRecord[field.field.customId]存储的是什么类型的数据,然后决定如何调整。 可能的代码修改包括: - 在q-date和q-time的v-model绑定上使用计算属性,将Date对象换为格式化字符串- 在选择器的更新事件中手动格式化时间,并更新currentRecord。 - 修改fieldChanged函数,在接收到值时先格式化再存储。 同时,需要确保格式化函数formatDateTimeWithTranslation能够正确处理输入的值,无论是Date对象还是原始字符串。 最后,需要测试修改后的代码,确保日期和时间选择器仍然正常工作,并且存储的数据是格式化后的字符串。</think>要实现时间数据直接以格式化字符串存储,需在 **数据绑定阶段** 和 **事件处理阶段** 同时处理格式换。以下是修改方案: --- ### ✅ 修改核心思路 1. **使用计算属性分离原始值和格式化值**:保持组件内部使用 `Date` 对象,存储时自动换为格式化字符串。 2. **在事件处理中强制格式化**:当用户选择时间后,立即将 `Date` 换为格式化字符串并更新表单数据。 --- ### 🛠️ 修改后的代码示例 ```vue <div v-else-if="field.field.fieldViewType == fieldViewTypeEnum.DateTime && field.field.displayType !== displayTypeEnum.Hidden"> <label> <span class="text-red-8" v-if="field.mandatory">*</span> {{ field.label }} </label> <!-- 使用计算属性绑定格式化后的值 --> <q-input outlined dense :value="formattedDateTime" :disable="fieldValueDisable(field.field, scriptContext.formContext.currentRecord)" :rules="[(val) => validateField(val, field.field)]" @update:model-value="(val) => fieldChanged(val, field.field)" > <!-- 日期选择器:绑定原始 Date 对象 --> <template v-slot:prepend> <q-icon name="event" class="cursor-pointer"> <q-popup-proxy cover transition-show="scale" transition-hide="scale"> <q-date v-model="rawDateTime" mask="YYYY/MM/DD" > <div class="row items-center justify-end"> <q-btn v-close-popup :label="t('common.close')" color="primary" flat /> </div> </q-date> </q-popup-proxy> </q-icon> </template> <!-- 时间选择器:绑定原始 Date 对象 --> <template v-slot:append> <q-icon name="access_time" class="cursor-pointer"> <q-popup-proxy cover transition-show="scale" transition-hide="scale"> <q-time v-model="rawDateTime" :format24h="false" > <div class="row items-center justify-end"> <q-btn v-close-popup :label="t('common.close')" color="primary" flat /> </div> </q-time> </q-popup-proxy> </q-icon> </template> </q-input> <!-- 显示格式化后的时间 --> {{ "时间" + formattedDateTime }} </div> ``` --- ### 💡 在 `script` 中添加计算属性和方法 ```javascript export default { data() { return { // 原始 Date 对象,用于组件内部状态管理 rawDateTime: null }; }, computed: { // 格式化后的时间字符串 formattedDateTime() { if (!this.rawDateTime) return ""; return this.formatDateTimeWithTranslation(this.rawDateTime); } }, methods: { // 当时间选择器更新时,自动格式化并更新表单数据 fieldChanged(val, field) { const formattedVal = this.formatDateTimeWithTranslation(val); // 更新表单数据为格式化字符串 this.scriptContext.formContext.currentRecord[field.customId] = formattedVal; }, // 格式化函数(确保支持 Date 对象和字符串) formatDateTimeWithTranslation(date) { if (!date) return ""; // 实现你的格式化逻辑,例如:YYYY/MM/DD HH:mm return moment(date).format("YYYY/MM/DD HH:mm"); } } }; ``` --- ### 📌 关键点说明 - **`rawDateTime`**:作为中间变量,用于 `q-date` 和 `q-time` 的绑定,保持组件内部对 `Date` 的正常操作。 - **`formattedDateTime`**:计算属性,将 `rawDateTime` 换为格式化字符串,供 `q-input` 显示和提交使用。 - **`fieldChanged`**:在事件中将 `Date` 换为格式化字符串,确保表单数据始终为字符串格式。 --- ### ✅ 效果 - **表单数据中存储的是格式化字符串**(如 `"2025/04/05 03:45"`)。 - **组件内部仍使用 `Date` 对象**,保证选择器功能正常。 - **无需在其他地方重复格式化**,提升代码可维护性。 --- ### 📚 相关问题 1. 如何在 Vue 中使用计算属性实现数据双向绑定? 2. 如何确保 q-date 和 q-time 的值在组件外部保持同步? 3. 如何在 Vue 中使用 moment.js 格式化日期时间? 4. 如何在表单提交时统一处理格式化数据? 5. 如何在 Vue 中实现表单数据的自动格式化和校验?
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值