好像,我找不到我的问题的答案,所以我在这里,首先在Stackoverflow :)
将提到的If语句树:
buttonSzamol.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
//Változók
int StartHour = 18;
int StartMin = 50;
int StopHour = 20;
int StopMin = 49;
int DayTimeIntervalStart = 6;
int DayTimeIntervalStop = 17;
int NightTimeIntervalLateStart = 18;
int NightTimeIntervalLateStop = 23;
int NightTimeIntervalEarlyStart = 0;
int NightTimeIntervalEarlyStop = 5;
int DayHoursTotal = 0;
int NightHoursTotal = 0;
int DayTimePricePerHour = Integer.parseInt(NappaliOraDij.getText());
int NightTimePricePerHour = Integer.parseInt(EjszakaiOraDij.getText());
int StartDay = Integer.parseInt((DatumStart.getText()).replace(".", ""));
int StopDay = Integer.parseInt((DatumStart.getText()).replace(".", ""));
//1 started hour
if( (StartDay == StopDay) && ( ( (StartHour == StopHour) && (StartMin < StopMin) ) || ( ((StartHour + 1) == StopHour) && (StartMin >= StopMin) ) ) ) {
if((DayTimeIntervalStart <= StartHour) && (StopHour <= DayTimeIntervalStop)) {
DayHoursTotal++;
}
if((NightTimeIntervalLateStart <= StartHour) && (StopHour <= NightTimeIntervalLateStop)) {
NightHoursTotal++;
}
} else/*More hours*/if( (StartDay == StopDay) && ( ( (StartHour < StopHour) && (StartMin <= StopMin) ) || ( (StartHour < StopHour) && (StartMin > StopMin) ) ) ) {
if( (StartHour < StopHour) && (StartMin < StopMin) ) {
if((DayTimeIntervalStart <= StartHour) && (StopHour <= DayTimeIntervalStop)) {
DayHoursTotal = DayHoursTotal + (StopHour - StartHour);
DayHoursTotal++;
}
if((NightTimeIntervalLateStart <= StartHour) && (StopHour <= NightTimeIntervalLateStop)) {
NightHoursTotal = NightHoursTotal + (StopHour - StartHour);
NightHoursTotal++;
}
}else if(( (StartHour < StopHour) && (StartMin >= StopMin) )) {
if((DayTimeIntervalStart <= StartHour) && (StopHour <= DayTimeIntervalStop)) {
DayHoursTotal = DayHoursTotal + (StopHour - StartHour);
if(StartMin != StopMin) {
DayHoursTotal--;
}
}
if((NightTimeIntervalLateStart <= StartHour) && (StopHour <= NightTimeIntervalLateStop)) {
NightHoursTotal = NightHoursTotal + (StopHour - StartHour);
if(StartMin != StopMin) {
NightHoursTotal--;
}
}
}
}
NappaliOrak.setText(Integer.toString(DayHoursTotal));
EjszakaiOrak.setText(Integer.toString(NightHoursTotal));
OrakOsszesen.setText(Integer.toString(DayHoursTotal + NightHoursTotal));
NappaliOsszeg.setText(Integer.toString(DayHoursTotal * DayTimePricePerHour));
EjszakaiOsszeg.setText(Integer.toString(NightHoursTotal * NightTimePricePerHour));
VegOsszeg.setText(Integer.toString((DayHoursTotal * DayTimePricePerHour) + (NightHoursTotal * NightTimePricePerHour)));
}
});
所以,问题简而言之就是。我试图为我的同事在工作中创建停车费计算器。主要的想法是,它需要计算客户开始的白天和夜间小时数,并且需要计算这些小时的价格。我已将StartHour / Min-StopHour / Min字段更改为直接整数,以使其更加难以理解。我不知道是否有一个模块,但我开始用很多If语句来做这个,我刚刚纠结了。在附带的pastebin中,开始时间为18:50,停止时间为20:49。如果我们输入这些数据,输出应该是2小时开始。现在,如果分钟相同,则不计入开始时间。但是如果我们将输入更改为20:51,那么它又开始了一个小时,因此DayHoursTotal应该等于3。
预先感谢您的任何帮助。如果您对我的代码或想法有更多疑问,请询问。
您似乎正在尝试计算不仅在2次之间,而且在不同日期之间的开始时间。
为此,最好使用java.time
包,更具体地说是LocalDateTime
类。
LocalDateTime.of(startYear, startMonth, startDay, startHour, startMinute)
qazxsw poi与来自Java 8 LocalDateTimes
类的qazxsw poi方法相结合,可以得到你所需要的。
between()
PS:你不需要那么多'间隔'变量。
只需一天的开始时间(ChronoUnit
)和夜晚(ChronoUnit.MINUTES.between(Temporal t1, Temporal t2)
)就足够了。
之前和之后的小时率可以从这两个间隔得出。
扰流板!如果你想进一步调查你的视线! ;)
这是一个可运行的代码示例,显示停车逻辑> 1天: (我省略了用户输入解析/逻辑,因为这取决于你的实现)
dayTimeIntervalStart
这输出:
发现小时差异:30 工作日:12 夜间:18 总小时数:30 日费为5:60 夜间费用为10:180 总费用:240
首先,您需要以不同方式解析整数。你的方法很危险,例如丢失信息。另外,如果有人试图输入无效的值,你需要使代码保险。请参阅此问题:nightTimeIntervalLateStart
除此之外,只需几分钟和几小时的工作总是很困难。我建议使用绝对时间(以毫秒为单位),这样可以更容易地进行计算。请参阅此问题:import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
public class ParkingFee {
private static long hoursDifference(LocalDateTime ldt1, LocalDateTime ldt2) {
long minutesDiff = ChronoUnit.MINUTES.between(ldt1, ldt2);
long hoursDiff = Math.round(Math.ceil(minutesDiff/60.0));
return hoursDiff;
}
public static long hoursDifference(
int startDay, int startMonth, int startYear, int startHour, int startMinute,
int endDay, int endMonth, int endYear, int endHour, int endMinute) {
return hoursDifference(
LocalDateTime.of(startYear, startMonth, startDay, startHour, startMinute),
LocalDateTime.of(endYear, endMonth, endDay, endHour, endMinute));
}
public static int determineDayCycle(int dayTimeIntervalStart, int nightTimeIntervalLateStart) {
return nightTimeIntervalLateStart - dayTimeIntervalStart;
}
public static void main(String[] args) {
// Hourly rates
int dayTimePricePerHour = 5;
int nightTimePricePerHour = 10;
// Rate intervals
int dayTimeIntervalStart = 6;
int nightTimeIntervalLateStart = 18;
// Counted hours per rate
int dayHoursTotal = 0;
int nightHoursTotal = 0;
// Start date and time
int startYear = 2019;
int startMonth = 1;
int startDay = 1;
int startHour = 20;
int startMinute = 50;
// End date and time
int endYear = 2019;
int endMonth = 1;
int endDay = 3;
int endHour = 2;
int endMinute = 49;
// Calculate the hours difference
long hourDiff = hoursDifference(
startDay, startMonth, startYear, startHour, startMinute,
endDay, endMonth, endYear, endHour, endMinute);
System.out.println("Hour difference found: "+ hourDiff);
// Handle parking for full days
if (hourDiff > 24) {
int dayCycle = determineDayCycle(dayTimeIntervalStart, nightTimeIntervalLateStart);
long fullDays = hourDiff / 24;
nightHoursTotal += (24-dayCycle)*fullDays;
dayHoursTotal += dayCycle*fullDays;
hourDiff = hourDiff % 24;
}
// Handle the parking for less than full day
while (hourDiff > 0) {
if (startHour < dayTimeIntervalStart) { // Before the day interval -> night
nightHoursTotal++;
} else if(startHour < nightTimeIntervalLateStart) { // Before the night interval -> day
dayHoursTotal++;
} else { // After the day interval -> night
nightHoursTotal++;
}
startHour++;
if (startHour > 23) // At midnight reset the hour to 0
startHour = 0;
hourDiff--;
}
System.out.println("Day hours: "+ dayHoursTotal);
System.out.println("Night hours: "+ nightHoursTotal);
System.out.println("Total hours: "+ (dayHoursTotal + nightHoursTotal));
System.out.println("Day rate charged at "+ dayTimePricePerHour +": "+ (dayHoursTotal * dayTimePricePerHour));
System.out.println("Night rate charged at "+ nightTimePricePerHour +": "+ (nightHoursTotal * nightTimePricePerHour));
System.out.println("Total rate charged: "+ ((dayHoursTotal * dayTimePricePerHour) + (nightHoursTotal * nightTimePricePerHour)));
}
}
您的代码和其他答案无法解释How do I convert a String to an int in Java?异常。如果您正在跟踪实际时刻,当人们实际停放时,而不是理论上的24小时漫长天,那么您必须考虑夏令时(DST)等异常情况。世界各地的政治家都表示喜欢重新定义其辖区内的时区。因此,日期可以是任何长度,例如25小时长,23小时,23.5小时,24.25或其他。
时区是特定地区人民使用的Difference in hours of two Calendar objects的过去,现在和将来变化的历史。
time zone类正是用于此目的的错误类。该类故意没有时区概念或从UTC偏移。您可以在代码中将其用作构建块,但必须通过offset-from-UTC类为其指定LocalDateTime
来确定实际时刻。
ZoneId
指定您的时区。
如果未指定时区,则JVM会隐式应用其当前的默认时区。在运行时(!)期间,该默认值可能是ZonedDateTime
,因此您的结果可能会有所不同。最好明确指定您期望/预期的时区作为参数。如果关键,请与您的用户确认该区域。
以ZoneId
的格式指定change at any moment,例如proper time zone name,Continent/Region
或America/Montreal
。切勿使用2-4字母缩写,如Africa/Casablanca
或Pacific/Auckland
,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。
EST
如果要使用JVM的当前默认时区,请求它并作为参数传递。如果省略,代码变得模糊不清,因为我们不确定您是否打算使用默认值,或者如果您像许多程序员一样,不知道这个问题。
IST
汇总您的日期和时间。
ZoneId z = ZoneId.of( "America/Montreal" ) ;
➥请注意,在这个例子中,我们的时间跨度可能只有2小时,但可能没有。它可能是3小时或其他一段时间,具体取决于该区域当时安排的那个日期的异常情况。
要计算经过时间,请使用ZoneId z = ZoneId.systemDefault() ; // Get JVM’s current default time zone.
计算天数(24小时的时间段,与日历无关),小时,分钟和秒。 (对于年 - 月 - 天,使用LocalDate startDate = LocalDate.of( 2019 , 1 , 23 ) ; // 23rd of January in 2019.
LocalTime startTime = LocalTime.of( 18 , 50 ) ; // 6:50 PM.
ZonedDateTime startMoment = ZonedDateTime.of( startDate , startTime , z ) ;
LocalDate stopDate = LocalDate.of( 2019 , 1 , 23 ) ; // 23rd of January in 2019.
LocalTime stopTime = LocalTime.of( 20 , 50 ) ; // Two hours later, exactly — maybe! Depends on any anomalies at that time in that zone.
ZonedDateTime stopMoment = ZonedDateTime.of( stopDate , stopTime , z ) ;
。)
Duration
在整个小时内询问整个时间跨度。
Period
在附带的pastebin中,开始时间为18:50,停止时间为20:49。如果我们输入这些数据,输出应该是2小时开始。现在,如果分钟相同,则不计入开始时间。但是如果我们将输入更改为20:51,那么它又开始了一个小时,因此DayHoursTotal应该等于3。
这种方法被称为半开放,当开头是包容性的,而结尾是独占的。这通常用于日期时间处理。 Duration d = Duration.between( startMoment , stopMoment ) ;
和long hours = d.toHours() ; // Entire duration as count of whole hours.
类适用于这种方法。
但要注意单独匹配分钟数。您的日期时间对象可能持有秒和/或小数秒,这会使您的算法失效。作为一种习惯,如果有可能比您想要更小的粒度,请明确截断日期时间对象。例如,Duration
。
显然,利率变化使问题复杂化。其他答案似乎已经涵盖了这一点,所以我不会重复。但我可以添加一个重要的提示:请参阅Period
的类ZonedDateTime.truncatedTo
和ThreeTen-Extra可能对您有所帮助。它们包括重叠,包含,邻接等方便的比较方法。
划分和阻碍
减少小块中的大逻辑使其更容易实现
Interval
直接计算最终价格。更新以存储总天数和夜间时间应该是一项挑战
我的例子的结果:
LocalDateRange
可能需要更多测试以确保它在所有条件下都很好,但对您来说应该是一个有用的起点