关于日期:使用Java获取本月的最后一个星期五

关于日期:使用Java获取本月的最后一个星期五

Get Last Friday of Month in Java

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

1
2
3
4
5
6
7
8
9
10
11
12
    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());
    }

让Calendar.class为您做魔术吧;)

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

根据marked23的建议:

1
2
3
4
5
6
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();
}

java.time

使用Java 8和更高版本中内置的java.time库,您可以使用TemporalAdjusters.lastInMonth

1
2
val now = LocalDate.now()
val lastInMonth = now.with(TemporalAdjusters.lastInMonth(DayOfWeek.FRIDAY))

您可以从DayOfWeek枚举中选择任意一天。

如果您需要添加时间信息,则可以使用任何可用的LocalDateLocalDateTime转换,例如

1
lastFriday.atStartOfDay() // e.g. 2015-11-27T00:00

您无需循环就可以找到答案。要确定本月的"最后星期五"日期,请从下个月的第一天开始。减去适当的天数,具体取决于该月的第一天是星期几(数字)。有你的"上周五"。我很确定它可以简化为冗长的单行代码,但是我不是Java开发人员。所以我将其留给其他人。


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

我认为您可以采用以下解决方案(但可能不是最短的解决方案,但肯定更具可读性):

1
2
3
4
5
6
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);

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

如果该月的第一天是

  • 星期日,然后最后一个星期五始终是27日。
  • 星期一,然后最后一个星期五始终是26日。
  • 星期二,那么最后一个星期五始终是25日。
  • 星期三,然后最后一个星期五是第24个,除非一个月中有31天,那么它是第31个
  • 星期四,然后最后一个星期五是23日,除非一个月中有30天或更多,则为30日。
  • 星期五,然后最后一个星期五是22日,除非一个月中有29天或更多,则它是29日。
  • 星期六,然后最后一个星期五始终是28日。

只有三种特殊情况。一个switch语句和三个if语句(如果您希望每种情况都只有一行,则为三元运算符...)

在纸上解决。不需要任何特殊的库,函数,julian转换等(嗯,除了获得1日的工作日,还有该月的天数...)

Aaron用Java实现了它。

-亚当


亚当·戴维斯算法的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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?");
}}

以下是获取每月的最后一个星期五或每周几的方法:

1
2
3
4
5
Calendar thisMonth = Calendar.getInstance();
dayOfWeek = Calendar.FRIDAY; // or whatever
thisMonth.set(Calendar.WEEK_OF_MONTH, thisMonth.getActualMaximum(Calendar.WEEK_OF_MONTH);;
thisMonth.set(Calendar.DAY_OF_WEEK, dayOfWeek);
int lastDay = thisMonth.get(Calendar.DAY_OF_MONTH); // this should be it.

在Java 8中,我们可以简单地做到这一点:

1
2
3
4
LocalDate lastFridayOfMonth = LocalDate
                                    .now()
                                    .with(lastDayOfMonth())
                                    .with(previous(DayOfWeek.FRIDAY));

尽管我同意scubabbl,但这是一个没有时间的版本。

1
2
3
4
5
6
7
8
9
10
11
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());
}

下面的节目是每个月的最后一个星期五。它可用于获取任何月份中星期几的最后一天。变量offset=0表示当前月份(系统日期),offset = 1表示下个月,依此类推。 getLastFridayofMonth(int offset)方法将返回最后一个星期五。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import java.text.SimpleDateFormat;
import java.util.Calendar;

public class LastFriday {

  public static Calendar getLastFriday(Calendar cal,int offset){
    int dayofweek;//1-Sunday,2-Monday so on....
    cal.set(Calendar.MONTH,cal.get(Calendar.MONTH)+offset);
    cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH)); //set calendar to last day of month
    dayofweek=cal.get(Calendar.DAY_OF_WEEK); //get the day of the week for last day of month set above,1-sunday,2-monday etc
    if(dayofweek<Calendar.FRIDAY)  //Calendar.FRIDAY will return integer value =5
      cal.set(Calendar.DAY_OF_MONTH, cal.get(Calendar.DAY_OF_MONTH)-7+Calendar.FRIDAY-dayofweek);
    else
      cal.set(Calendar.DAY_OF_MONTH, cal.get(Calendar.DAY_OF_MONTH)+Calendar.FRIDAY-dayofweek);

    return cal;
  }

  public static String  getLastFridayofMonth(int offset) { //offset=0 mean current month
    final String DATE_FORMAT_NOW ="dd-MMM-yyyy";
    Calendar cal = Calendar.getInstance();
    SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT_NOW);
    cal=getLastFriday(cal,offset);
    return sdf.format(cal.getTime());

  }

  public static void main(String[] args) {
    System.out.println(getLastFridayofMonth(0)); //0 = current month
    System.out.println(getLastFridayofMonth(1));//1=next month
    System.out.println(getLastFridayofMonth(2));//2=month after next month
  }

}

