【发布时间】:2019-02-17 09:32:03
【问题描述】:
我有 5 次 示例:
凌晨 4:21
下午 12:1
下午 3:32
下午 6:30
晚上 8:4
现在时间是
上午 10:4
我想做一个比较 下一次最接近当前时间是什么时候
结果将是:
下一次:12:1 PM
【问题讨论】:
-
12:1 PM??你是说12:10 PM还是12:01 PM? -
我的意思是下午 12:01
我有 5 次 示例:
凌晨 4:21
下午 12:1
下午 3:32
下午 6:30
晚上 8:4
现在时间是
上午 10:4
我想做一个比较 下一次最接近当前时间是什么时候
结果将是:
下一次:12:1 PM
【问题讨论】:
12:1 PM??你是说12:10 PM 还是12:01 PM?
我专门设计了一个函数来解决你的问题,你需要的函数使用。
它肯定对你有用。
/**
*
* @author Niravdas
*/
public class TimeDiff {
String[] times = { "04:21 AM", "12:01 PM", "03:32 PM", "06:30 PM", "08:04 PM"};
String findingafter="10:04 AM";
public TimeDiff()
{
int time=nextTimeArrayIndex(findingafter,times);
if(time>=0)
System.out.println("NEXT TIME: "+times[time]);
}
public static void main(String argv[])
{
new TimeDiff();
}
int nextTimeArrayIndex(String Finding,String[] fromArray)
{
int shortest=-1,shortestsec=-1;
long minsecdif=(24*60*60+1),minsec=(24*60*60+1);
int hr=Integer.parseInt(Finding.substring(0, 2));
int min=Integer.parseInt(Finding.substring(3, 5));
long seconds = convertToSec(hr, min, 0, Finding.substring(Finding.length()-2));
System.out.println("seconds :" + seconds);
for(int i=0;i<fromArray.length;i++)
{
int temphr=Integer.parseInt(fromArray[i].substring(0, 2));
int tempmin = Integer.parseInt(fromArray[i].substring(3,5));
long tempsec = convertToSec(temphr, tempmin, 0, fromArray[i].substring(Finding.length()-2));
System.out.println("Compared to :" + tempsec);
if((tempsec - seconds) > 0 && minsecdif > (tempsec - seconds))
{
minsecdif = (tempsec - seconds);
shortest = i;
}
if(minsec > tempsec)
{
minsec = tempsec;
shortestsec=i;
}
}
if(shortest >=0)
{
return shortest;
}
else
{
return shortestsec;
}
}
long convertToSec(int hr,int min,int sec,String AMorPM)
{
if(hr==12)
{
hr=0;
}
long secs = (hr*60*60) + (min*60) + (sec*60);
if(AMorPM.equalsIgnoreCase("PM"))
{
secs += (12*60*60);
}
return secs;
}
}
我希望它能解决你的问题。
【讨论】:
更新:添加了午夜翻转的逻辑,并添加了使用二分搜索的替代方案。
首先将输入解析为一天中以毫秒为单位的时间,方法是将时间字符串解析为 UTC 时区。
然后找到“当前”值之上或之后的最小值,如果在“当前”值之上或之后没有值,则仅找到最小值(翻转)。
例子:
public static String findNext(String current, String... times) throws ParseException {
SimpleDateFormat fmt = new SimpleDateFormat("hh:mm a");
fmt.setTimeZone(TimeZone.getTimeZone("UTC"));
long currentMillis = fmt.parse(current).getTime();
long bestMillis = 0, minMillis = 0;
String bestTime = null, minTime = null;
for (String time : times) {
long millis = fmt.parse(time).getTime();
if (millis >= currentMillis && (bestTime == null || millis < bestMillis)) {
bestMillis = millis;
bestTime = time;
}
if (minTime == null || millis < minMillis) {
minMillis = millis;
minTime = time;
}
}
return (bestTime != null ? bestTime : minTime);
}
测试
System.out.println(findNext("10:4 AM",
"4:21 AM", "12:1 PM", "3:32 PM", "6:30 PM", "8:4 PM"));
System.out.println(findNext("10:4 PM",
"4:21 AM", "12:1 PM", "3:32 PM", "6:30 PM", "8:4 PM"));
输出
12:1 PM
4:21 AM
如果保证给定时间已经排序,那么可以通过二分查找来完成:
public static String findNext(String current, String... times) {
SimpleDateFormat fmt = new SimpleDateFormat("hh:mm a");
fmt.setTimeZone(TimeZone.getTimeZone("UTC"));
int idx = Arrays.binarySearch(times, current, new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
try {
return fmt.parse(s1).compareTo(fmt.parse(s2));
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
});
if (idx < 0)
idx = -idx - 1;
return times[idx < times.length ? idx : 0];
}
【讨论】:
10:4 PM 调用findNext 将返回null。也许它应该环绕并返回4:21 AM,不确定。如果是这样,假设参考时间已排序,则在方法末尾添加if(bestTime == null) return times[0]; 将起作用。
times 值已经排序,那么二分搜索会好得多。不能做出这样的假设,因为问题没有具体说明。仅仅因为样本数据已排序,并不意味着实际数据会排序。
您可以将时间转换为日期对象,然后转换为 long(自 1970 年 1 月 1 日以来的毫秒数),并以毫秒为单位计算差异
long diffInMs = currentDate.getTime() - anotherDate.getTime();
然后检查哪个具有最小的差异,但也等于或大于零。负差表示旧日期,而您想要下一个最接近的日期
要将时间转换为日期,请检查:https://stackoverflow.com/a/8826392/2597775
基本上,它说:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
String inputString = "00:01:30.500";
Date date = sdf.parse("1970-01-01 " + inputString);
【讨论】: