简而言之,我有:

startTime (When my interval chain will start)

repeatEveryMinuteInterval (Repeat every minute of this action)

duration (Duration of the action)

它建立了音程的链条.例1:

StartTime - 15:00 UTC 9/19/2022
repeatEveryMinuteInterval - 15
duration - 5 minutes

15:00 - 15:05
15:15 - 15:20
15:30 - 15:35
15:45 - 15:50
16:00 - 16:05
// as it is endless it will iterate an infinite number of times

示例2:

StartTime - 03:07 UTC 10/19/2022
repeatEveryMinuteInterval - 30
duration - 5 minutes

03:07- 03:12
03:37- 03:12
04:07- 04:12
// as it is endless it will iterate an infinite number of times

我的问题是:既然这两条区间链没有终点,我怎么知道它们future 不会重叠呢?

我假设,如果两个间隔共享相同的时间,即使是部分时间,它们也是重叠的.

15:30 - 15:45
15:25 - 15:31 

They are overlapping as they both have 15:30 - 15:31 in the intervals.

从实现的Angular 来看,我想出了3种方法,而且都是虚拟的)

1.)假设它们会重叠,因为这是一个无穷无尽的集合,不可能计算并得到一致的结果.

2.)来计算下1000次迭代并进行比较.问题是我不知道我应该迭代多少次才能得到有效的结果,并且这个操作不需要花费很多时间来计算.

UPD:如果任何人有带或不带时区的解决方案,我都很乐意与您交流.谢谢

我重新提出我的问题,因为我收到了来自CryptoFool的更新,这个问题可以解决.

封闭式问题 https://stackoverflow.com/questions/73768795/how-to-know-will-2-repeatable-intervals-overlap-in-the-future

更新2:添加新的示例(其中repepeEveryMin>=持续时间)

StartTime - 00:00 UTC 9/20/2022
repeatEveryMinuteInterval - 600 (every 10 hours)
duration - 5 minutes

00:00 - 00:05
10:00 - 10:05
20:00 - 20:05
// other iterations
StartTime - 19:02 UTC 9/20/2022
repeatEveryMinuteInterval - 30
duration - 5 minutes

19:02 - 19:07
19:32 - 19:37
20:02 - 20:07
// other iterations

