如何在两个给定日期之间仅获取星期一的最后一天的日期

时间:2017-08-06 19:19:27

标签: javascript date

返回值应为" 10/31/2016 8/31/2017和#34;等字符串。此函数返回一年中的所有星期一,但我只需要每月最后一个星期一的日期,如果它们是该月的最后一天。

function getMondays(startYear, endYear) {
  const startDate = new Date(startYear, 0, 2)
  const endDate = new Date(endYear, 11, 32)

  var i = startDate,
  month = i.getYear(),
  mondaysOfYear = []

  while (i.getDay() !== 2) {
  i.setDate(i.getDate() + 1)
  }

  while (i.getYear() === month) {
    mondaysOfYear.push(new Date(i.getTime()))
    i.setDate(i.getDate() + 7)
  }
  return mondaysOfYear
}
getMondays(2017, 2017)

5 个答案:

答案 0 :(得分:2)

你的逻辑看起来不合适。有:

while (i.getDay() !== 2) {
  i.setDate(i.getDate() + 1)
}

getYear 返回2位数的年份,将其分配给名为" month"的变量。似乎不合理。然后:

if (i.getMonth() != prevMonth) mondaysOfYear.push(prevDate);

将增加日期,直到getDay返回2,即星期二。然后:

function getMondays(startYear, endYear) {
  // Set start to 1 Jan of start year
  var start = new Date(startYear, 0);
  // Set end to 31 Dec of end year
  var end = new Date(endYear, 11,31);
  var mondays = [];
  
  do {
    // setDate to end of month 
    start.setMonth(start.getMonth() + 1, 0);

    // If it's a Monday, store it in US mm/dd/yyyy format
    if (start.getDay() == 1) {
      mondays.push(start.toLocaleString('en-us', {
        year:  'numeric',
        month: '2-digit',
        day:   '2-digit'
      }));
    }

    // Set date to start of next month
    start.setDate(start.getDate() + 1);
  } while (start <= end) 
 
  return mondays;
}

console.log( getMondays(2016,2017) );

对我没有任何意义。我猜你的算法是将日期设置为星期一,然后添加几周,如果它在一个月末结束,请保存。但是你没有这样实现它。

更简单且可能更快的算法是从开始到结束每个月的最后一天,如果它是星期一,则将其推送到数组。有很多方法可以做到这一点,这里有一个。

&#13;
&#13;
{{1}}
&#13;
&#13;
&#13;

答案 1 :(得分:1)

&#13;
&#13;
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let cell = tableView.cellForRow(at: indexPath) as! FeedTableViewCell
    self.addImageViewWithImage(image: cell.postedImage.image)
}
&#13;
&#13;
&#13;

答案 2 :(得分:0)

这将取出你所有的最后一个星期一 -

function getMondays(startYear, endYear) {
  const startDate = new Date(startYear, 0, 2)
  const endDate = new Date(endYear, 11, 32)

  var i = startDate,
  month = i.getYear(),
  mondaysOfYear = []

  while (i.getDay() !== 2) {
  i.setDate(i.getDate() + 1)
  }
  var prevMonth = 0;
  var prevDate;
  while (i.getYear() === month) {
    if(i.getMonth()!= prevMonth) mondaysOfYear.push(prevDate);
    prevMonth = i.getMonth(); //Retaining the last month to compare
    prevDate = new Date(i.getTime()); //Retaining the last monday
    i.setDate(i.getDate() + 7); 
  } 
  mondaysOfYear.push(prevDate);//for December
  return mondaysOfYear
}
getMondays(2017, 2017);

过滤掉月份变化的日期。在循环之后最后添加12月的最后一个星期一。

答案 3 :(得分:0)

这样的东西?

- 编辑

以下是jsfiddle的链接,以防它在stackoverflow上给出错误的结果:)

function getMondays(startYear, endYear) {
  var months = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
  var mondays = [];
  while(startYear <= endYear) {
    for(var i = 0; i < 12; i++) {
      var leapYear = startYear % 4 === 0 && i === 1;
      var currentDate = new Date(startYear, i, leapYear ? months[i]+1 : months[i]);
      if(currentDate.getDay() === 1)
        mondays.push(currentDate);
    }
    startYear += 1;
  }
  return mondays;
}

