【问题标题】:Android - Check if current time is between 2 given times and the day of the week is validAndroid - 检查当前时间是否在 2 个给定时间之间以及星期几是否有效
【发布时间】:2019-09-26 15:49:31
【问题描述】:

如果时间介于开始时间和停止时间之间以及特定日期,我必须采取行动。我参考了SO上的一些现有线程来检查时间是否在指定的时间范围内。

假设开始时间是下午 23:00,停止时间是上午 7:00,当前时间是上午 2:00。只是时间有效性函数返回 true。但如果我在这段代码中包含天数,该函数将返回 false。例如:用户选择[星期一、星期二、星期三]。即使星期四不在列表中,但结束时间上午 7:00 落在星期四,可以在星期三下午 23:00 至星期四上午 7:00 之间的任何时间采取行动,但不能在星期四晚上 23:00 或任何不采取行动的日子采取行动列表中提到的。

下面是我的代码:

private fun isCurrentTimeBetweenProvidedTime(context: Context): Boolean {
        var reg = "^([0-1][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$".toRegex()
        val startTime = getStartTime()
        val endTime = getEndTime()
        val currentTime = getCurrentTime()

        if (reg.containsMatchIn(startTime) && reg.containsMatchIn(endTime) && reg.containsMatchIn(currentTime)) {
            var valid = false

            var startTime = SimpleDateFormat("HH:mm:ss").parse(startTime)
            var startCalendar = Calendar.getInstance()
            startCalendar.time = startTime

            var currentTime = SimpleDateFormat("HH:mm:ss").parse(currentTime)
            var currentCalendar = Calendar.getInstance()
            currentCalendar.time = currentTime

            var endTime = SimpleDateFormat("HH:mm:ss").parse(endTime)
            var endCalendar = Calendar.getInstance()
            endCalendar.time = endTime

            if (currentTime.compareTo(endTime) < 0) {
                currentCalendar.add(Calendar.DATE, 1)
                currentTime = currentCalendar.time
            }

            if (startTime.compareTo(endTime) < 0) {
                startCalendar.add(Calendar.DATE, 1)
                startTime = startCalendar.time
            }

            if (currentTime.before(startTime)) {
                valid = false
            } else {
                if (currentTime.after(endTime)) {
                    endCalendar.add(Calendar.DATE, 1)
                    endTime = endCalendar.time
                }

                if (currentTime.before(endTime)) {
                    valid = true
                } else {
                    valid = false
                }
            }

            // This won't work if day is Thursday and time is 2:00am, even though time falls between 23:00-7:00
            var todayCalendar = Calendar.getInstance()
            if ((currentTime >= startTime && todayCalendar.get(Calendar.DAY_OF_WEEK) in selectedDays.values) &&
                    (currentTime <= endTime && (todayCalendar.get(Calendar.DAY_OF_WEEK) in selectedDays.values || todayCalendar.get(Calendar.DAY_OF_WEEK)-1 in selectedDays.values))) {
                Log.d(TAG, "Days are valid")
            }

            return valid
        }

        return false
    }

我该如何处理这些日子场景?

【问题讨论】:

  • 考虑扔掉早已过时且臭名昭著的麻烦SimpleDateFormat 和朋友,并将ThreeTenABP 添加到您的Android 项目中,以便使用java.time,现代Java 日期和时间API。使用起来非常好,并且会更好地支持您的任务。
  • 在我看来这是一个重复的问题。也许不是以前的一个问题,但如果你结合例如Check if a given time lies between two times regardless of dateWhat is the easiest way to get the current day of the week in Android??
  • 我理解正确吗?在您的示例中,您希望在星期一 23 点和星期二 7 点之间以及在星期二和星期三之间以及星期三和星期四之间的晚上采取类似的行动?但是不是星期一 7 点之前和 不是星期四 23 点之后?

标签: android date kotlin


【解决方案1】:

java.time 和 ThreeTenABP

请注意:此代码可以在低于和高于 26 级的 Android API 级别上运行。我将在下面进一步解释。我必须相信你会翻译 Java 代码。

如果我正确理解了您的要求:

    ZoneId zone = ZoneId.of("America/Chihuahua");

    LocalTime startTime = LocalTime.of(23, 0);
    LocalTime endTime = LocalTime.of(7, 0);
    Set<DayOfWeek> selectedDays
            = EnumSet.of(DayOfWeek.MONDAY, DayOfWeek.TUESDAY, DayOfWeek.WEDNESDAY);

    ZonedDateTime now = ZonedDateTime.now(zone);
    LocalTime timeNow = now.toLocalTime();
    DayOfWeek currentDayOfWeek = now.getDayOfWeek();
    boolean inIntervalOnDay;
    if (startTime.isAfter(endTime)) { // crosses midnight
        if (timeNow.isBefore(endTime)) { // in interval, after midnight
            // Day is correct if the day before is among the selected days
            inIntervalOnDay = selectedDays.contains(currentDayOfWeek.minus(1));
        } else if (timeNow.isBefore(startTime)) {
            inIntervalOnDay = false;
        } else { // after start time, before midnight
            inIntervalOnDay = selectedDays.contains(currentDayOfWeek);
        }
    } else {
        inIntervalOnDay = ! timeNow.isBefore(startTime)
                && timeNow.isBefore(endTime)
                && selectedDays.contains(currentDayOfWeek);
    }
    System.out.println("Now: " + now + " (" + currentDayOfWeek + ") Valid? " + inIntervalOnDay);

刚才运行sn-p的时候,输出是:

现在:2019-09-27T03:47:56.856-06:00[美国/吉娃娃](星期五)有效吗?假的

如果不是美国/吉娃娃,请替换您想要的时区。时区很重要。

问题:我可以在 API 级别 26 以下的 Android 上使用 java.time 吗?怎么样?

是的,java.time 在较旧和较新的 Android 设备上运行良好。它只需要至少 Java 6

  • 在 Java 8 及更高版本以及更新的 Android 设备(从 API 级别 26 起)中,现代 API 是内置的。
  • 在 Java 6 和 7 中获得 ThreeTen Backport,这是现代类的后向端口(JSR 310 的 ThreeTen;请参阅底部的链接)。
  • 在(较旧的)Android 上使用 ThreeTen Backport 的 Android 版本。它被称为 ThreeTenABP。并确保从 org.threeten.bp 导入日期和时间类以及子包。

链接

【讨论】:

    【解决方案2】:

    一种可能的方法是将您的所有时间标准化为与所选周起点的偏移量,例如周日上午 12:00 = 0。将您的所有时间转换为自起点以来的分钟数。然后只需检查您选择的时间(也转换为自开始后的分钟数)是否在任何范围内。

    【讨论】:

    • 谢谢@dharms!你的方法给了我另一个想法。如果我的开始时间是 23:00,结束时间是第二天 7:00,那么 23:00 的毫秒时间将大于 7:00 的毫秒时间。我总是可以用它作为检查。如果是这样的话,从 23:00-23:59:59,我可以查看选定日期的列表,从 00:00-7:00,我可以查看选定+1 天的列表。如果用户开始时间是上午 9:00 到下午 5:00,在这种情况下,以毫秒为单位的开始时间小于以毫秒为单位的结束时间。我认为这种方法可能有效。
    • 那肯定行得通,但实施起来可能比我建议的要复杂。最终,您可以随心所欲地做,我很乐意为您提供帮助!
    猜你喜欢
    • 2013-01-19
    • 1970-01-01
    • 2018-07-26
    • 1970-01-01
    • 2021-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多