【问题标题】:Setting value of datetime-local from Date从 Date 设置 datetime-local 的值
【发布时间】:2015-05-11 11:20:01
【问题描述】:

我想用当前日期和时间设置本地日期时间输入的值。现在我有一个丑陋的解决方案,涉及对前 17 个字符进行切片。此外,它以格林威治标准时间而不是本地时间设置时间。我的代码如下:

<input type="datetime-local" name="name" id="1234">

<script type="text/javascript">
  var d = new Date();
  var elem = document.getElementById("1234"); 
  elem.value = d.toISOString().slice(0,16);
</script>

这段代码有两个问题:

  1. 有没有一种方法可以将 Date 转换为合法值,而无需手动对字符串进行切片?
  2. 我希望字符串在本地日期时间中显示为DD/MM/YYYY, hh:mm(例如,05/11/2015, 14:10 在 GMT 中是 13:10,但我在 GMT+1 中,所以我想显示 14:10)。当前显示的是05/11/2015, 01:10 PM。我想删除 PM 并以当地时间显示。

这可能是XY problem,所以如果我做错了,并且有更好的方法在 html 中显示日期时间选择器,我会很高兴听到。

【问题讨论】:

    标签: javascript html datetime


    【解决方案1】:

    我最终减去getTimezoneOffset 分钟来调整toISOString 值:

    var now = new Date();
    now.setMinutes(now.getMinutes() - now.getTimezoneOffset());
    document.getElementById('dt').value = now.toISOString().slice(0,16);
    &lt;input id="dt" type="datetime-local" /&gt;

    【讨论】:

    • 我希望有更多内置的东西来生成本地日期时间输入所需的格式,但是这个答案很有效并且很简单。谢谢!
    • 酷,代码干净且易于准备。
    • @Ninja 就像你的评论一样。 XD
    • 顺便说一句:如果您的datetime-local 输入设置了step="1",并且您希望该值不被第二次删除,请将.slice(0,16) 部分替换为.replace(/\.\d\d\dZ/, "")
    【解决方案2】:

    toISOString 函数负责将您的本地日期 (new Date) 转换为 GMT。

    如果不想使用 GMT 然后切片,则需要使用纯 Date 构造函数和所有 getX 函数,其中 X 是(天、月、年...)

    此外,您需要使用一个函数来扩展Number 对象,该函数将帮助您返回01 而不是1,例如,以保留dd/mm/yyyy, hh/mm 格式。

    让我把这个原型函数称为AddZero

          <input type="datetime-local" name="name" id="1234">
    
         <script type="text/javascript">
           Number.prototype.AddZero= function(b,c){
            var  l= (String(b|| 10).length - String(this).length)+1;
            return l> 0? new Array(l).join(c|| '0')+this : this;
         }//to add zero to less than 10,
    
    
           var d = new Date(),
           localDateTime= [(d.getMonth()+1).AddZero(),
                    d.getDate().AddZero(),
                    d.getFullYear()].join('/') +', ' +
                   [d.getHours().AddZero(),
                    d.getMinutes().AddZero()].join(':');
           var elem=document.getElementById("1234"); 
           elem.value = localDateTime;
         </script>
    

    See this

    【讨论】:

    • 感谢您的回答。这会将正确的时间打印为字符串 (05/11/2015, 14:36:30),但不能作为 datetime-local 的值
    • 我在w3schools.com/htmL/… 上运行我的代码。如果你复制粘贴你的代码,你会看到它不能正确显示。
    • 酷!你所说的 datetime-local 是什么意思?除非我错了,否则本地日期时间是安装运行浏览器时操作系统的日期和时间。
    • 是的,当你在那里运行你的代码时,它只会为我显示 null。
    • 谢谢,我会玩的。
    【解决方案3】:

    以下函数将接受一个日期对象(例如new Date()),并将返回一个格式正确为&lt;input type='datetime-local'&gt; 的字符串。

    const dateForDateTimeInputValue = date => new Date(date.getTime() + new Date().getTimezoneOffset() * -60 * 1000).toISOString().slice(0, 19)
    

    【讨论】:

    • 这并不总是有效,因为getTimezoneOffset 它使用的是new Date 而不是日期。当日期来自时间开关之前,我们在时间开关偏移后计算它会不正确。例如。当给定时间是:1645100310000,当前时间是1649067798571 调用dateForDateTimeInputValue(new Date(1645100310000)) 会给我们'2022-02-17T14:18:30' 而不是正确的:'2022-02-17T13:18:30'
    • 所以正确的解决方案是:const dateForDateTimeInputValue = date =&gt; new Date(date.getTime() + date.getTimezoneOffset() * -60 * 1000).toISOString().slice(0, 19)
    【解决方案4】:

    这是我使用时间戳的解决方案:

      function timestampToDatetimeInputString(timestamp) {
        const date = new Date((timestamp + _getTimeZoneOffsetInMs()));
        // slice(0, 19) includes seconds
        return date.toISOString().slice(0, 19);
      }
      
      function _getTimeZoneOffsetInMs() {
        return new Date().getTimezoneOffset() * -60 * 1000;
      }
    
      document.getElementById('dt').value = timestampToDatetimeInputString(Date.now());
      
    &lt;input id="dt" type="datetime-local" /&gt;

    【讨论】:

      【解决方案5】:

      依靠别人的...

      <input id="myDateTime" type="datetime-local">
      
      <script>
      
          var dateString = "7/15/20 7:9:00 PM"
      
          if (dateString !== "") {
      
              var dateVal = new Date(dateString);
              var day = dateVal.getDate().toString().padStart(2, "0");
              var month = (1 + dateVal.getMonth()).toString().padStart(2, "0");
              var hour = dateVal.getHours().toString().padStart(2, "0");
              var minute = dateVal.getMinutes().toString().padStart(2, "0");
              var sec = dateVal.getSeconds().toString().padStart(2, "0");
              var ms = dateVal.getMilliseconds().toString().padStart(3, "0");
              var inputDate = dateVal.getFullYear() + "-" + (month) + "-" + (day) + "T" + (hour) + ":" + (minute) + ":" + (sec) + "." + (ms);
      
              $("#myDateTime").val(inputDate);
          }
      </script>
      

      分配给 input.val() 的值必须在 YYYY-MM-DDThh:mm:ss.mss 中填充每个数字占位符 - 请参阅 Proper format for datetime-local value

      【讨论】:

        【解决方案6】:

        示例:

         <TextField
           variant="standard"
           style={{width:"50%"}}
         //type='datetime-local'
         type='datetime-local'
         InputLabelProps={{
          shrink: true                                              
          }}
        defaultValue={new Date().toISOString().substring(0, (new Date().toISOString().indexOf("T")|0) + 6|0)}
        />
        

        【讨论】:

          【解决方案7】:

          Mdn 说这样的客户端时间有问题

          function setValue(element, date) {
              var isoString = date.toISOString()
              element.value = isoString.substring(0, (isoString.indexOf("T")|0) + 6|0);
          }
          
          setValue(document.querySelector("#timelocal"), new Date())
          <!--midnight of January 1st, 10000: the exact time of Y10K-->
          <input type="datetime-local" id="timelocal"/>

          那么你应该总是添加

          new Date().getTimezoneOffset() * 60 * 1000
          

          当你给这个元素赋值时,当你读取它的值时减去

          function setValue(element, date) {
              date = new Date(date.getTime() - new Date().getTimezoneOffset() * 60 * 1000)
              var isoString = date.toISOString()
              element.value = isoString.substring(0, (isoString.indexOf("T")|0) + 6|0);
          }
          
          var el = document.querySelector("#timelocal");
          setValue(el, new Date())
          
          var correctDate =  new Date( el.valueAsNumber + new Date().getTimezoneOffset() * 60 * 1000);
          console.log(correctDate.toString())
          &lt;input type="datetime-local" id="timelocal"/&gt;

          【讨论】:

            【解决方案8】:

            从 ES6(?) 开始,您可以使用 .valueAsDate 属性:

            const dateInput = document.querySelector('#date-input')
            
            const localDt =_=>  // return local Date time
              {
              let now = new Date()
              now.setMinutes(now.getMinutes() - now.getTimezoneOffset())
              now.setSeconds(0)       // remove seconds
              now.setMilliseconds(0) // remove milliseconds
              return now
              }
              
            // usage :
            dateInput.valueAsDate = localDt()  // init date value 
            &lt;input type="datetime-local" id="date-input" &gt;

            【讨论】:

              【解决方案9】:

              这可能有点矫枉过正。如果您只想要 OP 要求的内容,请跳到最后一行 input.valueAsNumber...

              /**
               * Store the given date and time into the given input element.
               * Everything will be displayed in local time, similar to dateAndTime.toString().
               * 
               * Going the other way is easy:  `new Date(input.value)`.
               * @param input This should be set to "datetime-local".
               * @param dateAndTime The date and time to load into the input.
               */
              export function loadDateTimeLocal(input : HTMLInputElement, dateAndTime : Date, truncateTo : "minutes" | "seconds" | "milliseconds" = "milliseconds") {
                // The element will remember this value.
                // If you store a time like '2021-12-08T14:23:01.001', the display and the editor will show seconds and milliseconds.
                // If you store a time like '2021-12-08T14:23:01.000' or '2021-12-08T14:23:01', the display and the editor will show seconds but not milliseconds.
                // If you store a time like '2021-12-08T14:23:00.000' or '2021-12-08T14:23', the display and the editor will show neither seconds nor milliseconds.
                // Changing the time using the GUI will not change which fields are displayed.
                // Note:  Rounding or truncating will only remove fields, not add them.
                // If you want to display "14:23:00.000", and you want the user to be able to set the seconds via the GUI, I don't think that's possible.
                // Note:  I didn't see this documented anywhere.  I learned this by experimenting with Chrome.
                let truncateBy : number;
                switch (truncateTo) {
                  case "minutes": {
                    truncateBy = dateAndTime.getSeconds() * 1000 + dateAndTime.getMilliseconds();
                    break;
                  }
                  case "seconds": {
                    truncateBy = dateAndTime.getMilliseconds();
                    break;
                  }
                  case "milliseconds" : {
                    truncateBy = 0;
                    break;
                  }
                  default: {
                    throw new Error("wtf");
                  }
                }
                // This is conversion is surprisingly hard to do.  Advice from MDN and others failed miserably.
                input.valueAsNumber = (+dateAndTime) - (dateAndTime.getTimezoneOffset() * 60000) - truncateBy;
              }
              

              【讨论】:

                【解决方案10】:

                我刚刚创建了一个函数来将新的 Date 本地时区格式化为 datetime 以将其插入到 mysql 注册表中

                const dateTime = new Date();
                const dateTimeFormat = (dateTime) => {
                    
                    const localDateTime = dateTime.toLocaleString('en-GB')
                    const dateTimeArray = localDateTime.split(',')
                    const date = dateTimeArray[0].split('/').reverse().join('-')
                    const time = dateTimeArray[1]
                    
                    return date + ' ' + time
                }
                

                【讨论】:

                  【解决方案11】:

                  替换此行

                  elem.value = d.toISOString().slice(0,16);
                  

                  elem.value = d.toLocaleString();
                  

                  这仍然会在最后打印“am/pm”,但它会根据本地值调整时间。

                  【讨论】:

                  • 这不适用于 datetime-local 类型的输入
                  【解决方案12】:

                  我个人用过:

                  <input type="datetime-local" name="name" id="1234" value="<?php echo date('Y-m-d');echo 'T';echo date (H);echo ':';echo date(i);?>">
                  

                  【讨论】:

                  • 只投票给你,因为这是在 php 中,OP 标签引用 html、javascript 和 datetime 对象
                  • 我使用 PHP,这个解决方案也适用于我,谢谢
                  猜你喜欢
                  • 1970-01-01
                  • 2014-09-20
                  • 2014-10-09
                  • 2014-08-12
                  • 2022-12-28
                  • 2017-04-12
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多