【问题标题】:Check if the time is within the min and max range检查时间是否在最小和最大范围内
【发布时间】:2018-06-22 06:35:42
【问题描述】:

我不知道这里发生了什么:如果当前时间在给定范围之间,我需要返回 true,例如:现在是 15:45:00 并且在 12:00:00(分钟)和 18 之间: 00:00(max),但是这个方法做错了:

private boolean verifyIfInside(String max, String min){
    try {
        DateFormat dateFormat = new SimpleDateFormat ("HH:mm:ss");

        Date date = new Date();

        String hour1 = min;
        String hour2 = max;
        String newHour = dateFormat.format(date);

        Date minHour, maxHour, nowHour;
        minHour = dateFormat.parse(hora1);
        maxHour = dateFormat.parse(hora2);
        nowHour = dateFormat.parse(newHour );

        if ((minHour.compareTo(nowHour) <= 0) && (maxHour.compareTo(nowHour) >= 0)){
            return true;
        } else {
            return false;
        }
    } catch (ParseException parseException){
        parseException.printStackTrace();
        return false;
    }
}

【问题讨论】:

  • 使用 Date.before()Date.after() 而不是将时间转换为字符串并使用字符串比较。此外,您按此顺序传递max, min,但hour1, hour2 对应于min, max。您是否以正确的顺序传递参数?
  • hour1 可能是 - 对我们来说 - 翻译成 hora1 更进一步。事实上,参数被定义为(max, min) 有点违反直觉。
  • 您使用早已过时的课程DateFormatSimpleDateFormatDate 有什么特别的原因吗?我建议您使用java.time, the modern Java date and time API,而不是那种麻烦。使用起来感觉好多了。

标签: java date time datetime-comparison


【解决方案1】:

建议的修改可以正常工作:

  • 颠倒最小和最大参数。
  • 使用.before().after() 比较当前小时是否在最小小时之后和最大小时之前。
  • 要包含您可以使用的最小/最大时间界限:!nowHour.after(maxHour) &amp;&amp; !nowHour.before(minHour);
  • 要排除最小/最大时间界限,请改用:nowHour.after(minHour) &amp;&amp; nowHour.before(maxHour);
  • 如果您受限于较旧版本的 java,请考虑按照 @Basil Bourque 的建议使用适当的 java.time ThreeTen-Backport 项目。否则,请使用 Java 8+ 中的最新时间 API。

代码:

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class scratch_21 {
    public static void main(String[] args) {
        System.out.println(verifyIfInside("14:00:00", "14:15:00"));
    }

    private static boolean verifyIfInside(String min, String max) {
        try {
            DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");

            Date date = new Date();

            String hora1 = min;
            String hora2 = max;
            String newHour = dateFormat.format(date);

            Date minHour, maxHour, nowHour;
            minHour = dateFormat.parse(hora1);
            maxHour = dateFormat.parse(hora2);
            nowHour = dateFormat.parse(newHour);

            return  nowHour.after(minHour) && nowHour.before(maxHour);
        } catch (ParseException parseException) {
            parseException.printStackTrace();
            return false;
        }
    }
}

【讨论】:

  • 代码转储不是一个有用的答案,因为它要求读者扫描您的所有代码并尝试确定您为解决问题所做的工作。如果您解释一下您所做的更改以及更改的原因,您的答案会更好。
  • @egallardo Stack Exchange 的创始人希望这个网站成为一个学习/教学资源,而不仅仅是一个代码 sn-p 集合。
  • @BasilBourque 所以,请教我我发布的内容有什么问题。我解释了修改并发布了 OP 认为有用的固定版本。这有什么问题?
  • @egallardo 好多了。我删除了我的反对票。两个较温和的批评:(a) 在 2018 年,我们不应该教授使用现在遗留下来的麻烦的旧日期时间类,完全被 java.time 类所取代。 (b) 您对 Joda-Time 的推荐也已过时。该项目现在处于维护模式,其团队建议迁移到 java.time 类。对于 Java 6 和 Java 7,请使用 ThreeTen-Backport 项目。对于早期的 Android,请使用 ThreeTenABP 项目。
【解决方案2】:
  1. 时区至关重要。除非您知道当前时间位于哪个时区,否则您的验证毫无意义。为了读者的利益,也请在您的代码中指定它。
  2. 您使用的日期和时间类DateDateFormatSimpleDateFormat 不仅过时已久,尤其是最后一个以难以使用而著称。相反,我建议您使用现代 Java 日期和时间 API java.time。这甚至提供了一个LocalTime 课程,一个没有日期的时间,它比Date 更精确地满足您的需求。

所以你的方法写得清晰简洁:

private static boolean verifyIfInside(String max, String min) {
    LocalTime now = LocalTime.now(ZoneId.of("Europe/Budapest"));
    LocalTime minHour = LocalTime.parse(min);
    LocalTime maxHour = LocalTime.parse(max);
    return ! (now.isBefore(minHour) || now.isAfter(maxHour));
}

如果不是欧洲/布达佩斯,请替换您想要的时区。

由于我了解您希望您的范围具有包容性,并且由于 isBeforeisAfter 严格表示之前和之后,所以我使用否定来测试时间“不在范围之外”。

我进一步利用了这样一个事实,即您的时间格式12:00:00 与 ISO 8601 一致,现代类将其解析为默认格式,也就是说,没有任何明确的格式化程序。一个潜在的缺点是时间字符串的验证较弱:parse() 也将接受12:0012:23:29.82376342。如果你需要拒绝这些错误,你确实需要一个明确的格式化程序。

你的代码出了什么问题?

据我所知,您在问题中的代码工作正常(如果我们只是将hora1 更改为hour1 或相反,hora2 也是)。您可能对参数的顺序感到困惑。如果在 12 和 18 之间运行,则以下返回 true:verifyIfInside("18:00:00", "12:00:00")。然而,许多人会发现将调用写为verifyIfInside("12:00:00", "18:00:00") 是很自然的,它总是返回false。因此,将方法声明为verifyIfInside(String min, String max) 几乎肯定会更好,也就是说,在max 之前使用min

当然,正如我所提到的,另一种可能性是,您的 JVM 使用的时区与您认为它正在使用的时区不同。这很可能会给您带来意想不到的结果。确保不是这种情况的唯一方法是明确指定它应该使用哪个时区。

【讨论】:

  • 时区并不重要,与原始问题无关。
【解决方案3】:

我已经用 .before().after() 对其进行了测试,它工作正常,您还可以减少以下代码:-

private static boolean verifyIfInside(String min , String max){
    try {
        DateFormat dateFormat = new SimpleDateFormat ("HH:mm:ss");

        String current_time = dateFormat.format(new Date());

        Date minHour = dateFormat.parse(min);
        Date maxHour = dateFormat.parse(max);
        Date curr_time = dateFormat.parse(current_time);

        return minHour.before(curr_time) && maxHour.after(curr_time);

    } catch (ParseException parseException){
        parseException.printStackTrace();
        return false;
    }
}

【讨论】:

  • 欢迎@RafaelAraujo,如果你真的喜欢它,请投票。
猜你喜欢
  • 1970-01-01
  • 2016-05-03
  • 1970-01-01
  • 1970-01-01
  • 2020-05-11
  • 2018-04-07
  • 2019-02-11
  • 2021-11-13
  • 2019-12-06
相关资源
最近更新 更多