皮卡迪解析
将日期转换为正确的格式通常很容易,但棘手的部分通常是从字符串中获取日期。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>