56
\$\begingroup\$

Every digital clock contains a small creature that has to advance the time every minute [citation needed]. Due to the popularty of digital clocks and the popularity of catching them in the wild, they are nearly extinct in nature which is why in this challenge we try to automate this task:

Given your string of a given time in the 24h format, the task is to advance this time by one minute.

Details

  • Both the input and output must be strings.
  • The time is given as a five character string.
  • Both the hour and the minutes are given as a two digit number: if the number is below 10, there will be a leading zero.
  • The two numbers are separated by a colon.

Examples

Input    Output
00:00    00:01
00:02    00:03
05:55    05:56
09:59    10:00
12:49    12:50
20:05    20:06
23:59    00:00
\$\endgroup\$
3
  • 17
    \$\begingroup\$ Congratulations on finding a challenge in which Excel beats Jelly! \$\endgroup\$
    – ojdo
    Oct 6 at 13:58
  • 2
    \$\begingroup\$ [citation needed] 🤣 \$\endgroup\$ Oct 7 at 23:53
  • 3
    \$\begingroup\$ Ref: Pratchett. In Discworld, imps usually do that sort of thing. “Good Morning, Insert Name Here! I am the Dis-Organizer Mark Five, the Gooseberry™. How may I—” \$\endgroup\$
    – roblogic
    Oct 8 at 3:35

47 Answers 47

55
\$\begingroup\$

Microsoft Excel, 9 bytes

=A1+"0:1"

Input is in cell A1.
Tested on my Mac (Excel for Mac version 16.53) and online at Office.com.

enter image description here

