在 Java 中获取每月的最后一个星期五

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/76223/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 08:00:06  来源:igfitidea点击:

Get Last Friday of Month in Java

javadatecalendar

提问by Nick Klauer

I am working on a project where the requirement is to have a date calculated as being the last Friday of a given month. I think I have a solution that only uses standard Java, but I was wondering if anyone knew of anything more concise or efficient. Below is what I tested with for this year:

我正在从事一个项目,其中要求将日期计算为给定月份的最后一个星期五。我想我有一个只使用标准 Java 的解决方案,但我想知道是否有人知道更简洁或更高效的方法。以下是我今年测试的内容:

    for (int month = 0; month < 13; month++) {
        GregorianCalendar d = new GregorianCalendar();
        d.set(d.MONTH, month);
        System.out.println("Last Week of Month in " + d.getDisplayName(d.MONTH, Calendar.LONG, Locale.ENGLISH) + ": " + d.getLeastMaximum(d.WEEK_OF_MONTH));
        d.set(d.DAY_OF_WEEK, d.FRIDAY);
        d.set(d.WEEK_OF_MONTH, d.getActualMaximum(d.WEEK_OF_MONTH));
        while (d.get(d.MONTH) > month || d.get(d.MONTH) < month) {
            d.add(d.WEEK_OF_MONTH, -1);
        }
        Date dt = d.getTime();
        System.out.println("Last Friday of Last Week in  " + d.getDisplayName(d.MONTH, Calendar.LONG, Locale.ENGLISH) + ": " + dt.toString());
    }

采纳答案by ColinD

Based on marked23'ssuggestion:

基于marked23的建议:

public Date getLastFriday( int month, int year ) {
   Calendar cal = Calendar.getInstance();
   cal.set( year, month + 1, 1 );
   cal.add( Calendar.DAY_OF_MONTH, -( cal.get( Calendar.DAY_OF_WEEK ) % 7 + 1 ) );
   return cal.getTime();
}

回答by scubabbl

That looks like a perfectly acceptable solution. If that works, use it. That is minimal code and there's no reason to optimize it unless you have to.

这看起来是一个完全可以接受的解决方案。如果有效,请使用它。这是最少的代码,除非必须,否则没有理由对其进行优化。

回答by Binil Thomas

Slightly easier to read, brute-force approach:

稍微容易阅读的蛮力方法:

public int getLastFriday(int month, int year) {
    Calendar cal = Calendar.getInstance();
    cal.set(year, month, 1, 0, 0, 0); // set to first day of the month
    cal.set(Calendar.MILLISECOND, 0);

    int friday = -1;
    while (cal.get(Calendar.MONTH) == month) { 
        if (cal.get(Calendar.DAY_OF_WEEK) == Calendar.FRIDAY) { // is it a friday?
            friday = cal.get(Calendar.DAY_OF_MONTH);
            cal.add(Calendar.DAY_OF_MONTH, 7); // skip 7 days
        } else {
            cal.add(Calendar.DAY_OF_MONTH, 1); // skip 1 day
        }
    }
    return friday;
}

回答by Hans Doggen

I would use a library like Jodatime. It has a very useful API and it uses normal month numbers. And best of all, it is thread safe.

我会使用像Jodatime这样的库。它有一个非常有用的 API,它使用正常的月份数字。最重要的是,它是线程安全的。

I think that you can have a solution with (but possibly not the shortest, but certainly more readable):

我认为你可以有一个解决方案(但可能不是最短的,但肯定更具可读性):

DateTime now = new DateTime();      
DateTime dt = now.dayOfMonth().withMaximumValue().withDayOfWeek(DateTimeConstants.FRIDAY);
if (dt.getMonthOfYear() != now.getMonthOfYear()) {
  dt = dt.minusDays(7);
}       
System.out.println(dt);

回答by Hans Doggen

You never need to loop to find this out. For determining the "last Friday" date for this month, start with the first day of next month. Subtract the appropriate number of days depending on what (numerical) day of the week the first day of the month falls on. There's your "last Friday." I'm pretty sure it can be boiled down to a longish one-liner, but I'm not a java dev. So I'll leave that to someone else.

你永远不需要循环来找出这个。要确定本月的“最后一个星期五”日期,请从下个月的第一天开始。根据一个月的第一天所在的星期几(数字)减去适当的天数。这是你的“最后一个星期五”。我很确定它可以归结为一个较长的单行代码,但我不是 Java 开发人员。所以我会把它留给别人。

回答by Benno Richters

Though I agree with scubabbl, here is a version without an inner while.

虽然我同意 scubabbl,但这里有一个没有内部时间的版本。

