问题描述
问题情况:我有大量的记录都标有时间戳。我正在遍历所有这些来做这个和那个,但我需要检测一天的变化。
现在对于我正在做的每个循环:
cal.setTimeInMillis(record.time);
int currentDay = cal.get(Calendar.DAY_OF_WEEK);
当它运行数十万次时,它是否像我想象的一样慢? 我想我错过了一个非常简单的模数答案或其他东西。
编辑:时区无关紧要,我收集的更多信息可以解决某人的消耗品报告。每份报告 24 小时更准确,所以实际上我不必担心是早上 5 点到凌晨 5 点还是下午 3 点到下午 3 点,只要我能够收集 24 小时的信息。
谢谢大家
解决方法
经过安迪·特纳 (Andy Turner) 的时间测试后,我不一定确信您需要任何优化的解决方案。在任何情况下,timsmelik 的建议都非常简单:将一天更改的时间转换为自纪元以来的毫秒数,这样您只需比较 long
值。我不认为它会严重损害可读性。所以这里是代码。我正在使用并热烈推荐 java.time,现代 Java 日期和时间 API,如果仅用于从小时到毫秒的转换以及打印结果。即使这样的转换看起来微不足道,最好还是让标准库来做。它更不言自明,更不容易出错,而且更容易让读者相信它是正确的。
final long twentyfourHoursAsMillis = Duration.ofHours(24).toMillis();
// Times are already sorted descending (from newest to oldest)
long[] times = { 1_611_718_370_000L,1_611_632_000_000L,1_611_631_970_000L,1_611_459_150_000L };
List<List<Long>> chunks = new ArrayList<>();
List<Long> currentChunk = new ArrayList<>();
// Process first time separately to get started
currentChunk.add(times[0]);
long timeOfNextChunk = times[0] - twentyfourHoursAsMillis;
// Process remaining times
for (int i = 1; i < times.length; i++) {
long currentTime = times[i];
if (currentTime <= timeOfNextChunk) {
chunks.add(currentChunk);
currentChunk = new ArrayList<>();
do {
timeOfNextChunk -= twentyfourHoursAsMillis;
} while (currentTime <= timeOfNextChunk);
}
currentChunk.add(currentTime);
}
// Save last chunk,why not?
chunks.add(currentChunk);
// Print result
for (List<Long> chunk : chunks) {
String chunkAsString = chunk.stream()
.map(Instant::ofEpochMilli)
.map(Instant::toString)
.collect(Collectors.joining(","));
System.out.println(chunkAsString);
}
输出为:
2021-01-27T03:32:50Z,2021-01-26T03:33:20Z
2021-01-26T03:32:50Z
2021-01-24T03:32:30Z
我正在打印 Instant
对象。它们总是以 UTC 打印。对于您的情况,如果您根本需要打印时间,您可能想要做其他事情。
您应该检查您的假设,即时间按顺序排列。
我相信你的话,并在 24 小时内分解成块。 24 小时甚至可能并不意味着早上 5 点到凌晨 5 点,但可能意味着例如从美国东部时间 3 月 13 日凌晨 5 点到美国东部时间 3 月 14 日早上 6 点,因为在此期间夏令时 (DST) 已经开始。如果您更喜欢在同一时钟时间拆分,可以修改代码以实现这一点。