Pikaday JS如何使用全日和全月名称输入格式而无需使用js Pikaday解析自定义名称日期解析

问题描述

我正在像这样使用Pikaday.js:

new Pikaday({
            field: document.getElementById('top-banner-datepicker'),minDate: new Date()

我知道答案来自文档中的以下示例:

var picker = new Pikaday({
    field: document.getElementById('datepicker'),format: 'D/M/YYYY',toString(date,format) {
        // you should do formatting based on the passed format,// but we will just return 'D/M/YYYY' for simplicity
        const day = date.getDate();
        const month = date.getMonth() + 1;
        const year = date.getFullYear();
        return `${day}/${month}/${year}`;
    },parse(dateString,format) {
        // dateString is the result of `toString` method
        const parts = dateString.split('/');
        const day = parseInt(parts[0],10);
        const month = parseInt(parts[1],10) - 1;
        const year = parseInt(parts[2],10);
        return new Date(year,month,day);
    }
});

但是我不知道如何使用全天(星期一,星期二,星期三等)和全月名字(一月,二月等),而不是缩写(星期一,星期二,星期三...一月, 2月,3月...等等)

我不想使用Moment.JS,因为它是一个巨大的依赖项。

任何帮助,不胜感激!

谢谢

enter image description here

解决方法

如果您希望格式化日期选择器字段,则可以使用toLocaleString()

例如,如果要获取十月而不是十月:

date.toLocaleString('default',{
      month: 'long' // use localestring month to get the long month
});

如果您想用星期日代替星期日:

date.toLocaleString('default',{ // use localestring weekday to get the long day
      weekday: 'long'
});

示例片段:

var picker = new Pikaday({
  field: document.getElementById('datepicker'),firstDay: 1,minDate: new Date(),maxDate: new Date(2020,12,31),yearRange: [2000,2020],format: 'D-M-YYYY',toString(date,format) {
    console.log(date.toLocaleString('default',{
      weekday: 'short' // use localestring weekday to get the short abbv of day
    }));
    console.log(date.toLocaleString('default',{
      month: 'short' // use localestring weekday to get the short abbv of month
    }));
    // you should do formatting based on the passed format,// but we will just return 'D/M/YYYY' for simplicity
    const day = date.getDate();
    const daylong = date.toLocaleString('default',{ // use localestring weekday to get the long day
      weekday: 'long'
    });
    const month = date.getMonth() + 1;
    const monthlong = date.toLocaleString('default',{
      month: 'long' // use localestring month to get the long month
    });
    const year = date.getFullYear();
    return `${daylong},${monthlong},${day} ${year}`; // just format as you wish
  }
});
#datepicker {
  width: 200px;
}
<link href="https://pikaday.com/css/pikaday.css" rel="stylesheet" />
<script src="https://pikaday.com/pikaday.js"></script>
<label for="datepicker">Date:</label>
<input type="text" id="datepicker">

,

Pikaday解析

通常可以很容易地将日期转换成正确的格式,但是棘手的部分通常是从字符串中获取日期。 Pikaday Read Me中有此警告:

但是要小心。如果返回的格式化字符串不能为 通过Date.parse方法(或moment正确地解析 可用),那么您必须在以下位置提供自己的parse函数 配置。该函数将传递格式化的字符串和 格式:

parse(dateString,format = 'YYYY-MM-DD')

使用Date.parsecan yield irregular results。这是moment.js派上用场的地方,因为它可以处理各种格式。当人们直接在输入字段或其他地方键入内容时,将使用解析功能。

两种方法可能涉及使用moon.js的轻量级替代方法或自定义格式化程序。

方法1:轻量级替代方案

您可以搜索moment.js替代方案。我发现this repo列出了一些。在此示例中,我选择了luxon,因为它似乎很小。您可以在此处查看其支持的所有令牌:https://moment.github.io/luxon/docs/manual/parsing.html#table-of-tokens

为帮助解析,我添加了此位,以除去工作日解析,以防万一工作日与实际日期不符:

      if (format.startsWith('EEEE ')) {
        format = format.split(' ').slice(1).join(' ');
        dateString = dateString.split(' ').slice(1).join(' ');
      }

这是一个有效的代码段:

var picker = new Pikaday({
    field: document.getElementById('datepicker'),format: 'EEEE LLLL d,yyyy',format) {
      return luxon.DateTime.fromJSDate(date).toFormat(format);
    },parse(dateString,format) {
      if (format.startsWith('EEEE ')) {
        format = format.split(' ').slice(1).join(' ');
        dateString = dateString.split(' ').slice(1).join(' ');
      }
      return luxon.DateTime.fromFormat(dateString,format).toJSDate();
    }
});
div {
  position: absolute;
  bottom: 0;
}
#datepicker {
  width: 250px;
}
<link href="https://pikaday.com/css/pikaday.css" rel="stylesheet" />
<script src="https://pikaday.com/pikaday.js"></script>
<script src="https://moment.github.io/luxon/global/luxon.min.js"></script>
<div><label for="datepicker">Date:</label>
<input type="text" id="datepicker">
</div>