int year = 2008;
for (int m = Calendar.JANUARY; m <= Calendar.DECEMBER; m++) {
    Calendar cal = new GregorianCalendar(year, m, 1);
    cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
    int diff = Calendar.FRIDAY - cal.get(Calendar.DAY_OF_WEEK);
    if (diff > 0) {
        diff -= 7;
    }
    cal.add(Calendar.DAY_OF_MONTH, diff);
    System.out.println(cal.getTime());
}

回答by Adam Davis

You need to know two things - the number of days in the month, and the weekday the first of the month falls on.

您需要知道两件事 - 一个月中的天数,以及一个月的第一天所在的工作日。

If the first day of the month is a

如果一个月的第一天是

  • Sunday, then the last Friday is alwaysthe 27th.
  • Monday, then the last Friday is alwaysthe 26th.
  • Tuesday, then the last Friday is alwaysthe 25th.
  • Wednesday, then the last Friday is the 24th, unless there are 31 days in the month, then it's the 31st
  • Thursday, then the last Friday is the 23rd, unless there are 30 days or more in the month, then it's the 30th.
  • Friday, then the last Friday is the 22nd, unless there are 29 days or more in the month, then it's the 29th.
  • Saturday, then the last Friday is alwaysthe 28th.
  • 星期天,那么最后一个星期五总是27 号。
  • 星期一,然后最后一个星期五总是26 号。
  • 星期二,那么最后一个星期五总是25 号。
  • 星期三,那么最后一个星期五是24号,除非这个月有31天,那就是31号
  • 星期四,那么最后一个星期五是 23 号,除非这个月有 30 天或更多,那么就是 30 号。
  • 星期五,那么最后一个星期五就是22号,除非这个月有29天或者更多,那么就是29号。
  • 星期六,那么最后一个星期五总是28 号。

There are only three special cases. A single switch statement and three if statements (or ternary operators if you like every case to have a single line...)

只有三种特殊情况。一个 switch 语句和三个 if 语句(或者三元运算符,如果你喜欢每个 case 都有一行......)

Work it out on paper. Don't need any special libraries, functions, julian conversions, etc (well, except to get the weekday the 1st falls on, and maybe the number of days that month... )

在纸上解决。不需要任何特殊的库、函数、朱利安转换等(嗯,除了要得到第一个工作日,也许是那个月的天数......)

Aaron implemented it in Java.

Aaron 用 Ja​​va 实现了它。

-Adam

-亚当

回答by Aaron

code for Adam Davis's algorithm

亚当戴维斯算法的代码

public static int getLastFriday(int month, int year)
{
Calendar cal = Calendar.getInstance();
cal.set(year, month, 1, 0, 0, 0); // set to first day of the month
cal.set(Calendar.MILLISECOND, 0);

int firstDay = cal.get(Calendar.DAY_OF_WEEK);
int daysOfMonth = cal.getMaximum(Calendar.DAY_OF_MONTH);

switch (firstDay)
{
    case Calendar.SUNDAY :
        return 27;
    case Calendar.MONDAY :
        return 26;
    case Calendar.TUESDAY :
        return 25;
    case Calendar.WEDNESDAY :
        if (daysOfMonth == 31) return 31;
        return 24;
    case Calendar.THURSDAY :
        if (daysOfMonth >= 30) return 30;
        return 23;
    case Calendar.FRIDAY :
        if (daysOfMonth >= 29) return 29;
        return 22;
    case Calendar.SATURDAY :
        return 28;
}
throw new RuntimeException("what day of the month?");
}}

回答by Aaron

Hope this helps..

希望这可以帮助..

public static void getSundaysInThisMonth(int monthNumber, int yearNumber){
    //int year =2009;
    //int dayOfWeek = Calendar.SUNDAY;
    // instantiate Calender and set to first Sunday of 2009
    Calendar cal = new GregorianCalendar();
    cal.set(Calendar.MONTH, monthNumber-1);
    cal.set(Calendar.YEAR, yearNumber);
    cal.set(Calendar.DATE, 1);
    int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
    int dateOfWeek = cal.get(Calendar.DATE);
    while (dayOfWeek  != Calendar.SUNDAY) {
       cal.set(Calendar.DATE, ++dateOfWeek);
       dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
      }
    cal.set(Calendar.DATE, dateOfWeek);

    int i = 1;
    while (cal.get(Calendar.YEAR) == yearNumber && cal.get(Calendar.MONTH)==monthNumber-1)
    {
            System.out.println("Sunday " + " " + i + ": " + cal.get(Calendar.DAY_OF_MONTH));
            cal.add(Calendar.DAY_OF_MONTH, 7);
            i++;
    }

  }
  public static void main(String args[]){
    getSundaysInThisMonth(1,2009);
  }

回答by Aaron

Let Calendar.class do its magic for you ;)

让 Calendar.class 为您施展魔法;)

pCal.set(GregorianCalendar.DAY_OF_WEEK,Calendar.FRIDAY);
pCal.set(GregorianCalendar.DAY_OF_WEEK_IN_MONTH, -1);