【问题标题】:Get the specific 15 minutes timeframe based on current time根据当前时间获取具体的 15 分钟时间范围
【发布时间】:2017-01-03 08:40:03
【问题描述】:

我想获得基于当前时间的 15 分钟时间范围。

例如:

时间范围是every 15 minutes

即12比1分为四个时间段[ 12:00 to 12:15, 12:16 to 12:30, 1:31 to 12:45, 12:46 to 1:00]

如果当前时间是12:34 表示,我需要将时间范围返回为12:31 to 12:45

我们可以使用 Java 8 日期和时间 API 轻松做到这一点吗?

【问题讨论】:

  • 这很有趣,这个question 是最近的并且非常接近。作业?

标签: java java-8 java-time


【解决方案1】:

您可以创建一个 TemporalAdjuster 来计算当前 15 分钟周期的结束,并通过删除 14 分钟来计算周期的开始。

可能是这样的:

public static void main(String[] args) {
  LocalTime t = LocalTime.of(12, 34);
  LocalTime next15 = t.with(next15Minute());
  System.out.println(next15.minusMinutes(14) + " - " + next15);
}

public static TemporalAdjuster next15Minute() {
  return (temporal) -> {
    int minute = temporal.get(ChronoField.MINUTE_OF_DAY);
    int next15 = (minute / 15 + 1) * 15;
    return temporal.with(ChronoField.NANO_OF_DAY, 0).plus(next15, ChronoUnit.MINUTES);
  };
}

输出12:31 - 12-45

注意:我不确定它在 DST 更改时的表现如何 - 待测试。

【讨论】:

  • 感谢您的回答。
  • 或者只是int minutesDiff = 15 - minute%15;...
  • @Holger 实际上两者都没有,因为它会保留秒/纳米。编辑为先重置为午夜。
  • 好的,但是当您关心 nanos 时,首先使用它们进行计算更有意义,这再次允许使用模而不是除法、舍入和乘法:temporal.plus(900000000000L - temporal.getLong(ChronoField.NANO_OF_DAY)%900000000000L, ChronoUnit.NANOS)。当然,生产代码会使用static final 字段作为常量。
【解决方案2】:

您可以简单地使用 Date API 并计算间隔。 除以您的时间间隔(15 分钟)并再次相乘。这将去掉分钟并舍入到较低的 15 分钟间隔。现在您必须增加 15 分钟才能获得所需的输出。见以下代码:

import java.util.*;
import java.lang.*;
import java.io.*;

class Ideone
{
    public static void main (String[] args) throws java.lang.Exception
    {
        long ms = new Date().getTime();
        System.out.println("Current time: " + new Date().toString());

        long fifteen = 15 * 60 * 1000;
        long newMs = (ms / fifteen) * fifteen + fifteen;
        System.out.println("Calculated time: " + new Date(newMs));
    }
}

running example

编辑:

Running example 与 LocalDate

import java.util.*;
import java.lang.*;
import java.io.*;
import java.time.*;
import java.time.temporal.ChronoField;
import java.time.temporal.ChronoUnit;

class Ideone
{
    public static void main (String[] args) throws java.lang.Exception
    {
        LocalTime now = LocalTime.now();
        System.out.println(now);

        LocalTime next = now.with((temp) -> {
            int currentMinute = temp.get(ChronoField.MINUTE_OF_DAY);
            int interval = (currentMinute / 15) * 15 + 15;
            temp = temp.with(ChronoField.SECOND_OF_MINUTE, 0);
            temp = temp.with(ChronoField.MILLI_OF_SECOND, 0);
            return temp.with(ChronoField.MINUTE_OF_DAY, interval);  
        });
        System.out.println(next);
    }
}

【讨论】:

  • 提问者询问了 Java 8 日期和时间 API。我也认为使用这个比使用java.util.Date 和长算法更可取。
  • @OleV.V.,我同意使用 LocalDate 但算术仍然更容易。 (请注意,这可能更清楚)
  • @AxelH,感谢您一直以来的博学意见。我发现在几分钟内做算术比在毫秒内做算术更方便和更容易阅读(当然,你不必同意)。当然需要一些算术。
  • @OleV.V.事实上,我可以理解对于某些人来说,在几分钟内获得价值而不是60 * 1000 ms 更具可读性。即使这是一些通常的值。
  • 大家好,感谢您的反馈。我添加了一个带有 LocalDate 和分钟计算的示例。主要是我更喜欢用毫秒计算,但我认为这是一个品味问题。但在某些情况下是不可避免的。
【解决方案3】:

这是一个使用 LocalTime 的更简单的方法

public static void main(String[] args) {
  int interval = 15; //Can be customized to any value
  LocalTime now = LocalTime.now();
  int minuteOfDay = now.toSecondOfDay() / 60;
  int mod = (minuteOfDay / interval + 1) * interval;
  System.out.println("lower bound" + LocalTime.ofSecondOfDay((mod - interval) * 60));
  System.out.println("Upper bound" + LocalTime.ofSecondOfDay(mod * 60));
}

【讨论】:

    猜你喜欢
    • 2021-07-11
    • 2013-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-20
    • 2018-01-30
    • 1970-01-01
    相关资源
    最近更新 更多