【问题标题】:How to get all possible years from the given day, day of the week, and month?如何从给定的日期、星期几和月份中获取所有可能的年份?
【发布时间】:2015-07-10 07:07:39
【问题描述】:

我想获得与特定日期、星期几和月份相关的一组年份。我有可能从这种模式中获得不同的年份。假设日期是 15,月份是八月,一天中的一周是星期二,那么我将如何找到有效的年份?有公式吗?

【问题讨论】:

    标签: date math formula


    【解决方案1】:

    这会完全解决您的问题吗?

    这背后的想法:

    • 从第 0 年的特定日期(8 月 15 日)开始
    • 如果日期在指定的工作日 --> 将其添加到您的列表中
    • 增加 1 年
    • 回到第一格

    (直到达到您指定的 MAX_DATE)

    List<Integer> validYears = new ArrayList<>();
        LocalDate date = LocalDate.of(0, Month.AUGUST, 15);
        while (date.getYear() < 2015) {
            if (date.getDayOfWeek() == DayOfWeek.TUESDAY) {
                validYears.add(date.getYear());
            }
            date = date.plusYears(1);
        }
        validYears.forEach(year -> System.out.println(year));
    

    编辑: 如果您的日期是 2 月 29 日,您应该添加以下代码(因为如果您将 1 年添加到 0000-02-29,它将给您 0001-02-28,从那里您将停留在 28 日)

    if (date.isLeapYear()) { //And date was feb. 29
                date = date.withDayOfMonth(29);
            }
    

    这是一个带有流的版本:

    int day = 29;
    Month month = Month.FEBRUARY;
    List<LocalDate> collect = IntStream.range(0, 2016).filter(year -> day <= LocalDate.of(year, month, 1).lengthOfMonth())
                .mapToObj(year -> LocalDate.of(year, month, day)).filter(date -> date.getDayOfWeek() == DayOfWeek.TUESDAY)
                .collect(Collectors.toList());
    
    collect.forEach((year -> System.out.println(year)));
    

    【讨论】:

      【解决方案2】:

      这是一个简单的公式,您甚至可以在脑海中完成。您可以在此处找到更多信息:How to determine the day of the week, given the month, day and year

      1. 取年份的最后两位数。
      2. 除以 4,丢弃任何分数。
      3. 添加月份中的某一天。
      4. 添加月份键值:JFM AMJ JAS OND 144 025 036 146
      5. 为闰年的一月或二月减去 1。
      6. 对于公历日期,加 0 表示 1900 年,6 表示 2000 年,4 表示 1700 年,2 表示 1800 年;对于其他年份,加或减 400 的倍数。
      7. 对于儒略日期,为 1700 年加 1,每往回一个世纪加 1。
      8. 添加年份的最后两位数。
      9. 除以 7 并取余数。

      【讨论】:

        【解决方案3】:

        这个问题与经典的 Dommsday 算法有关。
        一种简单的计算方法是 Kraitchik 方法。

        Kraitchik 方法 -
        w = d + m + c + y mod 7,
        其中 w 是星期几(从周日的 1 开始向上计数,而不是 Gauss 版本中的 0);
        d、m、c 和 y 是取决于日、月和年的数字,如下表所示:

        Month   1   2   3   4   5   6   7   8   9   10  11  12  
        m       1   4   3   6   1   4   6   2   5   0   3   5   
        

        对于公历,取一年中的世纪(例如,1986 年是 1900 年,2014 年是 2000 年)。
        [世纪/100] 模组 4:0 1 2 3
        c: 0 5 3 1

        对于儒略历,
        [世纪/100] 模式 7:0 1 2 3 4 5 6
        c: 5 4 3 2 1 0 6

        最后,从这个表中得到年份编号(一月或二月的日期减去1):
        y 年的最后两位数字
        00 06 17 23 28 34 45 51 56 62 73 79 84 90 0 01 07 12 18 29 35 40 46 57 63 68 74 85 91 96 1 02 13 19 24 30 41 47 52 58 69 75 80 86 97 2 03 08 14 25 31 36 42 53 59 64 70 81 87 92 98 3 09 15 20 26 37 43 48 54 65 71 76 82 93 99 4 04 10 21 27 32 38 49 55 60 66 77 83 88 94 5 05 11 16 22 33 39 44 50 61 67 72 78 89 95 6

        就是这样。您可以从维基百科获得更多背景详细信息

        【讨论】:

        • 我看不懂那个表。也许移动应用程序中的格式丢失了。如果没有,您能详细说明吗?
        • 有关此主题的详细信息可在en.wikipedia.org/wiki/Determination_of_the_day_of_the_week 获得。在您的特定情况下,您需要进行修改,因为您需要查找年份。或许也可以循环运行几个世纪。
        【解决方案4】:

        这是 Java 8 中使用 LocalDate 解析器为您完成工作的一种方式。当我有一堆没有年份但要么是当前年份要么是下一个年份的日期时,我使用了它的修改版本。

            String dateString = "Mon Dec 23";
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("E MMM d yyyy");
            Integer startYear = 2000;
            Integer endYear = 3000;
        
            List<Integer> validYears = new ArrayList<>();
            for(int i = startYear; i <= endYear; i++){
              try{
                LocalDate localDate = LocalDate.parse(dateString + " " + i, formatter);
                validYears.add(localDate.getYear());
              } catch (Exception e){
                //Years that are not valid
              }
            }
        
            for(Integer year: validYears){
              System.out.println(year);
            }
        

        【讨论】:

          猜你喜欢
          • 2021-12-16
          • 2022-01-21
          • 1970-01-01
          • 1970-01-01
          • 2019-06-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-07-17
          相关资源
          最近更新 更多