You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

输入31日时dt_ini_vigencia等日期字段自动变为1日求助

问题描述

当输入框选择31日时,JSON字段dt_ini_vigencia和dt_fin_vigencia会被错误转换为当月1日。例如输入2022-12-31T03:00:00.000Z,经以下TypeScript代码处理后,dt_ini_vigencia变成2022-12-01T03:00:00.000Z,dt_fin_vigencia变成2023-12-01T03:00:00.000Z,仅31日触发该问题:

var cotacaoJson = JSON.parse(resp[0].ds_cotacao_json);
var date = new Date();
date.setDate(cotacaoJson.dt_ini_vigencia.substring(8, 10)); // 问题根源所在行
date.setMonth(cotacaoJson.dt_ini_vigencia.substring(5, 7) - 1);
date.setFullYear(cotacaoJson.dt_ini_vigencia.substring(0, 4));
date.setHours(0);
date.setMinutes(0);
date.setSeconds(0);
date.setMilliseconds(0);

var dateF = new Date();
dateF.setDate(cotacaoJson.dt_fin_vigencia.substring(8, 10));
dateF.setMonth(cotacaoJson.dt_fin_vigencia.substring(5, 7) - 1);
dateF.setFullYear(cotacaoJson.dt_fin_vigencia.substring(0, 4));
dateF.setHours(0);
dateF.setMinutes(0);
dateF.setSeconds(0);
dateF.setMilliseconds(0);

this.cotacao = cotacaoJson;

if (!this.editar)
{
  this.cotacao.clausulas_particulares = 'N/A';
}

this.cotacao.dt_ini_vigencia = date;
this.cotacao.dt_fin_vigencia = dateF;
问题原因

核心问题出在Date对象的属性设置顺序,以及JavaScript Date的自动溢出机制:

  • 代码先通过new Date()创建了一个以当前系统日期为基准的Date对象。比如当前日期如果是5月20日(5月只有30天),此时调用setDate(31),因为5月没有31日,Date会自动溢出,把日期调整为下一个月的第1天(也就是6月1日)。
  • 后续再调用setMonth和setFullYear修改年份和月份时,是基于已经变成6月1日的日期来调整的,最终得到的就是目标年份12月的1日——因为修改月份和年份不会改变日期的“日”部分,除非目标月份没有该日期,但12月有31天,所以1日会保留下来。
修复方案

有两种可靠的修复方式:

方式1:调整属性设置顺序

先设置年份和月份,最后设置日期,避免提前触发日期溢出:

var cotacaoJson = JSON.parse(resp[0].ds_cotacao_json);
// 处理生效起始日期
var date = new Date();
date.setFullYear(cotacaoJson.dt_ini_vigencia.substring(0, 4));
date.setMonth(cotacaoJson.dt_ini_vigencia.substring(5, 7) - 1);
date.setDate(cotacaoJson.dt_ini_vigencia.substring(8, 10)); // 最后设置日期
date.setHours(0, 0, 0, 0); // 合并设置时分秒,更简洁

// 处理生效结束日期
var dateF = new Date();
dateF.setFullYear(cotacaoJson.dt_fin_vigencia.substring(0, 4));
dateF.setMonth(cotacaoJson.dt_fin_vigencia.substring(5, 7) - 1);
dateF.setDate(cotacaoJson.dt_fin_vigencia.substring(8, 10));
dateF.setHours(0, 0, 0, 0);

this.cotacao = cotacaoJson;
if (!this.editar) {
  this.cotacao.clausulas_particulares = 'N/A';
}
this.cotacao.dt_ini_vigencia = date;
this.cotacao.dt_fin_vigencia = dateF;

方式2:直接用原日期字符串构造Date对象(更简洁)

原JSON中的日期字符串是标准的ISO格式,直接传入Date构造函数即可正确解析,再重置时分秒即可:

var cotacaoJson = JSON.parse(resp[0].ds_cotacao_json);
// 直接解析原日期字符串
var date = new Date(cotacaoJson.dt_ini_vigencia);
date.setHours(0, 0, 0, 0); // 重置时分秒为0

var dateF = new Date(cotacaoJson.dt_fin_vigencia);
dateF.setHours(0, 0, 0, 0);

this.cotacao = cotacaoJson;
if (!this.editar) {
  this.cotacao.clausulas_particulares = 'N/A';
}
this.cotacao.dt_ini_vigencia = date;
this.cotacao.dt_fin_vigencia = dateF;

内容的提问来源于stack exchange,提问作者Henrique Domanski

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 09:05:22