方法2:自定义格式化程序

对于这个答案,我将只使用您要求的格式,但是解析各种格式会很棘手。

自定义名称

要获得几个月的自定义名称,您可以将其硬编码为:

    var months = ['January','February','March','April','May','June','July','August','September','October','November','December'];
    var days = ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'];

或者,由于您需要普通名称,因此可以使用Intl.DateTimeFormat以编程方式生成它们。如果要在用户的语言环境中显示月份和工作日,这也很有用:

    var monthFormatter = new Intl.DateTimeFormat([],{ month: 'long' });
    var months = [... new Array(12)].map((d,i) => monthFormatter.format(new Date(2020,i,1)));
    var dayFormatter = new Intl.DateTimeFormat([],{ weekday: 'long' });
    var days = [... new Array(7)].map((d,i) =>dayFormatter.format(new Date(2020,1,2 + i)));

要访问名称,只需使用相应的索引(不过请记住,它们基于零)

    console.log(months[new Date().getMonth()]); // current month
    console.log(days[new Date().getDay()]); // current day

因此您的自定义格式功能如下所示:

    toString(date,format) {
        // you should do formatting based on the passed format,// but we will just return 'D/M/YYYY' for simplicity
        const day = date.getDate();
        const year = date.getFullYear();
        const weekday = date.getDay();
        const month = date.getMonth(); // remember,this is zero based!
        return `${days[weekday]} ${months[month]} ${day},${year}`;
    },

日期解析

这是针对上述格式Weekday Month Day,Year的自定义定制分析功能:

    parse(dateString,format) {
        // split the string into the parts separated by a space
        const parts = dateString.trim().split(' ');
        var day,month,year,startIndex;
        if (parts.length >= 3) {
          if (parts.length >= 4) {
            // if there's four parts,assume the first part is the weekday,which we don't need to use to convert it to a date
            startIndex = 1; // skip the weekday
          } else {
            // if there's only three parts,assume that the weekday was omitted
            startIndex = 0;
          }
          // look up the month from our prebuilt array. If it isn't found,it'll return -1,otherwise it will return the (zero based) numerical month.
          month = months.indexOf(parts[startIndex]);
          day = parts[startIndex + 1];
          // if there's a comma after the day,remove it
          if (day.endsWith(',')) {
             day = day.substring(0,day.length - 1);
          }
          day = +day; // convert the string into a number
          year = +parts[startIndex + 2]; // convert the string year into a number
        }
        if (parts.length < 3 // there is less than 3 parts
          || month === -1    // the month wasn't found
          || isNaN(day)      // the day isn't a number
          || isNaN(year)) {  // the year isn't a number
          return Date.parse(dateString); // fall back to default Date parsing
        }
        return new Date(year,day);
    }

总的来说,看起来像这样:

var monthFormatter = new Intl.DateTimeFormat([],{ month: 'long' });
var months = [... new Array(12)].map((d,1)))
var dayFormatter = new Intl.DateTimeFormat([],{ weekday: 'long' });
var days = [... new Array(7)].map((d,2 + i)))

// Alternatively you can just hard code these:
// var months = ['January','December'];
// var days = ['Sunday','Saturday'];


var picker = new Pikaday({
    field: document.getElementById('datepicker'),format: 'D/M/YYYY',day);
    }
});
div {
  position: absolute;
  bottom: 0;
}
#datepicker {
  width: 250px;
}
<link href="https://pikaday.com/css/pikaday.css" rel="stylesheet" />
<script src="https://pikaday.com/pikaday.js"></script>
<div><label for="datepicker">Date:</label>
<input type="text" id="datepicker">
</div>

,

不打算写一本书,因为这样的默认格式可以用Date完成,特别是方法toLocaleDateString(),其中long是非缩写的工作日/月份:

dateLocale: 'en-US',dateOptions: {weekday: 'long',year: 'numeric',month: 'long',day: 'numeric'},format) {
    return date.toLocaleDateString(this.dateLocale,this.dateOptions);
},

即使格式化可能性受到很大限制,
仍然是先进的,支持多语言环境没有问题。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...