首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何解决打印给定年份的所有周五和周六的问题?

如何解决打印给定年份的所有周五和周六的问题?
EN

Stack Overflow用户
提问于 2022-09-27 11:07:33
回答 2查看 97关注 0票数 0

我正试着打印任何一年的所有星期六和星期日。但出于某种原因,该程序不会只打印星期六,也不会打印2022年的星期五。一年来,我尝试过不同的价值观,但除了2022年之外,我仍然没有找到任何价值。我在这里做错了什么?贝娄是密码。

代码语言:javascript
复制
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();
    }
}

波纹管是输出

代码语言:javascript
复制
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
EN

回答 2

Stack Overflow用户

发布于 2022-09-27 23:09:39

tl;dr

使用java.time类、流、lambdas和谓词摘录代码。

代码语言:javascript
复制
this.datesOfYearforDaysOfWeek(
        Year.of( 2023 ) ,
        Set.of( DayOfWeek.SATURDAY , DayOfWeek.SUNDAY )
)
代码语言:javascript
复制
year.atDay( 1 )
        .datesUntil(
                year
                        .plusYears( 1 )
                        .atDay( 1 )
        )
        .filter(
                date -> dows.contains( date.getDayOfWeek() )
        )
        .toList()

详细信息

MC皇帝的回答是正确的和明智的。为了好玩,我将展示一种不同的方法。虽然我还没有测试性能,但可能没有那么有效率。在这里我们使用溪流和兰巴达。

我们使用LocalDate#datesUntil来获取一个LocalDate对象流。注意,datesUntil方法使用半开放逻辑,其中开头是包含的,而结尾是独占的。因此,一年从第一年开始,一直持续到第一年,但不包括第一年。

Year类代表了一年的时间,使代码更加清晰和自文档化。

主要逻辑:

代码语言:javascript
复制
    LocalDate firstOfYear = year.atDay( 1 );
    List < LocalDate > dates =
            firstOfYear
                    .datesUntil( firstOfYear.plusYears( 1 ) )
                    .filter(
                            date -> dows.contains( date.getDayOfWeek() )
                    )
                    .toList();

完整的方法。

代码语言:javascript
复制
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.
}

使用。

代码语言:javascript
复制
List < LocalDate > dates =
        this.datesOfYearforDaysOfWeek(
                Year.of( 2023 ) ,
                Set.of( DayOfWeek.SATURDAY , DayOfWeek.SUNDAY )
        );

跑的时候。

代码语言:javascript
复制
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]

使更紧凑,虽然不一定更好。同样的结果。

代码语言:javascript
复制
    // Logic
    List < LocalDate > dates =
            year.atDay( 1 )
                    .datesUntil(
                            year
                                    .plusYears( 1 )
                                    .atDay( 1 )
                    )
                    .filter(
                            date -> dows.contains( date.getDayOfWeek() )
                    )
                    .toList();

遗嘱执行人服务

您可能希望使用遗嘱执行人服务而不是自己管理线程。

将任务定义为返回所需日期列表的Callable。用所需的年份和星期数来构造对象.

代码语言:javascript
复制
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 ) );
    }
}

示例用法。

代码语言:javascript
复制
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() );

跑的时候。

代码语言:javascript
复制
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

完整的示例代码。

代码语言:javascript
复制
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();
        }
    }
}
票数 2
EN

Stack Overflow用户

发布于 2022-09-27 11:46:05

解释:

如果1月1日是星期六,这意味着周的星期五将是1月1日的前1天,也就是12月31日,当您将下面的字段设置为星期五时,它将值设置为12月31日,并且由于您的时间条件,它不会执行循环。

代码语言:javascript
复制
calendar.set(Calendar.DAY_OF_WEEK, day);

这段代码不适用于边缘情况,也就是说,从星期六开始的任何一年都不会在周五打印。例如2011年、2028年等

以下方法设定为每月的第一个星期五/星期六/任何工作日:

代码语言:javascript
复制
    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);
    }
代码语言:javascript
复制
calendar.set(Calendar.DAY_OF_WEEK, day);
// can be replaced by
setNextAvailableDay(calendar, day)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73866600

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档