所以我的方法收到24小时格式的时间(“HH:MM:SS”)并返回一个字符串差异时间。如果是当地时间下午2:00我应该能够“16:30:00”(下午4:30)发送它并输出“2小时30分钟”。但代码有一些问题,我只是一个初学者,我需要帮助来解决它。
问题是如果时间是下午4:40,我发送它“17:00:00”(下午5:00)它返回消息: 12小时20分钟而不是0小时20分钟。 另一个问题是,如果我发送当前时间,它将返回“12小时”,而不是像它应该的那样。
请记住,我只是java的初学者,数学真的不是我的事,所以任何帮助都非常感谢。感谢。
private static String timeUntil(String distanceTime) {
String returnMsg = null;
try {
SimpleDateFormat sdfDate = new SimpleDateFormat("hh:mm:ss");
Date now = new Date();
java.text.DateFormat df = new java.text.SimpleDateFormat("hh:mm:ss");
Date date1 = df.parse(sdfDate.format(now));
Date date2 = df.parse(distanceTime);
long diff = date2.getTime() - date1.getTime();
int timeInSeconds = (int) (diff / 1000);
int hours, minutes;
hours = timeInSeconds / 3600;
timeInSeconds = timeInSeconds - (hours * 3600);
minutes = timeInSeconds / 60;
if (hours >= 0) {
returnMsg = hours + " hours" +
"\n" + minutes + " mins";
} else {
returnMsg = minutes + " mins";
}
} catch (Exception e) {
e.printStackTrace();
}
return returnMsg;
}
答案 0 :(得分:4)
在您的日期格式中,hh
用于 12 - 小时。使用HH
24 -hour time:
new SimpleDateFormat("HH:mm:ss");
答案 1 :(得分:0)
代码审核评论......
不推荐使用大多数Date类的方法。您应该考虑使用Calendar(GregorianCalendar)而不是Date。
您的变量名称通常缺乏意义 - 您必须知道变量的目的才能知道其含义。如果使用更好的变量名,您的代码将更易于维护。 df可以重命名为“format”或“dateFormat”。
您创建一个Date对象'now',然后通过您的df DateFormat实例传递它,通过您的sdfDate实例,将其转换回Date。这是不必要的。将其替换为Date date1 = new Date();
并删除Date now = new Date();
。同时,我看到在单位之间进行转换时很难诊断出错误,因此您应该更改diff
以表示它是毫秒,例如diff_ms
。你应该保持名称一致 - 你从“不同”(diff
)变为“timeInSeconds”。它们都应该是“timeInXxx”或“diff_xx”。 distanceTime
参数应重命名为futureTime
你做了一堆数学来确定两次之间的差异,但有些库会为你做这件事。谷歌为“两个日期之间的java差异”找到了很多答案。
您的代码始终假定第二次出现在“now”之后。这应该包含在方法顶部的注释中。
当您实例化date1和date2时,它们可能都在同一天。尝试调试或至少在创建对象后立即将对象打印到stdout以查看是否是这种情况。这是你真正想要的吗?
您的代码无法处理闰年。
您为什么不寻找能够为您完成任务的图书馆,而不是自己处理所有的时间转换?
答案 2 :(得分:0)
这是您的固定代码。我已将日期格式更改为HH:mm:ss以及您的计算逻辑。试一试,告诉我们
private static String timeUntil(String distanceTime) {
String returnMsg = null;
try {
SimpleDateFormat sdfDate = new SimpleDateFormat("HH:mm:ss");
Date now = new Date();
java.text.DateFormat df = new java.text.SimpleDateFormat("HH:mm:ss");
Date date1 = df.parse(sdfDate.format(now));
Date date2 = df.parse(distanceTime);
long diff = date2.getTime() - date1.getTime();
int timeInSeconds = (int) (diff / 1000);
int hours, minutes;
hours = timeInSeconds / 3600;
timeInSeconds = timeInSeconds - (hours * 3600);
minutes = timeInSeconds / 60;
if (hours != 0) {
returnMsg = hours + " hours" +
"\n" + minutes + " mins";
} else {
returnMsg = minutes + " mins";
}
} catch (Exception e) {
e.printStackTrace();
}
return returnMsg;
}
答案 3 :(得分:0)
这是一个更健壮并使用Java更现代的日期函数的示例。我可以一点一点地指出你可以在你的例子中做得更好的事情,但有时它更容易给你一个很好的例子,让你从其他人的代码中收集你所能做的好的风格。
import java.util.Calendar;
public class testSpace {
public static void main (String ... args){
System.out.println(timeUntil("00:12:12"));
}
private static String timeUntil(String distanceTime){
String[] times = distanceTime.split(":");
Calendar now = Calendar.getInstance();
Calendar then = Calendar.getInstance();
then.set(Calendar.SECOND, Integer.parseInt(times[2]));
then.set(Calendar.MINUTE, Integer.parseInt(times[1]));
then.set(Calendar.HOUR, Integer.parseInt(times[0]) % 12);
then.set(Calendar.AM_PM, (Integer.parseInt(times[0]) >= 12 ) ? Calendar.PM : Calendar.AM);
boolean isFuture = (then.getTimeInMillis() > now.getTimeInMillis());
long interval = (isFuture)
? then.getTimeInMillis() - now.getTimeInMillis()
: now.getTimeInMillis() - then.getTimeInMillis();
return ((isFuture) ? "" : "-") + millToTime(interval);
}
public static long MILLISECOND_PER_HOUR = 1000*60*60;
public static long MILLISECOND_PER_MIN = 1000*60;
public static long MILLISECOND_PER_SECOND = 1000;
public static String millToTime(long mill){
long hours = mill / MILLISECOND_PER_HOUR;
long mins = (mill % MILLISECOND_PER_HOUR) / MILLISECOND_PER_MIN;
long sec = ((mill % MILLISECOND_PER_HOUR) % MILLISECOND_PER_MIN) / MILLISECOND_PER_SECOND;
return String.format("%d:%d:%d", hours, mins, sec);
}
}
答案 4 :(得分:0)
仅适用于没有日期或时区的时间。
LocalTime start = LocalTime.of( "16:40" ) ;
LocalTime stop = LocalTime.of( "17:00" ) ;
Duration d = Duration.between( start , stop ) ;
PT20M
或者,对于区域中的日期时间。
ZoneId z = ZoneId.of( "America/Montreal" )
ZonedDateTime zdtNow = ZonedDateTime.now( z );
ZonedDateTime zdtThen =
ZonedDateTime.of( // Pass a LocalDate, LocalTime, ZoneId.
zdtNow.toLocalDate() , // Same date…
LocalTime.parse( "16:30:00" ) , // … but different time-of-day.
z
)
Duration d = Duration.between( zdtNow , zdtThen ) ;
PT2H30M
您正在使用旧的日期时间类,现在是旧的,取而代之的是java.time类。
LocalTime
您错误地将日期时间类用于仅限时间的值。而是使用LocalTime
类。并在计算经过时间时使用时间跨度类。
String input = "16:30:00" ;
LocalTime lt = LocalTime.parse( input );
Instant
Instant
类代表UTC中时间轴上的一个时刻,分辨率为nanoseconds(小数部分最多九(9)位)。
Instant instant = Instant.now();
ZonedDateTime
确定wall-clock time需要时区。以continent/region
格式指定proper time zone name,例如America/Montreal
,Africa/Casablanca
或Pacific/Auckland
。切勿使用诸如EST
或IST
之类的3-4字母缩写,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdtNow = instant.atZone( z ); // Adjusted into your time zone.
现在为您指定的输入时间构建ZonedDateTime
。
ZonedDateTime zdtTarget = ZonedDateTime.of( zdtNow.toLocalDate() , lt , z );
Duration
使用Duration
表示未附加到时间轴的已用时间。
Duration d = Duration.between( zdtNow , zdtTarget );
请注意,如果指定的时间早于当前时间,则持续时间将为负数。
持续时间要获取描述该时间段的小时,分钟等的字符串,只需致电toString
以生成PnYnMnDTnHnMnS
格式P
格式的字符串T
标记开头,14:00:00
将年 - 月 - 日与小时 - 分 - 秒分开。
如果同一区域中的当前时间为Duration
,则输出为:
PT2H30M
奇怪的是,在Java 8中,这个类2
缺少任何部分的getter方法,例如30
等小时和toHoursPart
分钟。 ISO 8601,例如toMinutesPart
和from pytz import timezone
def get_curr_time():
pst = timezone('US/Pacific')
cur_time = datetime.now(pst)
return cur_time.strftime('%Y-%m-%d, %H:%M:%S')
。
Remedied in Java 9 with methods框架内置于Java 8及更高版本中。这些类取代了麻烦的旧java.time日期时间类,例如legacy,java.util.Date
和& Calendar
现在位于SimpleDateFormat
的Joda-Time项目建议迁移到java.time。
要了解详情,请参阅maintenance mode。并搜索Stack Overflow以获取许多示例和解释。规范是Oracle Tutorial。
从哪里获取java.time类?
How to use…项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如ThreeTen-Extra,Interval
,YearWeek
和YearQuarter
。