我正在尝试创建一个接受三个输入变量(开始日期,结束日期,粒度)的函数,并输出一个包含所有日期的数组。根据输入,输出将是每日或每月粒度。例如,如果我看2015年1月 - 2015年2月:
我根据其他一些帖子编写了一些内容,从逻辑上讲它似乎对我有用,但出于某种原因,每天查看每日粒度会返回31天。下面的脚本只关注每日粒度(每月会更容易) - 有人可以看看我做错了什么,如果有更有效的方法来做到这一点?
日期的输入格式为“yyyy-mm”
我意识到这可能是一个新手的错误,但至少我会学到:)
由于
function dateRange2 (startDate,endDate,granularity) {
var dates = [];
var d0 = startDate.split('-');
var d1 = endDate.split('-');
var months31 = [1,3,5,7,8,10,12];
var months30 = [4,6,9,11];
for (var y = d0[0]; y <= d1[0]; y++) {
for (var m = d0[1]; m <= d1[1]; m++) {
if (m in months31) {
for (var d =1;d <=31; d++) {
dates.push(y+"-"+m+"-"+d);
}
} ///// Issue seems to be here - not switching over to next clause
else if (m in months30) {
for (var d =1; d <=30; d++) {
dates.push(y+"-"+m+"-"+d);
}
} else if (m=2 && y=2016) {
for (var d =1; d <=29; d++) {
dates.push(y+"-"+m+"-"+d);
}
} else if (m=2 && y!=2016) {
for (var d =1; d <=28; d++) {
dates.push(y+"-"+m+"-"+d);
}
}
}
}
return dates;
}
答案 0 :(得分:2)
而不是在运算符中,使用indexOf如下:
if (months31.indexOf(m) >= 0){
}
else if (months30.index(m) >= 0){
}
运算符中的将返回给定值是否为object的属性: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/in
答案 1 :(得分:1)
其他人已经展示了如何修复代码。回答&#34;更有效率&#34;因为你还没有提供标准,所以很难。但是,如果您需要关注度分离的健壮代码,请考虑使用单独的函数来解析日期字符串,格式化日期并计算范围。
如果您有许多不同的格式可供使用,有许多用于解析和格式化日期的小型库,但如果没有,那么以下简单的函数应该适合。
如果文档和评论足够,请询问,我会提供更新。
/* Parse date string in ISO 8601 format as local
** @param {string} s - Date string like 2016-04-01
** @returns {Date} If date is invalid, returns an invalid Date
*/
function parseISODate(s) {
var b = s.split(/\D/);
var d = new Date(b[0], b[1]? b[1] - 1 : 0, b[2] || 1);
return d && d.getMonth() == b[1] - 1? d : new Date(NaN);
}
/* Return an ISO 8601 formatted date string based on local time
** Only works for positive years (i.e. doesn't do -ve year)
** @param {Date} date - date object to create date string from
** @returns {string} dates string in yyyy-mm-dd format or default from
** Date.prototype.toString (i.e. "Invalid Date")
*/
function toISODate(date) {
return date.getDate()? ('000' + date.getFullYear()).slice(-4) + '-' +
('0' + (date.getMonth() + 1)).slice(-2) + '-' +
('0' + date.getDate()).slice(-2) : date.toString();
}
/* Generate an array of ISO 8601 formatted date strings for a
** range of dates inclusive of start and end. Either monthly
** or daily intervals (default is daily).
** @param {string} fromDate - start date in ISO 8601 format
** @param {string} toDate - end date in ISO 8601 format
** @param {boolean} monthly - return monthly intervals
** @returns {Array} of date strings. If either fromDate or
** toDate are invalid, returns undefined.
*/
function genDatesInRange(fromDate, toDate, monthly) {
var s = parseISODate(fromDate);
var e = parseISODate(toDate);
var dates = [];
// Check that dates are valid
if (!s.getDate() || !e.getDate()) return;
// If monthly, set start to 1st of start month and e to 1st of end month
if (monthly) {
s.setDate(1);
e.setDate(1);
}
while (s <= e) {
dates.push(monthly? toISODate(s).substr(0,7) : toISODate(s));
if (monthly) {
s.setMonth(s.getMonth() + 1);
} else {
s.setDate(s.getDate() + 1);
}
}
return dates;
}
// Daily
console.log(genDatesInRange('2015-05-23','2015-06-03')); // Daily
console.log(genDatesInRange('2015-09-03','2016-03-13', true)); // Monthly
&#13;
答案 2 :(得分:0)
经过一些试验和错误后计算出来 - 它可能不是最漂亮的代码,但是它完成了这项工作......理想情况下,我已将每条注释行添加为单独函数的一部分。
我还注意到每个案例都使用四个&#34; if&#34;参数不需要&#34;否则如果&#34;。
function dateRangetest (start_month,start_year,end_month,end_year,granularity) {
var dates = [];
var d0 = [start_year,start_month];
var d1 = [end_year,end_month];
// var d0 = [2014,6] FOR TESTING
// var d1 = [2016,4]
switch (granularity) {
case "Daily":
for (var y = d0[0]; y <= d1[0]; y++) {
if ((y == d0[0]) && (d0[0] != d1[0])) { // if year=start_year && year != end year ... start from start_month and loop up to month 12
for (var m = d0[1]; m <= 12; m++) {
for (var d =1;d <= monthday(m,y); d++) {
dates.push(y+"-"+m+"-"+d)
}
}
}
if ((y != d0[0]) && (y!= d1[0])) { // if year != start_year && year != end year .... start from month 1 to month 12 - this would 2015 data in pulling Dec 2014 - April 2016
for (var m = 1; m <= 12; m++) {
for (var d =1;d <= monthday(m,y); d++) {
dates.push(y+"-"+m+"-"+d)
}
}
}
if ((y != d0[0]) && (y == d1[0])) { // if year !=start_year && year = end_year .... start from month 1 up until end_month
for (var m = 1; m <= d1[1]; m++) {
for (var d =1;d <= monthday(m,y); d++) {
dates.push(y+"-"+m+"-"+d)
}
}
}
if ((y == d0[0]) && (y == d1[0])) { /// if year=start_year && year = end_year .... start from start_month to end_month
for (var m = d0[1]; m <= d1[1]; m++) {
for (var d =1;d <= monthday(m,y); d++) {
dates.push(y+"-"+m+"-"+d)
}
}
}
}
break;
case "Monthly":
for (var y = d0[0]; y <= d1[0]; y++) {
if ((y == d0[0]) && (d0[0] != d1[0])) { // if year=start_year && year != end year ... start from start_month and loop up to month 12
for (var m = d0[1]; m <= 12; m++) {
dates.push(y+"-"+m)
}
}
if ((y != d0[0]) && (y!= d1[0])) { // if year != start_year && year != end year .... start from month 1 to month 12 - this would 2015 data in pulling Dec 2014 - April 2016
for (var m = 1; m <= 12; m++) {
dates.push(y+"-"+m)
}
}
if ((y != d0[0]) && (y == d1[0])) { // if year !=start_year && year = end_year .... start from month 1 up until end_month
for (var m = 1; m <= d1[1]; m++) {
dates.push(y+"-"+m)
}
}
if ((y == d0[0]) && (y == d1[0])) { /// if year=start_year && year = end_year .... start from start_month to end_month
for (var m = d0[1]; m <= d1[1]; m++) {
dates.push(y+"-"+m)
}
}
}
}
return dates
}
/// Function for Day Date Range
function monthday (month,year) {
var months31 = [1,3,5,7,8,10,12]
var months30 = [4,6,9,11]
var leapyear = [2016,2020,2024,2028,2032]
if (months31.indexOf(month) >=0){
var result = 31}
else if (months30.indexOf(month) >=0){
var result = 30}
else if (month==2 && leapyear.indexOf(year) >=0){
var result = 29}
else if (month==2 && year != 2016){
var result = 28}
return result
}