5

我像这样使用 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);
    }
});

但我不知道如何使用全天(周一、周二、周三等)和全月名称(一月、二月等)而不是缩写词(周一、周二、周三... Jan、Feb、Mar ... ETC)

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

非常感谢任何帮助!

谢谢

在此处输入图像描述

4

3 回答 3

7

如果您希望格式化 datepicker 字段,您可以使用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">

于 2020-11-04T02:44:52.613 回答
2

皮卡迪解析

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

不过要小心。如果您返回的格式化字符串无法被Date.parse方法正确解析(或者moment如果它可用),那么您必须parse在 config.xml 中提供您自己的函数。此函数将传递格式化的字符串和格式:

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

使用Date.parse会产生不规则的结果。这是moment.js派上用场的地方,因为它可以处理各种格式。当一个人直接在输入字段或其他地方输入时使用解析功能。

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

方法 1:轻量级替代品

您可以搜索 moment.js 替代品。我发现这个 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',
    toString(date, 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, month, day);
    }

总之,它看起来像这样:

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)))

// Alternatively you can just hard code these:
// var months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
// var days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];


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 year = date.getFullYear();
        const weekday = date.getDay();
        const month = date.getMonth(); // remember, this is zero based!
        return `${days[weekday]} ${months[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, month, 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>

于 2020-11-04T04:29:55.173 回答
1

不打算写一本关于它的书,因为这种默认格式可以用 来完成Date,特别是 method toLocaleDateString()long非缩写的工作日/月在哪里:

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

即使格式化的可能性相当有限,
但进步仍然是,支持多语言环境是没有问题的。

于 2020-11-04T04:38:17.523 回答