我正试着打印任何一年的所有星期六和星期日。但出于某种原因,该程序不会只打印星期六,也不会打印2022年的星期五。一年来,我尝试过不同的价值观,但除了2022年之外,我仍然没有找到任何价值。我在这里做错了什么?贝娄是密码。
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Scanner;
public class JavaDayFinder extends Thread {
int day;
int year;
JavaDayFinder(int day, int year) {
this.day = day;
this.year = year;
}
@Override
public void run() {
Calendar calendar = new GregorianCalendar();
calendar.set(year, Calendar.JANUARY, 1);
calendar.getTime();
calendar.set(Calendar.DAY_OF_WEEK, day);
calendar.getTime();
while (calendar.get(Calendar.YEAR) == year) {
System.out.println(calendar.getTime());
calendar.add(Calendar.DAY_OF_MONTH, 7);
try {
Thread.sleep(250);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
public static void main(String[] args) {
System.out.println("This program prints all the common holidays (Fridays & Saturdays) of any given year.");
System.out.print("Please input the year of which you want to know the holidays: ");
Scanner scan = new Scanner(System.in);
int year = scan.nextInt();
System.out.println("Given year : " + year);
System.out.println();
JavaDayFinder friday = new JavaDayFinder(6, year);
JavaDayFinder saturday = new JavaDayFinder(7, year);
friday.start();
saturday.start();
}
}波纹管是输出
This program prints all the common holidays (Fridays & Saturdays) of any given year.
Please input the year of which you want to know the holidays: 2022
Given year : 2022
Sat Jan 01 17:05:56 BDT 2022
Sat Jan 08 17:05:56 BDT 2022
Sat Jan 15 17:05:56 BDT 2022
Sat Jan 22 17:05:56 BDT 2022
Sat Jan 29 17:05:56 BDT 2022
Sat Feb 05 17:05:56 BDT 2022
Sat Feb 12 17:05:56 BDT 2022
Sat Feb 19 17:05:56 BDT 2022
Sat Feb 26 17:05:56 BDT 2022
Sat Mar 05 17:05:56 BDT 2022
Sat Mar 12 17:05:56 BDT 2022
Sat Mar 19 17:05:56 BDT 2022
Sat Mar 26 17:05:56 BDT 2022
Sat Apr 02 17:05:56 BDT 2022
Sat Apr 09 17:05:56 BDT 2022
Sat Apr 16 17:05:56 BDT 2022
Sat Apr 23 17:05:56 BDT 2022
Sat Apr 30 17:05:56 BDT 2022
Sat May 07 17:05:56 BDT 2022
Sat May 14 17:05:56 BDT 2022
Sat May 21 17:05:56 BDT 2022
Sat May 28 17:05:56 BDT 2022
Sat Jun 04 17:05:56 BDT 2022
Sat Jun 11 17:05:56 BDT 2022
Sat Jun 18 17:05:56 BDT 2022
Sat Jun 25 17:05:56 BDT 2022
Sat Jul 02 17:05:56 BDT 2022
Sat Jul 09 17:05:56 BDT 2022
Sat Jul 16 17:05:56 BDT 2022
Sat Jul 23 17:05:56 BDT 2022
Sat Jul 30 17:05:56 BDT 2022
Sat Aug 06 17:05:56 BDT 2022
Sat Aug 13 17:05:56 BDT 2022
Sat Aug 20 17:05:56 BDT 2022
Sat Aug 27 17:05:56 BDT 2022
Sat Sep 03 17:05:56 BDT 2022
Sat Sep 10 17:05:56 BDT 2022
Sat Sep 17 17:05:56 BDT 2022
Sat Sep 24 17:05:56 BDT 2022
Sat Oct 01 17:05:56 BDT 2022
Sat Oct 08 17:05:56 BDT 2022
Sat Oct 15 17:05:56 BDT 2022
Sat Oct 22 17:05:56 BDT 2022
Sat Oct 29 17:05:56 BDT 2022
Sat Nov 05 17:05:56 BDT 2022
Sat Nov 12 17:05:56 BDT 2022
Sat Nov 19 17:05:56 BDT 2022
Sat Nov 26 17:05:56 BDT 2022
Sat Dec 03 17:05:56 BDT 2022
Sat Dec 10 17:05:56 BDT 2022
Sat Dec 17 17:05:56 BDT 2022
Sat Dec 24 17:05:56 BDT 2022
Sat Dec 31 17:05:56 BDT 2022
Process finished with exit code 0发布于 2022-09-27 23:09:39
tl;dr
使用java.time类、流、lambdas和谓词摘录代码。
this.datesOfYearforDaysOfWeek(
Year.of( 2023 ) ,
Set.of( DayOfWeek.SATURDAY , DayOfWeek.SUNDAY )
)year.atDay( 1 )
.datesUntil(
year
.plusYears( 1 )
.atDay( 1 )
)
.filter(
date -> dows.contains( date.getDayOfWeek() )
)
.toList()详细信息
MC皇帝的回答是正确的和明智的。为了好玩,我将展示一种不同的方法。虽然我还没有测试性能,但可能没有那么有效率。在这里我们使用溪流和兰巴达。
我们使用LocalDate#datesUntil来获取一个LocalDate对象流。注意,datesUntil方法使用半开放逻辑,其中开头是包含的,而结尾是独占的。因此,一年从第一年开始,一直持续到第一年,但不包括第一年。
Year类代表了一年的时间,使代码更加清晰和自文档化。
主要逻辑:
LocalDate firstOfYear = year.atDay( 1 );
List < LocalDate > dates =
firstOfYear
.datesUntil( firstOfYear.plusYears( 1 ) )
.filter(
date -> dows.contains( date.getDayOfWeek() )
)
.toList();完整的方法。
List < LocalDate > datesOfYearforDaysOfWeek ( final Year year , final Set < DayOfWeek > dows )
{
// Validate inputs.
Objects.requireNonNull( year );
Objects.requireNonNull( dows );
if ( dows.isEmpty() ) { throw new IllegalArgumentException( "Days of week is empty." ); }
// Logic
LocalDate firstOfYear = year.atDay( 1 );
List < LocalDate > dates =
firstOfYear
.datesUntil( firstOfYear.plusYears( 1 ) )
.filter(
date -> dows.contains( date.getDayOfWeek() )
)
.toList();
// Result.
return List.copyOf( dates ); // Effectively a no-op if already an immutable list.
}使用。
List < LocalDate > dates =
this.datesOfYearforDaysOfWeek(
Year.of( 2023 ) ,
Set.of( DayOfWeek.SATURDAY , DayOfWeek.SUNDAY )
);跑的时候。
dates.toString() = [2023-01-01, 2023-01-07, 2023-01-08, 2023-01-14, 2023-01-15, 2023-01-21, 2023-01-22, 2023-01-28, 2023-01-29, 2023-02-04, 2023-02-05, 2023-02-11, 2023-02-12, 2023-02-18, 2023-02-19, 2023-02-25, 2023-02-26, 2023-03-04, 2023-03-05, 2023-03-11, 2023-03-12, 2023-03-18, 2023-03-19, 2023-03-25, 2023-03-26, 2023-04-01, 2023-04-02, 2023-04-08, 2023-04-09, 2023-04-15, 2023-04-16, 2023-04-22, 2023-04-23, 2023-04-29, 2023-04-30, 2023-05-06, 2023-05-07, 2023-05-13, 2023-05-14, 2023-05-20, 2023-05-21, 2023-05-27, 2023-05-28, 2023-06-03, 2023-06-04, 2023-06-10, 2023-06-11, 2023-06-17, 2023-06-18, 2023-06-24, 2023-06-25, 2023-07-01, 2023-07-02, 2023-07-08, 2023-07-09, 2023-07-15, 2023-07-16, 2023-07-22, 2023-07-23, 2023-07-29, 2023-07-30, 2023-08-05, 2023-08-06, 2023-08-12, 2023-08-13, 2023-08-19, 2023-08-20, 2023-08-26, 2023-08-27, 2023-09-02, 2023-09-03, 2023-09-09, 2023-09-10, 2023-09-16, 2023-09-17, 2023-09-23, 2023-09-24, 2023-09-30, 2023-10-01, 2023-10-07, 2023-10-08, 2023-10-14, 2023-10-15, 2023-10-21, 2023-10-22, 2023-10-28, 2023-10-29, 2023-11-04, 2023-11-05, 2023-11-11, 2023-11-12, 2023-11-18, 2023-11-19, 2023-11-25, 2023-11-26, 2023-12-02, 2023-12-03, 2023-12-09, 2023-12-10, 2023-12-16, 2023-12-17, 2023-12-23, 2023-12-24, 2023-12-30, 2023-12-31]使更紧凑,虽然不一定更好。同样的结果。
// Logic
List < LocalDate > dates =
year.atDay( 1 )
.datesUntil(
year
.plusYears( 1 )
.atDay( 1 )
)
.filter(
date -> dows.contains( date.getDayOfWeek() )
)
.toList();遗嘱执行人服务
您可能希望使用遗嘱执行人服务而不是自己管理线程。
将任务定义为返回所需日期列表的Callable。用所需的年份和星期数来构造对象.
class DatesForDayOfWeekTask implements Callable < List < LocalDate > >
{
Year year;
DayOfWeek dow;
public DatesForDayOfWeekTask ( final Year year , final DayOfWeek dow )
{
this.year = year;
this.dow = dow;
}
@Override
public List < LocalDate > call ( ) throws Exception
{
return datesOfYearforDaysOfWeek( this.year , Set.of( this.dow ) );
}
}示例用法。
System.out.println( "INFO - Demo started. " + Instant.now() );
ExecutorService executorService = Executors.newCachedThreadPool();
DatesForDayOfWeekTask saturdayTask = new DatesForDayOfWeekTask( Year.of( 2023 ) , DayOfWeek.SATURDAY );
DatesForDayOfWeekTask sundayTask = new DatesForDayOfWeekTask( Year.of( 2023 ) , DayOfWeek.SUNDAY );
Future < List < LocalDate > > saturdayFuture = executorService.submit( saturdayTask );
Future < List < LocalDate > > sundayFuture = executorService.submit( sundayTask );
System.out.println( "INFO Tasks submitted. Please wait. " + Instant.now() );
try { Thread.sleep( Duration.ofSeconds( 10 ).toMillis() ); } catch ( InterruptedException e ) { throw new RuntimeException( e ); }
this.shutdownAndAwaitTermination( executorService );
try
{
System.out.println( "saturdayFuture.get() = " + saturdayFuture.get() );
System.out.println( "sundayFuture.get() = " + sundayFuture.get() );
}
catch ( InterruptedException e ) { throw new RuntimeException( e ); }
catch ( ExecutionException e ) { throw new RuntimeException( e ); }
System.out.println( "INFO - Demo ended. " + Instant.now() );跑的时候。
INFO - Demo started. 2022-09-28T00:38:58.460930Z
INFO Tasks submitted. Please wait. 2022-09-28T00:38:58.469034Z
saturdayFuture.get() = [2023-01-07, 2023-01-14, 2023-01-21, 2023-01-28, 2023-02-04, 2023-02-11, 2023-02-18, 2023-02-25, 2023-03-04, 2023-03-11, 2023-03-18, 2023-03-25, 2023-04-01, 2023-04-08, 2023-04-15, 2023-04-22, 2023-04-29, 2023-05-06, 2023-05-13, 2023-05-20, 2023-05-27, 2023-06-03, 2023-06-10, 2023-06-17, 2023-06-24, 2023-07-01, 2023-07-08, 2023-07-15, 2023-07-22, 2023-07-29, 2023-08-05, 2023-08-12, 2023-08-19, 2023-08-26, 2023-09-02, 2023-09-09, 2023-09-16, 2023-09-23, 2023-09-30, 2023-10-07, 2023-10-14, 2023-10-21, 2023-10-28, 2023-11-04, 2023-11-11, 2023-11-18, 2023-11-25, 2023-12-02, 2023-12-09, 2023-12-16, 2023-12-23, 2023-12-30]
sundayFuture.get() = [2023-01-01, 2023-01-08, 2023-01-15, 2023-01-22, 2023-01-29, 2023-02-05, 2023-02-12, 2023-02-19, 2023-02-26, 2023-03-05, 2023-03-12, 2023-03-19, 2023-03-26, 2023-04-02, 2023-04-09, 2023-04-16, 2023-04-23, 2023-04-30, 2023-05-07, 2023-05-14, 2023-05-21, 2023-05-28, 2023-06-04, 2023-06-11, 2023-06-18, 2023-06-25, 2023-07-02, 2023-07-09, 2023-07-16, 2023-07-23, 2023-07-30, 2023-08-06, 2023-08-13, 2023-08-20, 2023-08-27, 2023-09-03, 2023-09-10, 2023-09-17, 2023-09-24, 2023-10-01, 2023-10-08, 2023-10-15, 2023-10-22, 2023-10-29, 2023-11-05, 2023-11-12, 2023-11-19, 2023-11-26, 2023-12-03, 2023-12-10, 2023-12-17, 2023-12-24, 2023-12-31]
INFO - Demo ended. 2022-09-28T00:39:08.480522Z完整的示例代码。
package work.basil.example.days;
import java.time.*;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.*;
public class App
{
public static void main ( String[] args )
{
App app = new App();
// app.demo();
app.demoThreaded();
}
private void demo ( )
{
List < LocalDate > dates =
this.datesOfYearforDaysOfWeek(
Year.of( 2023 ) ,
Set.of( DayOfWeek.SATURDAY , DayOfWeek.SUNDAY )
);
System.out.println( "dates.toString() = " + dates );
}
List < LocalDate > datesOfYearforDaysOfWeek ( final Year year , final Set < DayOfWeek > dows )
{
// Validate inputs.
Objects.requireNonNull( year );
Objects.requireNonNull( dows );
if ( dows.isEmpty() ) { throw new IllegalArgumentException( "Days of week is empty." ); }
// Logic
List < LocalDate > dates =
year.atDay( 1 )
.datesUntil(
year
.plusYears( 1 )
.atDay( 1 )
)
.filter(
date -> dows.contains( date.getDayOfWeek() )
)
.toList();
// Result.
return List.copyOf( dates ); // Effectively a no-op if already an immutable list.
}
private void demoThreaded ( )
{
System.out.println( "INFO - Demo started. " + Instant.now() );
ExecutorService executorService = Executors.newCachedThreadPool();
DatesForDayOfWeekTask saturdayTask = new DatesForDayOfWeekTask( Year.of( 2023 ) , DayOfWeek.SATURDAY );
DatesForDayOfWeekTask sundayTask = new DatesForDayOfWeekTask( Year.of( 2023 ) , DayOfWeek.SUNDAY );
Future < List < LocalDate > > saturdayFuture = executorService.submit( saturdayTask );
Future < List < LocalDate > > sundayFuture = executorService.submit( sundayTask );
System.out.println( "INFO Tasks submitted. Please wait. " + Instant.now() );
try { Thread.sleep( Duration.ofSeconds( 10 ).toMillis() ); } catch ( InterruptedException e ) { throw new RuntimeException( e ); }
this.shutdownAndAwaitTermination( executorService );
try
{
System.out.println( "saturdayFuture.get() = " + saturdayFuture.get() );
System.out.println( "sundayFuture.get() = " + sundayFuture.get() );
}
catch ( InterruptedException e ) { throw new RuntimeException( e ); }
catch ( ExecutionException e ) { throw new RuntimeException( e ); }
System.out.println( "INFO - Demo ended. " + Instant.now() );
}
class DatesForDayOfWeekTask implements Callable < List < LocalDate > >
{
Year year;
DayOfWeek dow;
public DatesForDayOfWeekTask ( final Year year , final DayOfWeek dow )
{
this.year = year;
this.dow = dow;
}
@Override
public List < LocalDate > call ( ) throws Exception
{
return datesOfYearforDaysOfWeek( this.year , Set.of( this.dow ) );
}
}
// Boilerplate code taken from `ExecutorService` interface Javadoc, and slightly modified.
private void shutdownAndAwaitTermination ( ExecutorService executorService )
{
executorService.shutdown(); // Disable new tasks from being submitted
try
{
// Wait a while for existing tasks to terminate
if ( ! executorService.awaitTermination( 60 , TimeUnit.SECONDS ) )
{
executorService.shutdownNow(); // Cancel currently executing tasks
// Wait a while for tasks to respond to being cancelled
if ( ! executorService.awaitTermination( 60 , TimeUnit.SECONDS ) )
{ System.err.println( "Pool did not terminate" ); }
}
}
catch ( InterruptedException ex )
{
// (Re-)Cancel if current thread also interrupted
executorService.shutdownNow();
// Preserve interrupt status
Thread.currentThread().interrupt();
}
}
}发布于 2022-09-27 11:46:05
解释:
如果1月1日是星期六,这意味着周的星期五将是1月1日的前1天,也就是12月31日,当您将下面的字段设置为星期五时,它将值设置为12月31日,并且由于您的时间条件,它不会执行循环。
calendar.set(Calendar.DAY_OF_WEEK, day);这段代码不适用于边缘情况,也就是说,从星期六开始的任何一年都不会在周五打印。例如2011年、2028年等
以下方法设定为每月的第一个星期五/星期六/任何工作日:
private void setNextAvailableDay(Calendar calendar, int day) {
Date currTime = calendar.getTime();
calendar.set(Calendar.DAY_OF_WEEK, day);
if(currTime.after(calendar.getTime()))
calendar.add(Calendar.DAY_OF_MONTH, 7);
}calendar.set(Calendar.DAY_OF_WEEK, day);
// can be replaced by
setNextAvailableDay(calendar, day)https://stackoverflow.com/questions/73866600
复制相似问题