去停车费计算

问题描述 投票:0回答:4

好像,我找不到我的问题的答案,所以我在这里,首先在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。

预先感谢您的任何帮助。如果您对我的代码或想法有更多疑问,请询问。

java date time calculation parking
4个回答
2
投票

您似乎正在尝试计算不仅在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


0
投票

首先,您需要以不同方式解析整数。你的方法很危险,例如丢失信息。另外,如果有人试图输入无效的值,你需要使代码保险。请参阅此问题: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))); } }


0
投票

Time Zone

您的代码和其他答案无法解释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 nameContinent/RegionAmerica/Montreal。切勿使用2-4字母缩写,如Africa/CasablancaPacific/Auckland,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。

EST

如果要使用JVM的当前默认时区,请求它并作为参数传递。如果省略,代码变得模糊不清,因为我们不确定您是否打算使用默认值,或者如果您像许多程序员一样,不知道这个问题。

IST

组合日期,时间和区域以确定时刻

汇总您的日期和时间。

ZoneId z = ZoneId.of( "America/Montreal" ) ;  

➥请注意,在这个例子中,我们的时间跨度可能只有2小时,但可能没有。它可能是3小时或其他一段时间,具体取决于该区域当时安排的那个日期的异常情况。

Elapsed time

要计算经过时间,请使用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

Half-Open

在附带的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

Rate changes

显然,利率变化使问题复杂化。其他答案似乎已经涵盖了这一点,所以我不会重复。但我可以添加一个重要的提示:请参阅Period的类ZonedDateTime.truncatedToThreeTen-Extra可能对您有所帮助。它们包括重叠,包含,邻接等方便的比较方法。


0
投票

划分和阻碍

减少小块中的大逻辑使其更容易实现

Interval

直接计算最终价格。更新以存储总天数和夜间时间应该是一项挑战

我的例子的结果:

LocalDateRange

可能需要更多测试以确保它在所有条件下都很好,但对您来说应该是一个有用的起点

© www.soinside.com 2019 - 2024. All rights reserved.