稍微简单易读的暴力方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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;
}

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


1
2
3
4
5
6
7
public static int lastSundayDate()
{
    Calendar cal = getCalendarInstance();
    cal.setTime(new Date(getUTCTimeMillis()));
    cal.set( Calendar.DAY_OF_MONTH , 25 );
    return (25 + 8 - (cal.get(Calendar.DAY_OF_WEEK) != Calendar.SUNDAY ? cal.get(Calendar.DAY_OF_WEEK) : 8));
}

希望这可以帮助..

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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);
  }

1
2
3
4
5
6
7
public static Calendar getNthDow(int month, int year, int dayOfWeek, int n) {
    Calendar cal = Calendar.getInstance();
    cal.set(year, month, 1);
    cal.set(Calendar.DAY_OF_WEEK, dayOfWeek);
    cal.set(Calendar.DAY_OF_WEEK_IN_MONTH, n);
    return (cal.get(Calendar.MONTH) == month) && (cal.get(Calendar.YEAR) == year) ? cal : null;
}


推荐阅读

    linux命令解决方案?

    linux命令解决方案?,系统,管理,数据,电子,工作,电脑,软件,情况,不了,档案,lin

    linux中日期相关命令?

    linux中日期相关命令?,时间,系统,信息,命令,代码,服务,工作,工具,终端,时分,l

    linux设日期时间命令?

    linux设日期时间命令?,时间,系统,命令,国家,环境,数据,电脑,标准,信息,大陆,l

    linux使用命令的方法?

    linux使用命令的方法?,系统,信息,工具,标准,数据,命令,左下角,目录,文件夹,

    linux系统改日期命令?

    linux系统改日期命令?,时间,系统,信息,命令,终端,时分,窗口,操作系统,一下

    linux命令日期修改?

    linux命令日期修改?,时间,系统,电脑,信息,命令,标准,文件,终端,日期,时分,LIN

    linux命令创建项目组?

    linux命令创建项目组?,管理,密码,项目,命令,系统,位置,文件,用户组,用户,文

    linux切换日期命令?

    linux切换日期命令?,时间,系统,信息,命令,城市,终端,时分,日期,窗口,操作系

    复制项目的linux命令?

    复制项目的linux命令?,系统,项目,文件,命令,目录,源文件,语法,选项,目标,功

    linux设置日期命令?

    linux设置日期命令?,时间,系统,标准,命令,信息,大陆,国家,日期,时钟,时区,详

    linux命令项目部署?

    linux命令项目部署?,项目,服务,环境,软件,系统,代理,管理,统一,做好,业务,怎

    linux部署项目的命令?

    linux部署项目的命令?,项目,系统,设备,环境,工作,基础,传播,信息,标准,代码,L

    linux项目常用命令?

    linux项目常用命令?,工作,地址,系统,信息,管理,项目,命令,目录,标准,网络,lin

    linux项目更新命令?

    linux项目更新命令?,系统,信息,网络,地址,网站,通信,管理,时间,项目,命令,lin

    启动项目命令linux?

    启动项目命令linux?,工作,经理,产品,技术,地址,数字,系统,项目,命令,信息,怎

    linux修改日期命令?

    linux修改日期命令?,时间,系统,命令,信息,工具,工作,服务,代码,日期,终端,lin

    linux编译项目的命令?

    linux编译项目的命令?,系统,工作,地址,软件,工具,信息,代码,项目,命令,环境,l

    linux打印日期命令?

    linux打印日期命令?,时间,系统,工作,命令,标准,环境,档案,信息,设备,位置,Lin

    linux基本命令日期?

    linux基本命令日期?,时间,系统,命令,管理,工作,网络,工具,基础,标准,环境,详

    项目linux常用命令?

    项目linux常用命令?,工作,地址,系统,管理,设备,信息,项目,命令,目录,标准,lin