关于带有日期和随机数的程序的问题

Question on a program with date and random numbers

我正在尝试创建一个生成随机数的程序。当生成的随机数与当前日期匹配时,它会打印一个计数器,记录它进行了多少次尝试。日期格式为ddMMyyyy,生成的随机数为8位。最后它打印日期和计数五次。这是我到目前为止所拥有的,但它从来没有 returns 输出。

import java.util.Random;
import java.util.Date;
import java.text.*;

public class Program1 {

    public static void main(String[] args) {

        Date date = new Date();
        Random value = new Random();
        int x = value.nextInt();

        int counter = 0;

        do {
            counter++;
        } while(!date.equals(value));

        if (date.equals(value)){
            for(int i = 1; i < 6; i++) {
                SimpleDateFormat sdf = new SimpleDateFormat ("ddMMyyyy");
                System.out.println("The date is " + sdf.format(date) + "!");
                System.out.println("The Count is: " + counter);
                System.out.println();
            }
        }
    }
}

获取从纪元开始的 0 到毫秒数范围内的 long 数字,并应用格式化程序以获取所需格式的日期字符串。然后将它与今天的日期字符串进行比较。

演示:

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Objects;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;

class Main {
    public static void main(String[] args) {
        Date now = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("ddMMyyyy");
        String strToday = sdf.format(now);
        int counter = 0;

        while (true) {
            // Instantiate Date with minutes of 8 digits
            Date date = new Date(TimeUnit.MILLISECONDS
                    .convert(ThreadLocalRandom.current().nextLong(10000000, 100000000), TimeUnit.MINUTES));
            String strDate = sdf.format(date);
            if (Objects.equals(strToday, strDate)) {
                for (int i = 1; i < 6; i++) {
                    System.out.println("The date is " + strDate + "!");
                    System.out.println("The Count is: " + counter);
                    System.out.println();
                }
                break;
            } else {
                counter++;
            }
        }
    }
}

样本运行:

The date is 21032021!
The Count is: 33263

The date is 21032021!
The Count is: 33263

The date is 21032021!
The Count is: 33263

The date is 21032021!
The Count is: 33263

The date is 21032021!
The Count is: 33263

请注意 java.util 日期时间 API 及其格式 API、SimpleDateFormat 已过时且容易出错。建议完全停止使用它们并切换到 modern date-time API.*

使用现代日期时间 API:

import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
import java.util.Objects;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;

class Main {
    public static void main(String[] args) {
        // Change the ZoneId as applicable e.g. ZoneId.of("Europe/London")
        ZoneId zoneId = ZoneId.systemDefault();

        ZonedDateTime now = ZonedDateTime.now(zoneId);
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("ddMMuuuu", Locale.ENGLISH);
        String strToday = dtf.format(now);
        int counter = 0;

        while (true) {
            // Instantiate Date with minutes of 8 digits
            LocalDate date = Instant
                    .ofEpochMilli(TimeUnit.MILLISECONDS
                            .convert(ThreadLocalRandom.current().nextLong(10000000, 100000000), TimeUnit.MINUTES))
                    .atZone(zoneId).toLocalDate();
            String strDate = dtf.format(date);
            if (Objects.equals(strToday, strDate)) {
                for (int i = 1; i < 6; i++) {
                    System.out.println("The date is " + strDate + "!");
                    System.out.println("The Count is: " + counter);
                    System.out.println();
                }
                break;
            } else {
                counter++;
            }
        }
    }
}

样本运行:

The date is 21032021!
The Count is: 9097

The date is 21032021!
The Count is: 9097

The date is 21032021!
The Count is: 9097

The date is 21032021!
The Count is: 9097

The date is 21032021!
The Count is: 9097

* 无论出于何种原因,如果您必须坚持Java 6 或Java 7,您可以使用ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and

除了使用早已过时且出了名的麻烦 类 DateSimpleDateFormat 之外,您的程序中还有一些错误。

  1. 正如 printf 在评论中指出的那样,在您的 do-while 循环中,您既没有修改 date 也没有修改 value。因此,如果它们在循环之前不相等,它们将永远不会相等,并且您的循环将无限期地 运行。
  2. datevalue 永远不会 相等。 date 是一个 java.util.Datevalue 是一个 RandomDate 不能等于 Random。 Java 的一个令人困惑的特征是在语法上允许比较它们。一个好的 IDE 或像 SpotBugs 这样的代码分析工具应该警告你它不太可能做你想做的事。
  3. int 溢出:value.nextInt() 可以生成超过 40 亿个可能值,从 Integer.MIN_VALUEInteger.MAX_VALUE。因此,您的随机数生成器需要一段时间才能达到正确的值。因此,您的计数有时会溢出 int 可以容纳的值,最多 Integer.MAX_VALUE 或略高于 20 亿。
  4. 如果循环结束(在纠正错误 1. 和 2. 之后),我们已经知道循环条件为假。所以你不需要用 if 语句再次测试它。意思是:if 语句是多余的。你可能会争辩说它也没有害处,但它确实有害:它混淆了 reader.

避免 DateSimpleDateFormat 的解决方案在 Arvind Kumar Avinash 的答案的后半部分。 1.、2. 和 4. 的解决方案也在其他答案的代码中。 3. 的解决方案是使用 long 作为计数器。