-1

I'm writing a function that adds minutes to a time string - without using any libraries for Time. The function takes two arguments -

  1. The first, a "time" ([H]H:MM AM|PM) String, in the format of something like 12:00 AM or 3:30 PM (12-hour clock, no (24-hourclock) military time input)
  2. The second, an integer argument (positive or negative) as minutes, i.e. 200

Everything is fine-and-dandy until I came across adding negative minutes. For example, I can get the correct answer when having the first argument input as 02:00 AM, and the second argument input as -180, which should yield the answer of 11:00 PM.

My algorithm I use is to take my input String "time"/first argument, i.e. 02:00 AM, and convert/map that to military time (24-hour clock) for all my calculations (so I don't have to keep track of AM or PM), then I convert the entire thing to minutes, then I convert to hours and take % (modulo) with 24 (since 1 day is 24 hours) to get HOURS portion answer, and I use the previously computed minutes and % (modulo) with 60 to get the MINUTES portion of the answer.

In this example I gave above (02:00 AM) and (-180), would result in:

  1. 02:00AM == 120 minutes
  2. Add 120 minutes + (-180) minutes = -60 minutes
  3. Convert minutes (i.e. 60) to hours = -1 hr
  4. Use Math.floorMod(-1,24) = 23, to get the Hours portion of the answer. Using just % gives me the wrong answer of 1...
  5. Use -60 % 60 = 0, to get the MINUTES portion of the answer. Regular % operators works fine here
  6. Concatenate hours + minutes + AM/PM to return a String like 11:00 PM

I have been using the Math.floorMod(x,y), since the regular modulo % operator was not working for me, when subtracting and ending up with negative numbers that I needed to take the modulo of. I was now trying different inputs like 9:13 AM with -720 (half day) and -1440 (full day) of minutes and now I was getting some wrong answers.

It seems like when adding the minutes to a time using this modulus algorithm I always get the correct answer. Do I have to do something different now that I am essentially subtracting minutes and possibly ending up with negative numbers that I take modulo with 24?

Please let me know.

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
ennth
  • 1,698
  • 5
  • 31
  • 63
  • 2
    Why are you not using any library? If it’s for an exercise, it’s a good exercise, but for production code one should use [java.time, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/). And why are you keeping your time of day in a string? A representation involving numbers would seem more natural and practical to me. Like count of minutes since 00:00, from 0 through 1439, just to give one thinkable example.. – Ole V.V. Nov 01 '20 at 11:24
  • 1
    It would be easier to give a precise answer if we could see and maybe even try running your code. – Ole V.V. Nov 01 '20 at 11:27
  • @OleV.V. I can post the code, but its a lot of generic/obvious stuff like when I map to 24-hour clock (military time) , its just a gigantic-switch statement and its a lot of code/ugly and would fill up the page fast. I thought pseudo-code would be fine, since the problem is actually quite simple, despite how much I wrote. I see you posted a solution below, I will verify it in a minute here after breakfast :D thank you – ennth Nov 01 '20 at 12:19

1 Answers1

2

I am afraid that you may still get negative minutes. You may try adding for example -135 minutes rather than -180 and see what happens.

I think you will be better off reversing the operations:

  1. First use Math.floorMod(-60, 24 * 60) on the minutes to obtain 1380.
  2. Then convert the 1380 minutes to 23 hours.

This should ensure that minutes cannot be negative either.

Otherwise I think you’re fine.

PS Repeating myself from the comment: For production code use LocalTime from java.time, the modern Java date and time API for at time of day, and use its plusMinutes and minusMinutes methods for adding and subtracting minutes. Both of those methods accept positive and negative amounts of minutes.

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161