[Question]
  [
Implement a simple digital [Stopwatch](https://en.wikipedia.org/wiki/Stopwatch),
which will display the time elapsed in seconds and minutes, as described below.
> 
> **Important**
> 
> 
> Please read both *Display* and *Controls* sections !
> 
> 
> 
**Display**
Time elapsed, should be displayed in the `MM:SS` format,
by replacing the previously displayed time string "in-place"
(clearing the whole or a part of the screen is also allowed).
The stopwatch must be updated at least every second.
*Examples:*
0 minutes, 0 seconds
```
00:00
```
0 minutes, 33 seconds
```
00:33
```
1 minute, 50 seconds
```
01:50
```
Initially, you can start with '00:00' or with any other value in range [00:00-59:59].
Once your Stopwatch reaches `59:59`, it should reset to `00:00` and continue afresh.
You can use a different base (instead of decimal) or even a different numeral system if you wish, as long as you follow the general pattern.
For example `13:03` can be displayed as:
[Decimal](https://en.wikipedia.org/wiki/Decimal)
```
13:03
```
[Hexadecimal](https://en.wikipedia.org/wiki/Hexadecimal)
```
0D:03
```
[Base64](https://en.wikipedia.org/wiki/Base64)
```
N:D
```
[Quater-imaginary base](https://en.wikipedia.org/wiki/Quater-imaginary_base)
```
10101:3
```
[Roman Numerals](https://en.wikipedia.org/wiki/Roman_numerals)
```
XIII:III
```
Beware that if you use a non-decimal numeral system/base, it must be encoded using printable ASCII (or Unicode) characters, e.g. using two binary (unprintable) bytes for minutes and seconds is not allowed.
You must also left-pad your output with zeroes as appropriate, if your numerical system allows for that.
Replacing the separator character `:` with any other printable character (including digits) is also acceptable.
**Controls**
The stopwatch should start *paused*, and stay in this state, until user explicitly *starts* it, by pressing the *'control'* key (see below).
If, while stopwatch is counting, user presses the *'control'* key again, the stopwatch should *pause* (keeping the current time), until the *'control'* key is pressed a one more time.
The *'control'* key can be a single keystroke, e.g. `s`,
or any combination of keys, e.g. `Ctrl+Shift+X`, but it must be 'atomic', pressing multiple keys in sequence, e.g. `s` then `Enter`, is *not allowed*.
The same *'control'* key (or combination) must be used to *pause* and *resume* the stopwatch.
You must use a specific *'control'* key, i.e. 'any key' is not allowed.
Alternatively, you can use a single or double mouse-click, instead of a keypress for 'control'.
---
**Rules**
* This is [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'"), the shortest answer in bytes wins;
* Standard code-golf loopholes apply;
* Your program must (theoretically) be capable of running forever.
  
[Answer]
# Python 2, ~~167~~ 129 bytes
-36 bytes mostly\* from using [Maltysen's idea](https://codegolf.stackexchange.com/a/108487/53748) of catching `ctrl-c` using an exception - go give credit!  
-4 bytes thanks to DLosc (init `n` and `b` to 0 rather than `f()`)  
-1 byte thanks to FlipTack (use `p^=1` rather than `p=1-p`)  
-2 bytes thanks to Felipe Nardi Batista (remove precision specifiers)
```
import time
f=time.time
n=b=p=0
while 1:
 try:n=[n,f()][p];t=n-b;print'\r%02d:%02d'%(t/60%60,t%60),
 except:b=[b-n+f(),b][p];p^=1
```
Works the same as my original, below, but with the control key sequence of `ctrl+c`.  
(Tested by me with Python 2.7.8 on Windows 7, 64bit;  
Tested by Brian Minton with Python 2.7.13 on linux, 64bit)
\* also collapsed `if` statement to a list lookup in order to get the `try` as a one-liner.
My original:
```
import time,msvcrt as m
f=time.time
n=b=p=0
while 1:
 if m.kbhit()and m.getch()==b'p':b=[b-n+f(),b][p];p^=1
 if p:n=f()
 t=n-b;print'\r%0.2d:%0.2d'%(t/60%60,t%60),
```
(Tested by me with Python 2.7.8 on Windows 7, 64bit - this code, however, is Windows specific due to the use of the `msvcrt` library)
The control key is 'p'.
`n` and `b` are initialised to the same value at start-up, giving an "offset" of 0; `p` is initialised to 0, indicating a paused state.
Whenever the control key is pressed the value of `p` is switched. When switching from a paused state to an active state `b` is updated to a new value keeping any current offset from the previous active state(s) with `b-n`.
During an active state `n` is repeatedly updated to the current time by calling `time.time()`.
The difference between `n` and `b`, `t`, is then the total number of seconds (including a fractional part) elapsed during active state(s).
The minutes elapsed are then `t/60` and each of the minutes and seconds are displayed mod 60 with `(t/60%60,t%60)`. Leading zeros are prepended for each using string formatting of the integer part with `'...%0.2d...'`. Printing a tuple (the trailing `,`) where the first item has a leading carriage return (the `\r`) causes the previously printed text to be overwritten.
[Answer]
# SmileBASIC, ~~86~~ ~~77~~ 71 bytes
```
@L
N=N!=DIALOG(FORMAT$("%02D:%02D",F/60MOD 60,F MOD 60),,,N)F=F+1GOTO@L
```
`DIALOG` displays a textbox on the touch screen. `N` is the number of seconds the text box will stay on screen before it disappears. If `N` is `0`, it stays until the user presses the button on the touch screen.
`DIALOG` Returns `1` if the user pressed the button, and `0` if it closed automatically. So when the user pushes the pause button, it returns `1`, and the display time is set to `0`, pausing the stopwatch. After the user presses the button again, we set the display time back to `1`, resuming the timer. Basically, every time `DIALOG` returns `1`, the display time is switched between `1` and `0` using `!=`, which is eqivilant to a logical XOR as long as both inputs are 1 or 0.
[Answer]
# Python - ~~160~~ ~~159~~ 143 bytes
*Thanks to @JonathanAllan for saving me 18 bytes!*
Only uses builtin libraries, so the control key is `ctrl-c`, catching it with an `except keyboardInterrupt`.
```
import time
Z=0
print'00:00'
while 1:exec"try:\n while 1:\n  %s\nexcept:1\n"*2%(1,"print'\033c%02d:%02d'%divmod(Z%3600,60);Z+=1;time.sleep(1)")
```
[Answer]
# bash + Unix utilities, 90 or 93 bytes
**90-byte version:**
```
trap d=\$[!d] 2;for((n=0;;)){((d|!n))&&dc<<<DP60dod*d$n\r%+n|colrm 1 4&&: $[n++];sleep 1;}
```
**93-byte version:**
```
trap d=\$[!d] 2;for((n=0;;)){((d|!n))&&dc<<<DP60dod*$n+n|colrm 1 4&&n=$[(n+1)%3600];sleep 1;}
```
Ctrl-C is the resume/pause character. A space is the delimiter between minutes and seconds.
The difference between the two versions is that the 90-byte program will work for 2^63 seconds (at which point, bash will give me an integer overflow).
The 93-byte version will truly work forever.
The original problem included the requirement: "Your program must (theoretically) be capable of running forever."
If running for 2^63 seconds is sufficient to meet that requirement, then the 90-byte solution works. That duration is more than 20 times the age of the universe!
If the program needs to be able to run for longer than that, I'll have to go with the 93-byte solution.
---
I should probably point out that this solution, as well as at least some of the others posted, will *very* slowly fall behind the true elapsed time. This slippage is because the program is sleeping for one second between each execution of the body of the loop, but the body of the loop does take some tiny amount of time to execute. This will be inconsequential in practice.
[Answer]
# QBasic, ~~213~~ 211 bytes
Control key is tab. Leaving this running may cause laptop fires. You have been warned.
```
DO
WHILE k$<>CHR$(9)
k$=INKEY$
LOCATE 1
?CHR$(48+m\10);CHR$(48+(m MOD 10));":";CHR$(48+(d MOD 60)\10);CHR$(48+(d MOD 10))
IF r THEN
n=TIMER
d=v+n-b+86400
m=d\60MOD 60
END IF
WEND
k$=""
v=v+n-b
r=1-r
b=TIMER
LOOP
```
Here it is in action, pausing at 10, 15, and 20 seconds:
[![Stopwatch running](https://i.stack.imgur.com/FlWKZ.gif)](https://i.stack.imgur.com/FlWKZ.gif)
### Ungolfed and commented
```
' Outer loop runs forever
DO
  ' The WHILE-WEND loop runs until tab is pressed
  WHILE key$ <> CHR$(9)
    key$ = INKEY$
    ' Output the stopwatch value at top left of screen
    LOCATE 1
    ' Unfortunately, QBasic's PRINT USING doesn't have a format for printing
    ' with leading zeros, so we have to do it manually by printing the
    ' 10s digit and the 1s digit
    PRINT CHR$(48 + minute \ 10); CHR$(48 + (minute MOD 10));
    PRINT ":";
    PRINT CHR$(48 + second \ 10); CHR$(48 + (second MOD 10))
    ' Update the current time if the running flag is set
    IF running THEN now = TIMER
    ' Take the difference between now and the last time we started the
    ' stopwatch, plus the amount of saved time from previous runs,
    ' plus 86400 to account for the possibility of running over midnight
    ' (since TIMER is the number of seconds since midnight, and QBasic's
    ' MOD doesn't handle negative values like we would need it to)
    diff = saved + now - lastStarted + 86400
    second = diff MOD 60
    minute = diff \ 60 MOD 60
  WEND
  ' If we're outside the WHILE loop, the user pressed tab
  key$ = ""
  ' Add the previous run's time to the saved amount
  saved = saved + now - lastStarted
  ' Toggle running between 0 and 1
  running = 1 - running
  ' If we're starting, we want to put the current time in lastStarted;
  ' if we're stopping, it doesn't matter
  lastStarted = TIMER
LOOP
```
Note that values of `TIMER` are floating-point. This doesn't affect the output, since `MOD` and `\` truncate to integers. But it does add accuracy to the amount of saved time: if you pause the timer right before a tick, you'll see when you start it up again that the number changes in less than a second.
[Answer]
## Batch, 132 bytes
```
set/ar=0,m=s=100
:l
cls
@choice/t 1 /d y /m %m:~1%:%s:~1% /n
set/as+=r,m+=c=s/160,s-=c*60,m-=m/160*60,r^^=%errorlevel%-1
goto l
```
Pressing `n` will (un)pause the timer. The output flicker can be reduced at a cost of three (or four) bytes.
[Answer]
# Pure bash, 141 bytes
```
set -m
while ! read -t 1;do printf '\r%02i:%02i' $[s=s>3598?0:s+1,s/60] $[s%60];done&trap 'fg>/dev/null' TSTP
printf '00:00'
kill -STOP $!
read
```
This uses nothing but Bash builtins (no external tools). The control character is `Ctrl-Z`, so that standard `SIGTSTP` handling pauses the stopwatch.
* [`set -m` enables job control](https://www.gnu.org/software/bash/manual/bashref.html#The-Shopt-Builtin), which is usually off in a script.
* A [subshell](https://www.gnu.org/software/bash/manual/bashref.html#Command-Execution-Environment) process is [backgrounded (`&`)](https://www.gnu.org/software/bash/manual/bashref.html#Lists).
	+ [`read -t 1` waits one second for input from the user](https://www.gnu.org/software/bash/manual/bashref.html#index-read), then fails.
	+ The [`until` loop](https://www.gnu.org/software/bash/manual/bashref.html#Looping-Constructs) continues as long as `read` keeps failing.
	+ [`printf` outputs](https://www.gnu.org/software/bash/manual/bashref.html#index-printf) the correctly-padded and -formatted time
	+ `$[s=s>3598?0:s+1,s/60]` arithmetic expansion first [computes](https://www.gnu.org/software/bash/manual/bashref.html#Shell-Arithmetic) the updated time, checking whether to wrap and otherwise incrementing the seconds counter `s`, and then returns the floored division `s/60`.
	+ `$[s%60]` gives the seconds remainder.
* The outer script sets up a [`trap` handler](https://www.gnu.org/software/bash/manual/bashref.html#index-trap) for `TSTP`, the signal `Ctrl-Z` generates. When `Ctrl-Z` is pressed while the outer script is running, it will run [`fg>/dev/null` and put the subshell back into the foreground](https://www.gnu.org/software/bash/manual/bashref.html#index-fg). `>/dev/null` is necessary to stop `fg` printing out the subshell command every time.
* The script prints the initial `00:00` and [sends a `STOP` signal](https://www.gnu.org/software/bash/manual/bashref.html#index-kill) to the [child process `$!`](https://www.gnu.org/software/bash/manual/bashref.html#index-_0024_0021), which will pause the process.
* `read` waits for input forever, keeping the script alive.
If `Ctrl-Z` is pressed while the subshell is foregrounded, it will pause execution and return the outer script to the foreground, where it will wait silently. If the outer script is foregrounded, the trap handler will resume the subshell's execution, and it will count up again.
[Answer]
# Javascript in Chrome console, 143 bytes
```
f=document,m=s=g=i=0;setInterval(()=>{if(g%2){m=(i/60|0)%60;s=i++%60}f.write((m>9?m:'0'+m)+':'+(s>9?s:'0'+s));f.close();f.onclick=()=>g++},1e3)
```
When entered in console it inits the counter to 00:00 and then enables the control which is keypress on the document.
Not much magic going on, notably the `(i/60)|0` floors the number
Done and tested in Chrome console
[Answer]
# HTML + JavaScript (ES6), ~~191 192 187 183~~ 174 bytes
```
<b onclick='b=b?clearInterval(b):setInterval("a.innerHTML=`${(d=(((c=a.innerHTML.split`:`)[1]>58)+c[0])%60)>9?d:`0`+d}:${(e=++c[1]%60)>9?e:`0`+e}",1e3)'onload='b=0'id=a>00:00
```
### Explanation
Click the timer to start or pause the stopwatch. As such, a single click is the *control* key. The separator between the two values is a colon.
Whenever the user clicks the click, the value of `b` is checked. It is initialised to `0` which evaluates to `false`, so a string of code is evaluated every 1000 milliseconds. This sets the variable to the id of the interval, so it can be stopped later. If `b` contains a number, it evaluates to `true`, so the interval is stopped. This returns the value `undefined`, so the cycle continues.
The string of code changes the html of the element with id `a` (the stopwatch). First the minutes are parsed by taking the previous stopwatch value, splitting it by the colon, and getting the minutes value, which is increased by 0 if the value of the seconds is not 59 (greater than 58), and 1 otherwise, modulo 60. Then this value is padded. Then comes the colon, and lastly, the seconds. The code simply gets the old value, increases it by 1, takes modulo 60 and optionally pads it.
[Answer]
## C ~~309~~ 179 bytes
```
f(){m=0,s=0;A: while(getchar()^'\n'){if(s++==59){if(m++==59)m=0;s=0;}printf("\r%02d:%02d",m,s);sleep(1);system("clear");if(getchar()=='\n'){break;}}while(getchar()^'\n'){}goto A;}
```
Ungolfed version:
```
void f()
{
   int m=0,s=0;
   A: while(getchar()^'\n')
      {           
       if(s++==59)
       {
         if(m++==59)
           m=0;
         s=0;
       }
       printf("\r%02d:%02d",m,s);
       sleep(1);  
       system("clear");
        if(getchar()=='\n')
        {
          break;
        }
      }
       while(getchar()^'\n')
       {}
       goto A ;
}
```
Usage: Press `Enter` to *Pause* and *Resume* the Stopwatch.
Explanation:
* Wait for `Enter` keystroke, `break` the first `while` loop and wait until next `Enter` comes.
* Upon next `Enter` keystroke, `goto` first `while` loop and resume counting.
Now, I know `goto` is a bad coding practice in C, but I could not figure out another way.
[Answer]
# Javascript, 124 bytes
```
s=i=1,setInterval("s&&(d=document).close(d.write(`0${i/60%60|0}:`.slice(-3)+`0${i++%60}`.slice(-2))),d.onclick=_=>s=!s",1e3)
```
The 'control key' is a click on the document. 
To test this, paste the code in the console or in a html file inside the `<script>` tag.
*Explanation:*
```
let s = 1
let i = 1
setInterval(() => {
    //If s = true then check after the "&&" operator else false
    s && (d = document).close( //put the document variable inside the d variable, so now i don't need to use anymore the long word 'document, then i close the document
            d.write( //Write into the document the next string
                `0${i/60%60|0}:`.slice(-3) + `0${i++%60}`.slice(-2) //Here is the magic, here I update the 'i' variable and convert the 'i' value to minutes and seconds
            ) 
        ),
        d.onclick = _ => s = !s //Add onclick event to the document, if s = true then s = false, if s = false then s = true
}, 1e3) //1e3 = 1000
```
Tested in Chrome
[Answer]
# PHP, ~~94~~ 91 bytes
I assume that 32 is the key code for the space bar (which it probably is not);  
I currently have no way to test ncurses. But the rest of the code works fine.
```
for($s=[STDIN];;)echo date("\ri:s",$t+=$r^=stream_select($s,$n,$n,1)&&32==ncurses_getch());
```
starts at `00:00`, but increments immediately when pause ends
If You (like me) don´t have ncurses, You can test by replacing the second `date` parameter with `$t+=$r^=!rand(sleep(1),19);` or `$t+=$r^=++$x%20<1+sleep(1);`. (`sleep` always returns `0`.)
**breakdown**
```
for($s=[STDIN];                     // set pointer for stream_select
    ;                               // infinite loop:
)
    echo date("\ri:s",                  // 5. print CR + time
        $t+=                            // 4. increment $t if watch is running
        $r^=                            // 3. then toggle pause
            stream_select($s,$n,$n,1)   // 1. wait 1 second for a keystroke
            &&32==ncurses_getch()       // 2. if keystroke, and key==space bar
    ;
```
[Answer]
**C# 220 Bytes**
```
using static System.Console;
using static System.DateTime;
class P
{
    static void Main()
    {
        var l = Now;
        var d = l-l;
        for( var r = 1<0;;Write($"\r{d:mm\\:ss}"))
        {
            if (KeyAvailable&&ReadKey(1<2).KeyChar == 's')
            {
                l = Now;
                r = !r;
            }
            if (r)
                d -= l - (l = Now);
        }
    }
}
```
Golfed
```
using static System.Console;using static System.DateTime;class P{static void Main(){var l=Now;var d=l-l;for(var r=1<0;;Write($"\r{d:mm\\:ss}")){(KeyAvailable&&ReadKey(1<2).KeyChar=='s'){l=Now;r=!r;}if(r)d-=l-(l=Now);}}}
```
Using the `s` key to start/stop.
Whole program works by remembering the TimeDelta using `DateTime.Now`
Most C#-Magic here comes from the C# 7.0 feature `using static`.
[Answer]
Bash, 65 bytes 
`trap d=\$[!d] 2;for((;;)){ printf "\r%(%M:%S)T" $[n+=d];sleep 1;}`
Note that it must be written to a file script to work correctly, or else, try:
`bash -c 'trap d=\$[!d] 2;for((;;)){ printf "\r%(%M:%S)T" $[n+=d];sleep 1;}'`
Extended version to explain it:
```
trap d=\$[!d] 2                     # flip d for each INT (ctrl-c) signal.
for((n=0;;)){                       # repeat forever the code inside the {...}
                                    # The n=0 is not strictly needed.
    printf "\r%(%M:%S)T" "$[n+=d]"  # Print Minute:Second string calculated from 
                                    # the n value, increment by the value of d.
                                    # If IFS is not numeric (0-9), then, the
                                    # quotes around "$[n+=d]" could be removed.
    sleep 1                         # wait for 1 second.
}
```
The `%(...)T` format to printf is valid in bash 5+.
[Answer]
# Commodore BASIC (C64/TheC64 Mini, VIC-20, PET, C16/+4) - 147 tokenized and BASIC bytes
```
 0?"{clear}":geta$:ifa$<>" "thengoto
 1ti$="000000"
 2fori=.to1:?"{home}"mid$(ti$,3,2)":"mid$(ti$,5,2):geta$:b$=ti$:i=-(a$=" "):nE:pO198,.
 3geta$:ifa$<>" "then3
 4ti$=b$:goto2
```
`{clear}` in the listing is `SHIFT+CLR/HOME` which outputs as one PETSCII character when following an opening quotation mark, whereas `{home}` is the `CLR/HOME` key without the shift on the same condition of following an opening quotation mark.
Use the space bar as the control key.
To work with the Commodore 128 in BASIC 7, change the listing in the following lines:
```
 0?"{clear}":geta$:ifa$<>" "thengoto0
 2fori=.to1:?"{home}"mid$(ti$,3,2)":"mid$(ti$,5,2):geta$:b$=ti$:i=-(a$=" "):nE:poK198,.
```
Adds an extra seven tokens to the count (as all numbers are stored in BASIC as 7 bytes, so `goto10` is 8 tokenized bytes whereas `goto` is only 1).
[Answer]
# [C (gcc)](https://gcc.gnu.org/), ~~121~~ 115 bytes
```
p,r;g(){r^=1;}main(t,b){for(b=time(signal(2,g));;r?p=t:(b+=t!=p))t=time(0)-b,printf("\r%02d:%02d  ",t/60%60,t%60);}
```
[Try it online!](https://tio.run/##JcrBCsIwDADQX5mDQYIZ1h12WAj@iAhrdaXgaom5jX17Vby80wt9DKHWQsoRcNObnHlf55TByOO2vBS8WFof8E4xz08YKCIy66WITeCPYgcpiPZPDntPRVO2Bdqrdm64Tz@apiU7ja4bHdkX5L3WDw "C (gcc) – Try It Online")
Sets a signal handler for SIGINT, which is triggered by pressing control-C. We keep a time offset in `b`, and display the wall clock time minus the time offset. If we are paused, increment the time base everytime the wall clock ticks to freeze the displayed time.
Thanks to @ceilingcat for shaving off 6 bytes!
[Answer]
# Zsh + Gnu date, 242 bytes
Featuring 1/100ths of a second! It requires an interactive terminal, but [here's a TIO link](https://tio.run/##RY5PC4JAEMXv@ymWWCUpbTPo0OihQ7eI6BYqrOn6h7LMXYmK/ey2CtXl8d7wm5n3EkXXtWPrXfssT2PJ8cQQDO7/tGOgUKaJhscptiV16Nw0hwQnrWcF7VVwiQ@b/faoUK7RR1FeOF7BuwXpk6C24wiENtJY0ggq7cbSWCwptYU10yPEk@KGR2HD6qa8ygwb1E1XvWBSYSKYQ@7BfOpGYTKCDJRCnuf1DZ4w9Ggh9kmNfm8z@B4MeeCu@60B0U1kBDmorvsA) anyway. 
  
Hit `Enter` to start/stop the timer; `Ctrl-C` to exit.
```
u(){p=`gdate +%s`;q=`gdate +%N`;}
f(){read -t0.01&&{read;break};unset REPLY}
g(){while :;{u;t=$[p-a];s=$[t%60];m=$[(t%3600-s)/60]
echo "\r`printf %02d:%02d $m $s`.$q[1,2]\c";f;}}
<<<ready;read;u;a=$p
while :;{f;echo "\r\e[2A\c";u;a=$[p-t];g;}
```
Comments (a bit out of date):
```
u()echo $[`gdate +%s%N`/1000]       # fn:unix timestamp extended to µs
v()gdate +%s                        # fn:unix time, in s
f(){read -t0.01 -r&&{read -r;break;} # fn:listens for "Enter"
                      ;unset REPLY;}
g(){while :;                        # fn:rolling stopwatch
    {q=`u`;t=$[`v`-a]               #    t=time diff from baseline (s)
    ;echo "\r`printf %02d:%02d      #    format output
    $[(t%3600-s)/60] $s`            #    minutes:seconds
    .${q:10:2}\c";                  #    .xx = partial seconds
    f;}}                            #    listen for "Enter"
                                    # Execution starts here!
<<<ready;read;u;a=$p                # Wait for "Enter"; get baseline $a
while :;{                           # Main program loop
         f;                         # listen for an "Enter"
           echo "\r\e[2A\c"         # go up 1 line of the console
a=$[`v`-t]                          # reset the baseline
                ;g;}                # begin the stopwatch
```
]