【问题标题】:Question on a program with date and random numbers关于带有日期和随机数的程序的问题
【发布时间】:2021-06-18 14:14:48
【问题描述】:

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

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();
            }
        }
    }
}

【问题讨论】:

  • Random value = new value(); 这不是有效的 Java。发布代码时,请使用 IDE 中的复制/粘贴,不要重新输入代码。也请拨打tour,访问help center 并阅读How to Ask,了解如何有效地使用本网站。
  • 问题是你的do...while循环没有修改value的值。它在循环之前设置,在循环内不会改变。循环唯一要做的就是增加计数器。
  • 顺便说一句,可怕的 DateSimpleDateFormat 类在几年前被 JSR 310 中定义的现代 java.time 类所取代。
  • 我建议你不要使用SimpleDateFormatDate。这些类设计不佳且早已过时,尤其是前者,尤其是出了名的麻烦。而是使用来自java.time, the modern Java date and time APILocalDateDateTimeFormatter
  • 比利·帕克,请不要通过破坏自己的问题来为他人创造更多的工作,这样答案就不再有意义了。如果您想提出新问题,请改为提出新问题。

标签: java date random counter java-time


【解决方案1】:

在 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 将大部分 java.time 功能向后移植到 Java 6 和 7 . 如果您正在为一个 Android 项目工作并且您的 Android API 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaringHow to use ThreeTenABP in Android Project

【讨论】:

  • @billyparker - 为什么要在程序中添加毫秒? - java.util.Date 表示自称为“纪元”的标准基准时间以来的毫秒数,即January 1, 1970, 00:00:00 GMT(或 UTC)。 .nextLong(10000000, millis) 部分生成 long 值。在10000000millis 之间。
  • @billyparker - 有没有办法在不使用时间值和仅使用日期值的情况下做到这一点 - 此解决方案仅基于日期,但为了得出日期从毫秒开始,您需要首先获取可以从中提取日期的日期时间对象。
  • @billyparker - 这还会生成 8 位长的数字吗? - 是的,我错过了这部分。我刚刚更新了我的答案以满足此要求。
  • 如果在该月的前 9 天运行,则没有真正的 8 位数字等于日期。
【解决方案2】:

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-10-12
    • 1970-01-01
    • 2019-11-30
    • 1970-01-01
    • 2022-01-26
    • 1970-01-01
    • 2019-06-27
    • 1970-01-01
    相关资源
    最近更新 更多