var mondays = getMondays(2016, 2017)
console.log(mondays)

答案 4 :(得分:-1)

您的问题尚不清楚,但是显然您想查找所有发生在每月的最后一天恰好是星期一的情况。

java.time

现代方法使用 java.time 类。具体来说,LocalDate类表示没有日期和时区的仅日期值。顾名思义,还有类YearYearMonthDayOfWeek

为了传递类型安全,您可以传递Year对象,而不是仅传递整数,从而使代码更具自记录性。

Year startYear = Year.of( 2016 );
Year stopYear = Year.of( 2018 );

定义实用程序方法。

public List< LocalDate > calcMondays ( Year startYear , Year stopYear ) { … }

传递那对对象。

List< LocalDate> dates = this.calcMondays( startYear , stopYear ) ;

我建议一贯使用Half-Open方法来定义时间跨度。在这种方法中,开始为包含,而结束为排他。因此,2017-2019年的期限将从2017年的第一天开始,直至(但不包括)2019年的第一天,为期2年。

获取开始和结束的YearMonth,代表整个月份。

YearMonth startYm = YearMonth.from( startYear.atDay( 1 ) ) ;
YearMonth stopYm = YearMonth.from( stopYear.atDay( 1 ) ) ;

定义我们找到的日期的集合。

int initialCapacity = ( int ) ChronoUnit.MONTHS.between( startYear.atDay( 1 ) , stopYear.atDay( 1 ) );
List< LocalDate > lastMondays = new ArrayList<>( initialCapacity ) ;

定义我们要定位的星期几。使用DayOfWeek枚举。

DayOfWeek dow = DayOfWeek.MONDAY ; 

使用TemporalAdjuster类中的实现来定义TemporalAdjusters

TemporalAdjuster ta = TemporalAdjusters.lastInMonth( dow ) ;

几个月。对于每个,确定第一个星期一。使用TemporalAdjuster类中的TemporalAdjusters实现。

YearMonth ym = startYm ;
while( ym.isBefore( stopYm ) ) {
    LocalDate firstOfMonth = ym.atDay( 1 ) ;
    LocalDate ld = firstOfMonth.with( ta ) ;
    lastMondays.add( ld ) ;  // Collect our last-monday-of-this-month. 
    // Set up the next loop.
    ym = ym.plusMonths( 1 ) ;
}

报告。

System.out.println( lastMondays ) ;

看到那个code run live at IdeOne.com

  

[2016-01-25、2016-02-29、2016-03-28、2016-04-25、2016-05-30、2016-06-27、2016-07-25、2016-08- 29,2016-09-26,2016-10-31,2016-11-28,2016-12-26,2017-01-30,2017-02-27,2017-03-27,2017-04-24, 2017-05-29、2017-06-26、2017-07-31、2017-08-28、2017-09-25、2017-10-30、2017-11-27、2017-12-25]

现在,让我们修改该循环,以仅关注当月的最后一天恰好是星期一的情况。

YearMonth ym = startYm;
while ( ym.isBefore( stopYm ) ) {
    LocalDate endOfMonth = ym.atEndOfMonth();
    if ( endOfMonth.getDayOfWeek().equals( dow ) ) {
        lastMondays.add( endOfMonth );  // Collect our last-monday-of-this-month.
    }
    // Set up the next loop.
    ym = ym.plusMonths( 1 );
}

请参阅此code run live at IdeOne.com

  

[2016-02-29,2016-10-31,2017-07-31]

请注意,这些结果与课题中给出的结果不同。我确认这里的信息正确,并且问题的结果不正确。


关于 java.time

java.time框架已内置在Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.DateCalendarSimpleDateFormat

目前位于Joda-Timemaintenance mode项目建议迁移到java.time类。

要了解更多信息,请参见Oracle Tutorial。并在Stack Overflow中搜索许多示例和说明。规格为JSR 310

您可以直接与数据库交换 java.time 对象。使用符合JDBC driver或更高版本的JDBC 4.2。不需要字符串,不需要java.sql.*类。

在哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展了java.time。该项目为将来可能在java.time中添加内容提供了一个试验场。您可能会在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore