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

从DateTimePicker赋值给另一个时丢失UTC时区,如何解决?

问题描述

我有一个设置了UTC: true的DateTimePicker:

<DateTimePicker id="massStartDate" displayFormat="dd MMM yyyy, HH:mm" secondsStep="60" width="20%" minDate="{config>/minDate}" 
    value="{path : 'config>/jobShift/massStart', type: 'sap.ui.model.type.DateTime', formatOptions: { strictParsing: true , UTC: true, pattern: 'dd MMM yyyy, HH:mm:ss' }}"
    placeholder="Enter Start Date..."/>

需要将这个DateTimePicker的值循环传递给其他多个同样设置了UTC: true的DateTimePicker:

<DateTimePicker minDate="{config>/minDate}" displayFormat="dd MMM yyyy, HH:mm" secondsStep="60" 
    value="{path : 'ConstraintStartTimestamp', type: 'sap.ui.model.type.DateTime', formatOptions: { strictParsing: true , UTC: true, pattern: 'dd MMM yyyy HH:mm' }}"
    placeholder="Enter Start Date..."/>

但传递后,目标DateTimePicker显示的时间少了一小时。具体信息:

  • 初始DateTimePicker的值:Wed Jul 12 2023 10:27:00 GMT+0100 (British Summer Time)
  • 目标DateTimePicker绑定的Date对象值和上述一致,但UI实际显示为09:27(比预期时间少一小时)

赋值代码如下:

for(var i = 0; i < oItems.length; i++) {
    var oContext = oItems[i].getBindingContext();
    dStartDate = new Date(dpStartDate.getValue());
    dEndDate = new Date(dpEndDate.getValue());
    this.getModel().setProperty(oContext.getPath() + "/ConstraintStartTimestamp", dStartDate);
    this.getModel().setProperty(oContext.getPath() + "/ConstraintFinishTimestamp", dEndDate);
}
解决方案

问题根源在于dpStartDate.getValue()返回的是格式化后的本地时区字符串,用这个字符串创建Date对象时,浏览器会基于本地时区解析,再结合目标控件UTC: true的格式化规则,就会产生时区偏移导致的时间差。

以下两种方案可解决该问题:

方案1:直接获取绑定模型中的原始Date对象

优先从源控件的绑定模型取原始值,避免手动解析字符串带来的时区问题:

for(var i = 0; i < oItems.length; i++) {
    var oContext = oItems[i].getBindingContext();
    // 直接从config模型获取源控件绑定的原始Date对象
    dStartDate = this.getModel("config").getProperty("/jobShift/massStart");
    dEndDate = this.getModel("config").getProperty("/jobShift/massEnd"); // 替换为你的结束日期绑定路径
    this.getModel().setProperty(oContext.getPath() + "/ConstraintStartTimestamp", dStartDate);
    this.getModel().setProperty(oContext.getPath() + "/ConstraintFinishTimestamp", dEndDate);
}

方案2:将字符串解析为UTC时间后创建Date对象

如果必须通过getValue()获取字符串,需先将其转换为UTC时间再生成Date对象:

for(var i = 0; i < oItems.length; i++) {
    var oContext = oItems[i].getBindingContext();
    
    // 处理开始日期
    var startStr = dpStartDate.getValue();
    // 按源控件displayFormat拆分字符串:dd MMM yyyy, HH:mm
    const [datePart, timePart] = startStr.split(", ");
    const [day, month, year] = datePart.split(" ");
    const [hour, minute] = timePart.split(":");
    // 将月份名称转为数字(Jan=0,Feb=1...)
    const monthNum = new Date(Date.parse(`${month} 1, 2000`)).getMonth();
    // 创建UTC时间的Date对象
    dStartDate = new Date(Date.UTC(year, monthNum, day, hour, minute));

    // 处理结束日期(逻辑同开始日期)
    var endStr = dpEndDate.getValue();
    const [endDatePart, endTimePart] = endStr.split(", ");
    const [endDay, endMonth, endYear] = endDatePart.split(" ");
    const [endHour, endMinute] = endTimePart.split(":");
    const endMonthNum = new Date(Date.parse(`${endMonth} 1, 2000`)).getMonth();
    dEndDate = new Date(Date.UTC(endYear, endMonthNum, endDay, endHour, endMinute));

    this.getModel().setProperty(oContext.getPath() + "/ConstraintStartTimestamp", dStartDate);
    this.getModel().setProperty(oContext.getPath() + "/ConstraintFinishTimestamp", dEndDate);
}

额外注意事项

  • 确保源和目标控件的formatOptions.pattern与displayFormat时区规则统一,均设置UTC: true
  • 尽量避免手动处理日期字符串,优先通过模型传递原始Date对象或UTC时间戳,减少时区解析误差

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 09:47:47