在本例中,这两个内部 struct 在这里重叠:`

interval 1: 20:00 - 20:05
interval 2: 20:02 - 20:07

推荐答案

这个问题的答案来自最小公倍数的概念.无论这两个序列的周期是什么,总会有一个时间点,它们都在同一时间点开始一个新的周期,可能会有一个偏移量.从那时起,发生的一切都将是第一个周期中发生的事情的重演.

要得到这个周期的长度,只需要找到两个重复间隔中最小的公倍数.在最坏的情况下,当两个间隔中的一个是质数时,该周期将是interval1 * interval2.如果这些数字不是素数,它们所共有的任何公因子都将意味着周期长度将会缩短.以下是将计算最小公倍数的Python函数:

def compute_lcm(a, b):
    return abs(a*b) // math.gcd(a, b)

如果这两个序列同时开始,那么从现在开始,一切都会非常简单.但如果这两个时间间隔开始的时间不同,事情就会变得更加复杂.我们基本上必须考虑到这样一个事实,即单个周期不会捕获所有这两个序列,因为一个序列可能在单个周期开始之前开始,而另一个序列可能在周期开始之后结束.

我推理出了必须做什么才能考虑到两个序列的偏移量,还考虑了可能会将事情延长一点的持续时间.我可能不太明白这一点.我已经创建了几个示例,手动推理出重叠部分是什么,然后在我的代码中运行这些示例,我得到了相同的答案.所以它应该是正确的.

所以这就是它血淋淋的荣耀:

import math

def compute_lcm(a, b):
    return abs(a*b) // math.gcd(a, b)

# First sequence
# 15-20, 30-35, 45-50, 60-65
seq1 = {
    'start': 15,
    'repeat_interval': 15,
    'duration': 5,
    'extra': 0,
}

# Second sequence
# 5-11, 25-31, 45-51, 65-71
seq2 = {
    'start': 5,
    'repeat_interval': 20,
    'duration': 6,
    'extra': 0,
}

# Overlap by inspection: 30, 45-49

# Compute the magic value, the number of minutes at which the two sequences start over at the same time offset as for the initial cycle.
lcm = compute_lcm(seq1['repeat_interval'], seq2['repeat_interval'])

overall_start = 0

# This stuff's a bit crazy, I know.  Sorry.

# For whichever sequence starts last, add extra repeat intervals to
# the start of it so that it covers the entire main cycle, which
# starts where the other cycle starts.
if seq1['start'] > seq2['start']:
    while seq1['start'] > seq2['start']:
        seq1['start'] -= seq1['repeat_interval']
        seq1['extra'] += seq1['repeat_interval']
    overall_start = seq1['start']
else:
    while seq2['start'] > seq1['start']:
        seq2['start'] -= seq2['repeat_interval']
        seq2['extra'] += seq2['repeat_interval']
    overall_start = seq2['start']

# Compute a worst case length for the 'minutes' array we'll use
# to tally to find the overlaps.  
total_length = lcm + max(seq1['extra'], seq2['extra']) + max(seq1['duration'], seq2['duration'])
offset = -min(seq1['start'], seq2['start'])

# Create an array such that each element in the array represents a minute of time
minutes = [0] * total_length


# Now walk through each sequence from its start.  For each, compute each interval, and then loop over that
# interval, incrementing the value of each minute of it in the 'minutes' array to record that the sequence
# was "on" during that minute.
#
# NOTE: I chose to consider an interval's start and ent times to be exlusive of the last minute.  So the
# interval 10-15 consists of the minutes 10, 11, 12 and 13.  I could have gone the other way, including the
# last minute in each interval. If that's what is desired, I leave making that small change as an exercise for the OP

for seq in (seq1, seq2):
    t = seq['start']
    while t < seq['start'] + lcm + seq['extra']:
        for o in range(seq['duration']):
            tt = offset + t + o
            minutes[tt] += 1
        t += seq['repeat_interval']

# At this point, overlaps consist of values in the 'minutes' array that have a value of 2, meaning
# that both sequences were "on" during that minute.  Walk through the array, printing out each
# minute that was part of an overlap
for i in range(total_length):
    if minutes[i] > 1:
        print(i-offset)

结果:

30
45
46
47
48
49

如果您想要生成更多的重叠分钟数,只需继续迭代更多的分钟值,并对分钟值执行mod操作以在‘Minents’数组中进行查找.所以:

count = minutes[m % lcm]

如果count==2,则对于任何值"m",分钟"m"都是重叠的一部分.

哦..还有一件事,也许这就是我的答案遗失绿色支票的地方.此答案不考虑以小时和分钟指定的时间.它只是给出了计算重叠和计算最小必要周期长度的基本思想的答案,所有值都以分钟为单位表示.要在数小时或数天内执行此操作,只需将时间值转换为仅分钟表示即可.时区也会增加复杂性,但您只需补偿分钟值就可以考虑任何时区转换.

Java相关问答推荐

无法找到符号错误—Java—封装

Quarkus keycloat配置不工作.quarkus. keycloak. policy—enforcer. enable = true在. yaml表示中不工作

取消按钮,但没有任何操作方法引发和异常

Java记录的不同序列化/反序列化

格式中的特定回录键-值对

在Eclipse中调试未导出的JDK模块的Java包

如何将Pane的图像快照保存为BMP?

SpringBoot:在条件{Variable}.isBlank/{Variable}.isEmpty不起作用的情况下进行路径变量验证

为什么Collectors.toList()不能保证易变性

如何在Spring Boot中创建可以将值传递给配置的&Enable&Quot;注释?

如何在Jooq中获取临时表列引用?

FETCH类型设置为LAZY,但它仍会发送第二个请求

泛型与泛型问题的完美解决方案?

没有Tomcat,IntelliJ如何在本地运行API?

未调用OnBackPressedCallback-Activitiy立即终止

在Java中使用StorageReference将数据从Firebase存储添加到数组列表

我无法在我的Spring Boot应用程序中导入CSV依赖项

Eureka客户端无法使用用户/通行证注册到Eureka服务器

可以';不要在Intellij IDEA中使用最新的Java版本(JDK 21)

Java-Apache BufferedHttpEntity 在发送请求时加载整个文件