\$\endgroup\$
6
  • \$\begingroup\$ Great tool for the job :) To be a little nitpicky: If you input truly a string as required by the challenge (eg. '23:59), you get a number in the cell with the formula. \$\endgroup\$
    – pajonk
    Oct 5 at 9:24
  • \$\begingroup\$ Thanks. I just tried '23:59 on my Excel for Mac 16.53 and somehow it still works (00:00 output)... Edit: it seems to work on Office.com, too... \$\endgroup\$ Oct 5 at 10:40
  • \$\begingroup\$ @pajonk i.stack.imgur.com/SVFFr.png \$\endgroup\$ Oct 5 at 10:48
  • \$\begingroup\$ @pajonk (after some trial-and-error) - It seems to depend on the order that the cells are created. I entered 23:59 into A1 first, and then typed-in the 9-byte =A1+"0:1". After that, other inputs - including explicit strings like '12:30 - produce the correct output. This seems to be because Excel automatically applied a custom date-like format to the formula cell (my cell A2). This doesn't necessarily happen if the cells are filled-in in a different order. Not sure whether (or how) this should be reflected somewhere in the byte-count... \$\endgroup\$ Oct 5 at 11:00
  • 1
    \$\begingroup\$ Also works in LibreOffice, but not in Google Sheets 😊 \$\endgroup\$ Oct 15 at 7:35
11
\$\begingroup\$

Bash + coreutils date, 17

date -d$1+min +%R

Try it online!

This assumes everything is in UTC (such as how TIO appears to be set up). If this is not OK, then 4 bytes must be added:


Bash + coreutils date, 21

date -ud$1UTC+min +%R

Try it online!

\$\endgroup\$
11
\$\begingroup\$

x86-16 machine code, 61 55 54 bytes

00000000: be82 008b fe8b d6ad 86c4 9346 56ad 86c4  ...........FV...
00000010: 4037 0430 3d30 367c 1293 4037 0430 3d34  @7.0=06|..@7.0=4
00000020: 327c 03b8 3030 86c4 abb0 305f 86c4 abb8  2|..00....0_....
00000030: 2409 aacd 21c3                           $...!.

Listing:

BE 0082     MOV  SI, 82H            ; SI point to DOS command line tail 
8B FE       MOV  DI, SI             ; save pointer to beginning of string for later 
8B D6       MOV  DX, SI             ; save pointer to beginning of string for output 
AD          LODSW                   ; load hours digits into AX 
86 C4       XCHG AL, AH             ; endian convert 
93          XCHG AX, BX             ; save hours in BX 
46          INC  SI                 ; skip colon 
56          PUSH SI                 ; save string offset to minutes 
AD          LODSW                   ; load minutes digits into AX  
86 C4       XCHG AL, AH             ; endian convert 
40          INC  AX                 ; add one minute 
37          AAA                     ; BCD Adjust After Addition! 
04 30       ADD  AL, '0'            ; ASCII fix low digit 
3D 3630     CMP  AX, '60'           ; is minutes wrap around? 
7C 13       JL   NO_CARRY_HOUR      ; if not, skip hours 
93          XCHG AX, BX             ; move hours into AX 
40          INC  AX                 ; increment hours 
37          AAA                     ; BCD Adjust After Addition! 
04 30       ADD  AL, '0'            ; ASCII fix low digit 
3D 3234     CMP  AX, '24'           ; rolled over to 24 hours? 
7C 03       JL   NO_CARRY_DAY       ; if not, skip to convert 
B8 3030     MOV  AX, '00'           ; reset hours to '00' 
        NO_CARRY_DAY: 
86 C4       XCHG AL, AH             ; endian convert 
AB          STOSW                   ; write hours string 
B0 30       MOV  AL, '0'            ; reset minutes to '00' 
        NO_CARRY_HOUR: 
5F          POP  DI                 ; minutes string offset to DI 
86 C4       XCHG AL, AH             ; endian convert 
AB          STOSW                   ; write minutes to output string 
B8 0924     MOV  AX, 0924H          ; AL = '$', AH = write string function 
AA          STOSB                   ; write DOS string terminator to end of string 
CD 21       INT  21H                ; write output to console 
C3          RET                     ; return to DOS

Thought it would be a more straightforward use of BCD operations, though it gave me a use for the AAA instruction so there's that.

Standalone DOS executable. Input via command line, output to console.

enter image description here

OR...

21 bytes if I could take I/O as a packed BCD hex word (12:59 == 0x1259), and get to use AAA's bastard step-sibling DAA!

40          INC  AX             ; increment the time 
27          DAA                 ; decimal adjust packed BCD 
3C 60       CMP  AL, 60H        ; did minutes reach 60? 
7C 0E       JL   DONE           ; if not, do nothing else 
32 C0       XOR  AL, AL         ; otherwise, reset minutes to 0 
86 E0       XCHG AH, AL         ; swap hours and minutes in AL 
40          INC  AX             ; increment the hours 
27          DAA                 ; decimal adjust packed BCD 
3C 24       CMP  AL, 24H        ; did hours reach 24? 
86 E0       XCHG AH, AL         ; real quick, swap hours and minutes back 
7C 02       JL   DONE           ; if less than 24, do nothing else 
32 E4       XOR  AH, AH         ; otherwise, reset hour to 0 
        DONE: 
C3          RET
\$\endgroup\$
2
  • 2
    \$\begingroup\$ I'm impressed. Apparently BCD still has a use, if only in code golf. \$\endgroup\$
    – rosuav
    Oct 8 at 4:15
  • 1
    \$\begingroup\$ @rosuav "AAA and DAA are extremely useful x86 instructions." -no one ever \$\endgroup\$
    – 640KB
    Oct 8 at 4:20
9
\$\begingroup\$

PHP, 35 bytes

<?=date("H:i",strtotime($argn)+60);

Try it online!

\$\endgroup\$
3
  • \$\begingroup\$ Nice answer! On older PHP you can save 1 byte using a bit flipped string (~"H:i") as a default constant instead of "H:i" but it's probably not worth the hassle! \$\endgroup\$ Oct 6 at 17:43
  • 1
    \$\begingroup\$ Could you elaborate on that, @DomHastings? Can't figure out how that'd work. \$\endgroup\$
    – Shaggy
    Oct 14 at 23:15
  • \$\begingroup\$ Of course! I probably didn't explain it very well! But basically ~"..." bitflips the string see this example from this answer, and the resulting high-byte string can be used as a bare word constant to save 1 byte on the quotes. But it does add extra faff to the answer! Hope that helps! \$\endgroup\$ Oct 15 at 7:33
9
\$\begingroup\$

brainfuck, 216 bytes

,++++++++>,>>,>+>,++++>,+<<<[-<<-<-<+>>>>>>->-<<<]>>>[<<-]<<[>>----------<+[<-]<[->------<<<+<+[++++++[>-]>[<<[>>-]>>[<----<-->>->>]<]<<------>]>[<----------<+>>->]]<]<<<[->+>+>>+>>+>+<<<<<<<]>--------.>.>>.>>----.>.

Try it online!

The character : is the ASCII character after 9, so the program uses the one provided to it in the input to check if digits need to be carried, allowing it to avoid creating any large constants.

[
Read in the string and set up for the comparisons later. Increment minutes.
Subtract ':' from all characters and copy it elsewhere.
Layout:        Cell #  -1  0 1 2 3 4 5 6
        Cell contents  ':' A B _ _ 1 C D
The central 0 and 1 cells allow all of the conditionals to land near each other,
reducing the amount of travel needed in the worst case.
]
,++++++++>,>>,>+>,++++>,+
<<<[-<<-<-<+>>>>>>->-<<<]
# If minutes are 10: Carry
>>>[<<-]<<[
    >>----------<+
    # If tenminutes are 6: Carry
    [<-]<[
        ->------<<<+<+
        # If hours are not 10: Check for 24:00 rollover
        [
            ++++++
            [>-]>[
                <<[>>-]>>[
                    <----<--
                >>->>]
            <]
            <<------
        # If hours are 10: Carry
        >]>[
            <----------<+
        >>->]
    ]
<]
# Undo modifications from the start and print
<<<[->+>+>>+>>+>+<<<<<<<]
>--------.>.>>.>>----.>.
\$\endgroup\$
1
  • 1
    \$\begingroup\$ Welcome to Code Golf! Nice answer! \$\endgroup\$ Oct 13 at 3:57
8
\$\begingroup\$

Java (JDK), 83 49 bytes

i->java.time.LocalTime.parse(i).plusMinutes(1)+""

Try it online!

Huge cut-off thanks to Olivier Grégoire

\$\endgroup\$
1
  • 2
    \$\begingroup\$ 49 bytes by just using LocalTime rather than LocalDateTime \$\endgroup\$ Oct 7 at 7:37
8
\$\begingroup\$

Python 2, 68 bytes

def f(s):v=int(s[:2])*60-~int(s[3:]);print'%02d:%02d'%(v/60%24,v%60)

Try it online!

Python 3.8, 65 64 bytes

-1 byte thanks to @Matthew Willcockson

lambda s:f"{(v:=int(s[:2])*60-~int(s[3:]))//60%24:02}:{v%60:02}"

Try it online!

\$\endgroup\$
4
  • 1
    \$\begingroup\$ What's amazing is a more normal script version is less than 50 characters longer: import datetime as d,sys;f="%H:%M";print((d.datetime.strptime(sys.argv[1],f)+d.timedelta(minutes=1)).strftime(f)) \$\endgroup\$ Oct 7 at 10:33
  • \$\begingroup\$ Also, with Python 3 a single character can be shaved off with f-strings: lambda s:f"{(v:=int(s[:2])*60-~int(s[3:]))//60%24:02}:{v%60:02}" \$\endgroup\$ Oct 7 at 10:49
  • \$\begingroup\$ @MatthewWillcockson Thanks, I somehow missed that! \$\endgroup\$ Oct 10 at 22:48
  • 1
    \$\begingroup\$ @MatthewWillcockson if you're so inclined, you can golf the "more normal" version down such that it's only 34 bytes longer tio.run/… \$\endgroup\$ Oct 11 at 9:54
7
\$\begingroup\$

MATL, 12 bytes

YOl13L/+15XO

Beaten by Excel... :-D

Try it online! Or verify all test cases.

Explanation

YO     % Implicit input. Convert to date number. The integer part represents date,
       % the fractional part represents time of day
l      % Push 1
13L    % Push 1440 (predefined literal)
/      % Divide. Gives 1/1440, which is 1 minute expressed as fraction of a day
+      % Add
15XO   % Convert to date string with format 15, which is 'HH:MM'
       % Implicit display
\$\endgroup\$
6
\$\begingroup\$

Jelly,  20  19 bytes

ØDṗ2ḣ“ð<‘Œpj€”:ðṙiḢ

A monadic Link that accepts a list of characters and yields a list of characters.

Try it online!

How?

Surprisingly tricky to get anything below 22 in Jelly, no time-based functionality while parsing, evaluating and then adding leading zeros where needed is expensive, so I went with constructing all strings as a list and getting the next string cyclically.

ØDṗ2ḣ“ð<‘Œpj€”:ðṙiḢ - Link: characters, S
ØD                  - digit characters -> "0123456789"
  ṗ2                - Cartesian power 2 -> ["00",...,"99"]
     “ð<‘           - list of code-page indices -> [24, 60]
    ḣ               - head to -> [["00",..."23"],["00",...,"59"]]
         Œp         - Cartesan product -> [["00","00"],...,["23","59"]]
           j€”:     - join each with colons -> ["00:00",...,"23:59"]
               ð    - start a new dyadic chain, f(Times, S)
                 i  - first 1-indexed index of S in Times
                ṙ   - rotate Times left by that
                  Ḣ - head
\$\endgroup\$
6
\$\begingroup\$

Powershell, 82 or 153 bytes

get-date ((get-date ($Time=read-host "Enter the time")).addminutes(1)) -uformat %R

Or, if you want to show the input as well as the output;

do {$Time=read-host "Enter the time"
    write-host -nonewline $time `t 
    get-date ((get-date $Time).addminutes(1)) -uformat %R
    } while ($Time)
\$\endgroup\$
1
  • \$\begingroup\$ Welcome to Code Golf, and nice first answer! Make sure to check out our tips for golfing in Powershell to see if there are any ways for you to shorten your answer. \$\endgroup\$ Oct 6 at 2:20
5
\$\begingroup\$

Retina 0.8.2, 32 bytes

T`_d`d0`.9?(:59)?$
T`d`0`(24)?:6

Try it online! Link includes test cases. Explanation:

T`_d`d0`.9?(:59)?$

Increment all the digits in 09:59, 19:59, X:59, :X9 or just the last digit if nothing else matches. Incrementing 9 automatically rolls over to 0.

T`d`0`(24)?:6

Zero out 24:60 and the seconds of X:60 (X will already have been incremented above so it is correct).

\$\endgroup\$
5
\$\begingroup\$

JavaScript (Chrome / Edge / Node), 50 bytes

Very hackish.

s=>(new Date(+new Date([1,s])+6e4)+s).slice(16,21)

Try it online!

Commented

s =>              // s = "HH:MM"
  ( new Date(     // generate a date:
      +new Date(  //   generate a timestamp corresponding to:
        [1, s]    //     "1,HH:MM" which is interpreted as
                  //     Mon Jan 01 2001 HH:MM:00
      )           //   end of Date()
      + 6e4       //   add 60000 milliseconds (1 minute)
    )             // end of Date()
    + s           // coerce to a string
  ).slice(16, 21) // extract the updated "HH:MM"
\$\endgroup\$
5
\$\begingroup\$

C#, 64 62 55 bytes

-7 bytes thanks to asherber

(x)=>$"{System.DateTime.Parse(x).AddMinutes(1):HH:mm}";

dotnetfiddle!

Old version (62 Bytes)

(x)=>System.DateTime.Parse(x).AddMinutes(1).ToString("HH:mm");
\$\endgroup\$
1
  • 3
    \$\begingroup\$ Save a few bytes with string interpolation. (x)=>$"{System.DateTime.Parse(x).AddMinutes(1):HH:mm}"; \$\endgroup\$
    – asherber
    Oct 13 at 14:32
4
\$\begingroup\$

Python 3, 100 bytes

from datetime import*
f='%H:%M'
t=lambda s:(datetime.strptime(s,f)+timedelta(minutes=1)).strftime(f)

Try it online!

Python is terrible at this...

\$\endgroup\$
1
  • \$\begingroup\$ Ah, you are correct. Reverted \$\endgroup\$
    – Seggan
    Oct 4 at 22:57
4
\$\begingroup\$

Ruby -pl, 40 bytes

$_="#{Time.gm(1,1,~/:/,$`,$')+60}"[11,5]

Try it online!

~/:/ matches the colon in the input (yielding its index, 2), setting the pre- and post-match regexes $` and $' to the hour and minute, respectively.


Ruby -plaF:, 35 bytes

Suggested by @dingledooper

$_="#{Time.gm(1,1,1,*$F)+60}"[11,5]

Try it online!

The array $F is formed by automatically splitting the input at the colon.


Both versions perform the following operations:

  • convert input to a Time object,
  • add 60 seconds,
  • convert to a string of the form 0001-01-dd hh:mm:00 UTC, where for the 40 byte version dd is either 02 or 03 (the latter only when the input is 23:59); for the 35 byte version it is 01,
  • extract the 11th to 15th characters.

It's somewhat noteworthy that Time#gm internally coerces string arguments to integers.

\$\endgroup\$
4
  • \$\begingroup\$ For more flag abuse, you might be able to do $_="#{Time.gm(1,1,1,*$F)+60}"[11,5]+-plaF: \$\endgroup\$ Oct 4 at 23:04
  • \$\begingroup\$ @dingledooper Thanks! Using -F: felt a bit too cheaty but I've added it as an alternative. \$\endgroup\$
    – Dingus
    Oct 4 at 23:23
  • 1
    \$\begingroup\$ This combo is perhaps even more cheaty: $_="#{Time.parse($_)+60}"[11,5] + -plrrss :P \$\endgroup\$ Oct 5 at 0:23
  • \$\begingroup\$ @dingledooper Gotta love a monkey patch. We haven't even got to -e yet ;) \$\endgroup\$
    – Dingus
    Oct 5 at 1:07
4
\$\begingroup\$

C (gcc), 71 69 bytes

Thanks to dingledooper for the -2.

The only sneaky things were to reuse the input parameter and cache the format string.

i,z;f(s){sscanf(s,z="%02d:%02d",&i,&s);printf(z,(i+s/60)%24,++s%60);}

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ One other sneaky thing you can do is to reuse the input format string, with i,z;f(s){sscanf(s,z="%02d:%02d",&i,&s);printf(z,(i+s/60)%24,++s%60);} ;) \$\endgroup\$ Oct 5 at 3:42
4
\$\begingroup\$

05AB1E, 18 bytes

23Ý59ÝâT‰J':ýDIk>è

Try it online or verify all test cases.

Explanation:

23Ý                 # Push a list in the range [0,23]
   59Ý              # Push a list in the range [0,59]
      â             # Get the cartesian product of these two lists
       T‰J          # Format each integer to a string with potentially leading 0:
       T‰           #  Take the divmod-10: [n//10,n%10]
         J          #  And join these pairs of digits together
          ':ý      '# Join each inner pair together with ":" delimiter
             D      # Duplicate this list
              Ik    # Get the index of the input in this duplicated list
                >   # Increase it by 1
                 è  # And use it to index into the list
                    # (after which the result is output implicitly)
\$\endgroup\$
1
  • \$\begingroup\$ Wow. Much better than my clunky one \$\endgroup\$
    – wasif
    Oct 5 at 9:20
3
\$\begingroup\$

PHP, 40 bytes

fn($s)=>date('H:i',strtotime("$s+1min"))

Try it online!

PHP relative date formatting at its finest, trying to compress it to the max. Should take in account the DST following the locale

\$\endgroup\$
2
  • \$\begingroup\$ 36 bytes or 35 bytes \$\endgroup\$
    – Shaggy
    Oct 5 at 13:34
  • \$\begingroup\$ @Shaggy That's a significant improve compared to my answer, if you want to post as your own, be sure I'll upvote it! \$\endgroup\$
    – Kaddath
    Oct 5 at 13:38
3
\$\begingroup\$

MathGolf, 24 bytes

╟r■gæ├M<Þmò♀+░m╞':u_l=)§

Try it online.

Explanation:

╟r                       # Push a list in the range [0,60)
  ■                      # Take the cartesian product with itself
   g                     # Filter this list of pairs by,
    æ                    # using the following four characters as inner code-block:
     ├  Þ                #  Where the first value of the pair
      M<                 #  Is smaller than 24
         m               # Then map each remaining pair to,
          ò              # using the following eight characters as inner code-block:
           ♀+            #  Add 100 to both integers
             ░           #  Convert both to a string
              m╞         #  Remove the first character (the "1") from both strings
                ':u     '#  Join this pair with ":" delimiter
                   _     # After the map, duplicate the list of all possible times
                    l=   # Get the index of the string-input in this duplicated list
                      )  # Increase it by 1
                       § # And use it to (0-based modulair) index into the list
                         # (after which the entire stack is output implicitly as result)
\$\endgroup\$
3
\$\begingroup\$

SQL Server, 36 bytes

select left(dateadd(n,1,a),5) from t

Try it online (using all of the input values given in the question).

\$\endgroup\$
3
  • 2
    \$\begingroup\$ Welcome to Code Golf! \$\endgroup\$ Oct 14 at 1:08
  • 1
    \$\begingroup\$ Your post has an extra space before the 5 that's not there in the actual code. \$\endgroup\$
    – Neil
    Oct 14 at 16:29
  • \$\begingroup\$ Thanks, @Neil, I fixed it. Doesn't lower my score, though, unfortunately - the score was based on the correct version that didn't have the extra space. \$\endgroup\$ Oct 14 at 17:10
3
\$\begingroup\$

R, 46 43 bytes

-3 bytes thanks to Jonathan Carroll

Or R>=4.1, 36 bytes by replacing the word function with \.

function(t)format(strptime(t,h<-"%R")+60,h)

Try it online!


Without datetime functions:

R, 89 85 bytes

function(t,`[`=substr,m=el(t[4,5]:0+1)%%60)sprintf("%02d:%02d",el(t[1,2]:0+!m)%%24,m)

Try it online!

\$\endgroup\$
1
  • 1
    \$\begingroup\$ R4.1 function syntax really helps with golfing, but also %R is equivalent to %H:%M... \(t)format(strptime(t,h<-"%R")+60,h) for 36. \$\endgroup\$ Oct 14 at 23:27
3
\$\begingroup\$

PowerShell, 33 bytes

%{'{0:HH:mm}'-f((Date $_)+'0:1')}

Input comes from the pipeline.

Try it online!

Try it in a PS console (Windows or Core):

 '00:00', '00:02', '05:55', '09:59', '12:49', '20:05', '23:59'|%{'{0:HH:mm}'-f((Date $_)+'0:1')}

Explanation

% is an Alias for the Cmdlet "ForEach-Object", which accepts input from the pipeline and processes each incoming object inside the ScriptBlock {...}
'{0:HH:mm}' is the output string; {0:HH:mm} is a placeholder for the first argument of the following -f format operator. It contains formatting information to print a DateTime object in 24 hour format.
-f is the format operator, which will replace the placeholder with the actual time. Using -f is shorter than calling the .ToString('HH:mm') method.
((Date $_)+'0:1') does the heavy lifting: It first turns the current string coming in from the pipeline ($_) into a DateTime object by passing it to the Cmdlet Get-Date. The 'Get-' is implicit in PS, so leaving it out saves 4 bytes (Disclaimer: never use that in a regular script; it slows things down, because PS will search the path for a matching command as well - each time it's called!).
Now that there's a DateTime object on the left side, and PS sees an Add operation, it interpretes the '0:1' as timespan of 1 minute (try [TimeSpan]'0:1' in a PS console); this is shorter than using the DateTime's object AddMinutes() method.
The result of the addition is then inserted into the string, output is implicit.

\$\endgroup\$
2
\$\begingroup\$

Scala, 52 bytes

java.time.LocalTime.parse(_).plusMinutes(1).toString

Try it online!

Straightforward approach: parse string as time information via built-in functionality, add one minute to it, output as string

\$\endgroup\$
2
\$\begingroup\$

Factor, 56 bytes

[ ":"without hhmm>duration 1 minutes time+ duration>hm ]

This doesn't run on TIO because the calendar.parser vocabulary postdates Factor build 1525 (the one TIO uses) by just a bit. Here's a screenshot of running it in build 1889, the official 0.98 stable release:

A screenshot of running the above code in the Factor Listener

Explanation

It's a quotation that takes a string from the data stack as input and leaves a string on the data stack as output. Assuming "23:59" is on top of the data stack when this quotation is called...

Snippet Comment Data stack (the bottom is the top)
":"without
Remove the colon
"2359"
hhmm>duration
Parse a 4-digit string into a duration with hours and minutes
T{ duration f 0 0 0 23 59 0 }
1 minutes
Create a duration of one minute
T{ duration f 0 0 0 23 59 0 }
T{ duration f 0 0 0 0 1 0 }
time+
Add two durations and/or timestamps
T{ duration f 0 0 0 23 60 0 }
duration>hm
Convert a duration or timestamp to a HH:MM string
"00:00"
\$\endgroup\$
2
\$\begingroup\$

Batch, 83 bytes

@set/ps=
@set/am=6%s::=*60+1%-99,h=m/60%%24+100,m=m%%60+100
@echo %h:~-2%:%m:~-2%

Takes input on STDIN. Explanation:

@set/ps=

Read in the time.

@set/am=6%s::=*60+1%-99,h=m/60%%24+100,m=m%%60+100

Batch parses leading 0s as octal, so to allow hours and minutes to be 08 or 09, 6 is prefixed to the hours and 1 to the minutes. Additionally, the : is changed to *60+ and the resulting string evaluated. The 6 prefix does not change the overall result because 600 hours is exactly 25 days, while the 1 adds 100 minutes so 99 minutes are subtracted to obtain the desired total number of minutes. The total minutes are then divided back into hours and minutes, but with 100 added so that the last two digits can be extracted.

@echo %h:~-2%:%m:~-2%

Print the last two digits to get the real hours and minutes again.

\$\endgroup\$
2
\$\begingroup\$

Japt, 13 bytes

Ð6e4°ÐNi1¹¤¯5

Try it

\$\endgroup\$
2
\$\begingroup\$

QBasic, 132 bytes

INPUT t$
i=6
1i=i-1+f
x=ASC(MID$(t$,i))-47
f=i=4
x=x<10+f*4AND x
MID$(t$,i,1)=CHR$(x+48)
IF x=0GOTO 1
IF"24:00"=t$THEN t$="00:00
?t$

Try it here!

Explanation

' Read the input time into t$
INPUT t$
' i is the index of the current digit, starting one digit to the right of the string
i = 6
' Label 1 is the start of the loop
1
' Subtract 1 from i, and subtract an additional 1 if f is set (see below)
i = i - 1 + f
' x is the current digit plus 1
x = ASC(MID$(t$, i)) - 47
' f is true (-1) only when i = 4
f = (i = 4)
' If x = 10, or if f is true and x = 6, set x to 0; otherwise, leave it unchanged
x = x < (10 + f * 4) AND x
' Write that digit back into the string t$ at the current position
MID$(t$, i, 1) = CHR$(x + 48)
' Loop if this digit wrapped around to 0
IF x = 0 THEN GOTO 1
' Special-case wrapping around to 00:00
IF "24:00" = t$ THEN t$ = "00:00"
' Print the final result
PRINT t$
\$\endgroup\$
2
\$\begingroup\$

C (clang), 63 bytes

f(*s){strptime(s,"%R",s);*s=84;mktime(s);strftime(s,8,"%R",s);}

Try it online!

Thanks to @AZTECCO for the "%R" format!!

\$\endgroup\$
0
2
\$\begingroup\$

Julia 1.0, 66 bytes

using Dates;f="HH:MM";g(s)=Dates.format(DateTime(s,f)+Minute(1),f)

Try it online!

Using libraries because why not and it's still shorter than Python.

\$\endgroup\$
2
\$\begingroup\$

C (gcc), 101 bytes

I was hoping this would be shorter, but I am posting it despite the length because I think it's an interesting way to compute the answer.

This function modifies the input string so the output is the input. I'm not too familiar with the C golfing rules on this but since it's so long I'm neglecting that issue.

This function treats the input as individual characters, where each column has a 'max' value (the first 5 characters in u) and a 'reset' value (last 5 characters in u). First the last character of the input string is incremented, then from right to left each character is compared to the max. If any character is greater than its max, it is set to the 'reset' value of that column and the column to the left is incremented.

As described so far, this function will reset after 29:59. To make it reset after 23:59 I used short *a to check the first two characters at once to see if they equal "24" and if they do, set them to "00".

Also note that I had to modify the test code in order to copy input strings into writable memory.

Improvements are welcome, I think I'm out of ideas on this one.

Thanks to att for -22 bytes, a bugfix, and some awesome golfing!

c;f(char*x){for(x[c=4]++;~c;)x[--c]+=x[c]>"29:59"[c]&&(x[c]=c-2?48:58);*x<49&&x[1]==52?*x=x[1]=48:0;}

Try it online!

\$\endgroup\$
2
  • 1
    \$\begingroup\$ 114 bytes and a bugfix (e.g. "05">"24" is true) \$\endgroup\$
    – att
    Oct 16 at 5:19
  • 1
    \$\begingroup\$ 103 bytes with a couple alternatives, but getting rid of short* yields 101... \$\endgroup\$
    – att
    Oct 16 at 5:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.