【问题标题】:Date conversion resulting into time zone issue日期转换导致时区问题
【发布时间】:2021-12-14 05:40:41
【问题描述】:

我正在尝试获取功能 - 如果用户输入的日期小于当前日期,我需要在屏幕上显示错误消息,我实现了以下代码,该代码在我的本地系统日期中运行良好,但在其他时区。任何人都可以帮助得到这个。

我只需要使用 javascript 或 jquery。我不应该使用其他库。

dateFormat = function(value, event) {
        let newValue = value.replace(/[^0-9]/g, '').replace(/(\..*)\./g, '$1');
        const dayOrMonth = (index) => index % 2 === 1 && index < 4;
        // on delete key.  
        if (!event.data) {
            return value;
        }
        return newValue.split('').map((v, i) => dayOrMonth(i) ? v + '/' : v).join('');
}
    
    
    checkStart = function(value) {
        var newDate = new Date().toISOString();
        var inputDate = new Date(value).toISOString();

        var today = new Date(newDate).setHours(0,0,0,0);
        var userDate = new Date(inputDate).setHours(0,0,0,0);

        if(userDate < today) {
            $('#error-msg3').show();
            $('#startDate').val('');
        } else {
            $('#error-msg3').hide();
        }
}
<input type="tel" maxlength="10" id="startDate" name="startDate" placeholder="mm/dd/yyyy"
                            oninput="this.value = dateFormat(this.value, event)" onblur="checkStart(this.value)" required/>
                
                <span id="error">Start date should not be lesser than the current date.</span>

<script src="https://code.jquery.com/jquery-3.6.0.js"></script>

【问题讨论】:

  • 您是否在数据库中存储日期?您如何存储它,以及如何将其发送到服务器
  • 我已经更新了上面的代码,我正在将用户输入的日期格式转换为 mm/dd/yyyy 并通过表单操作 url 将其发送到服务器
  • 如果您的代码使用 jQuery,请将其作为库包含在 sn-p 中,否则只会抛出错误。为什么要使用输入类型 tel 作为日期?即使包含 jQuery,脚本似乎也没有做任何有用的事情。

标签: javascript jquery date timezone


【解决方案1】:

您的代码完全在客户端上运行,因此时区无关紧要。

在 OP 中有:

var newDate = new Date().toISOString();
...
var today = new Date(newDate).setHours(0,0,0,0);

日期到字符串到日期到数字的转换效率低下且没有必要。以下是等价的:

let today = new Date().setHours(0,0,0,0);

inputDate 类似:

var inputDate = new Date(value).toISOString();
...
var userDate = new Date(inputDate).setHours(0,0,0,0);

相当于:

let userDate = new Date(value).setHours(0,0,0,0);

所有计算都是本地的,因此时区无关紧要。另见Why does Date.parse give incorrect results?

尝试使用脚本控制用户输入总是令人担忧,因为有很多情况是不可能或不切实际的编码。对日期使用 tel 输入就是一个示例。通过使用日期输入并将最小值设置为今天,可以避免整个问题。然后用户无法选择今天之前的日期并且您的问题已解决,例如

window.onload = function() {
  let dateEl = document.getElementById('dateInput');
  dateEl.min = new Date().toLocaleString('en-CA', {year:'numeric', month:'2-digit', day:'2-digit'});
}
&lt;input id="dateInput" type="date"&gt;

如果您将用户发送的日期与服务器上的日期进行比较,则用户系统时钟的准确性和时区可能是一个问题,但这在 OP 中没有解释。

如果这是一个问题,那么您需要就该特定主题提出另一个问题。

如果您真的想要手动控制输入日期并在选择无效日期时显示错误消息,则解析日期输入中的值并将其与今天的开始时间进行比较并从那里:

// Parse YYYY-MM-DD as local
function parseYMDLocal(s) {
  let [Y, M, D] = s.split(/\D/);
  return new Date(Y, M-1, D);
}

// Check if date in YYYY-MM-DD format is before today
function isBeforeToday(d) {
  return parseYMDLocal(d) < new Date().setHours(0,0,0,0);
}

function checkValue() {
  let errEl = document.getElementById('errEl');
  errEl.textContent = '';
  console.log(typeof this.value);
  if (isBeforeToday(this.value)) {
    errEl.textContent = 'Date must be today or later';
  } else {
    // do something else
  }
}

window.onload = function() {
  document.getElementById('dateInp').addEventListener('blur', checkValue, false);
}
#errEl {color: red}
&lt;input id="dateInp" type="date"&gt;&lt;span id="errEl"&gt;&lt;/span&gt;

【讨论】:

    【解决方案2】:

    Server 和 Db 可能在不同的时区运行(首选 UTC),当您将日期作为字符串发送时,它没有任何时区,而只是一个字符串。

    尝试将其作为时间戳或 UTC 日期字符串发送 这样服务器和数据库就会自动将其转换为他们的 timzone 并存储它。并且当任何用户从其他时区获取它时,它会自动转换为他们的时区(但是您存储字符串,它将在任何地方都被视为字符串)

    let d = new Date()
    console.log(d.getTime()) 
    
    //or get utc string
    console.log(d.toUTCString())

    将此值发送到您的服务器 (API)

    【讨论】:

    • 如果我以这种方式使用,这适用于任何 timzone 吗? var newDate = new Date().toUTCString(); var inputDate = new Date(value).toUTCString(); var today = new Date(newDate).setHours(0,0,0,0); var userDate = new Date(inputDate).setHours(0,0,0,0);
    • 在您所在的时区,时间将是 (0,0,0),但在另一个时区,当然,时间会有所不同,正如您所知道的,如果您所在的时区是上午 12 点其他时间是凌晨 3 点。为所有时区设置 0,0,0 是没有意义的
    • 但是如果我以这种方式编写代码,它也允许我输入昨天的日期,这实际上应该需要显示一条错误消息。 var today = new Date().toUTCString(); var userDate = new Date(value).toUTCString(); if(userDate
    • 在发送到服务器之前检查日期是否已过。 google 和 StackOverflow 中提供了许多解决方案
    • OP 代码完全在客户端运行,因此服务器时区无关紧要。
    猜你喜欢
    • 2019-12-21
    • 1970-01-01
    • 2021-12-14
    • 2019-03-21
    • 2011-10-25
    • 1970-01-01
    • 1970-01-01
    • 2021-06-02
    相关资源
    最近更新 更多