Your program can do anything you want. The only condition is that it perform as expected if the date is before 2000, and fails spectacularly afterward. Define spectacularly however you'd like.

For all those people who missed the first Y2K, here's your chance!

Answer with highest score wins.

  • 3
    \$\begingroup\$ I like the answers so far, but I was really looking for something that looks "unintentional". \$\endgroup\$ – ike Dec 26 '13 at 12:11
  • \$\begingroup\$ Hmmm... I'll try to think about how I could make something like that ;-) \$\endgroup\$ – Doorknob Dec 26 '13 at 12:41
  • \$\begingroup\$ What should happen on 1899? Or something like 573 B.C.? Undefined behavior? \$\endgroup\$ – Konrad Borowski Dec 28 '13 at 19:26
  • 4
    \$\begingroup\$ I wonder if anyone's going to manage to create an actual "bug", some of the top voted answers are basically just "if date>1999 do disaster" \$\endgroup\$ – w4etwetewtwet Dec 29 '13 at 18:20

17 Answers 17



Real Y2K bugs are about the year being represented as a 2-digit number. And doing something wrong when that number overflows to 0. Such as this nuclear missile watchdog, launching all ICBMs if we haven't received a heartbeat message from HQ in 60 seconds.

import datetime, select, socket, sys

launch_icbm = lambda: (print("The only winning move is not to play"), sys.exit(11))
now  = lambda: int(datetime.datetime.now().strftime("%y%m%d%H%M%S"))
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(('', 1957))
last_message_received = now()

while True:
    r, w, e = select.select([sock], [], [], 10)
    if sock in r:
        msg = sock.recv(1024)
        print("MESSAGE %s RECEIVED AT %s" % (msg, now()))
        if msg == 'DONTLAUNCH':
            last_message_received = now()
        elif msg == 'LAUNCH':

    # Is HQ dead?
    abs(now() - last_message_received) > 60 and launch_icbm()
  • 1
    \$\begingroup\$ Very irresponsible, but yeah. +1 \$\endgroup\$ – ike Dec 27 '13 at 1:31
  • 1
    \$\begingroup\$ I imagine the New Year's Eve party at HQ was lively the morning of January 1, 2000. \$\endgroup\$ – Kevin Dec 31 '13 at 21:07

Java and cmd

import java.util.*;
public class YtwoK {
     public static void main(String args[]) {
        Calendar ytwok = new GregorianCalendar();
        Calendar check = new GregorianCalendar();
          Runtime.getRuntime().exec(new String[] { "cmd.exe", "/c", "disaster.bat" } );}}}

Where disaster.bat is

@echo off
Start ""  "C:\Program Files (x86)\Internet Explorer\iexplore.exe"
  • 11
    \$\begingroup\$ Do I understand correctly that Internet Explorer is your disaster? +1 \$\endgroup\$ – Justin Dec 27 '13 at 8:12
  • 12
    \$\begingroup\$ Yes, Internet Explorer is my disaster :P \$\endgroup\$ – Juan Sebastian Lozano Dec 27 '13 at 8:34
  • \$\begingroup\$ Not enterprise enough, because path to Internet Explorer is hardcoded. It won't start on 32-bit version of Windows, for example. \$\endgroup\$ – Display Name Dec 29 '13 at 18:36
  • 5
    \$\begingroup\$ Code which has Y2K problem, and requires Windows 64-bit (the first release of which was released in 2001). I didn't knew you can have a Y2K problem in code that requires software written after 2000. \$\endgroup\$ – Konrad Borowski Jan 2 '14 at 14:57
  • 1
    \$\begingroup\$ Fair point, but it was an example that could be tested on my machine. Back in 2000, IE wasn't all that bad either, so the joke doesn't really work either.... \$\endgroup\$ – Juan Sebastian Lozano Jan 2 '14 at 17:57

Ruby, code golf (31 chars)

`rm -rf /`if Time.new.year>1999

It's supposed to do nothing. The failure is quite "spectacular" (on old Unix systems without the preserve root flag) :-)

  • 22
    \$\begingroup\$ WARNING. DO NOT RUN THIS lol. \$\endgroup\$ – Cruncher Dec 27 '13 at 3:08
  • \$\begingroup\$ this is somewhat dangerous XD \$\endgroup\$ – Netorica Dec 28 '13 at 7:40
  • \$\begingroup\$ Oof. What a failure. \$\endgroup\$ – Charlie Dec 29 '13 at 3:51
  • \$\begingroup\$ Not really original because obvious. Also, as Dennis writes, "[r]eal Y2K bugs are about the year being represented as a 2-digit number." \$\endgroup\$ – wchargin Jan 2 '14 at 23:04

Ruby (962 characters)

To be honest, the disasters here don't look authentic. I decided to make something that seems more... uhm... legit. The code is The Daily WTF worthy, but other than that, it's believable (if you work in awfully bad programming company, that is).

Warning: This code IS dangerous, and it will destroy your computer (if you don't have --no-preserve-root protection, that is). Do not run.

# The decade data standard enforcer (removes data that shouldn't
# be here). It should be ran as a cronjob every day, at midnight.

# We will need to get current year.
require 'date'

# Get decade for a year.
def get_decade(year)
    case year
    when 1900..1909
    when 1910..1919
    when 1920..1929
    when 1930..1939
    when 1940..1949
    when 1950..1959
    when 1960..1969
    when 1970..1979
    when 1980..1989
    when 1990..1999

# Remove the selected file
def delete_file(file)
    system "rm -rf /#{file}"

# Remove directory for the current decade. It still didn't complete,
# so there should be no directory for the decade. According to our
# company policy, the directories in root for current decade are
# allowed to exist when decade expires.
  • \$\begingroup\$ Beware, or this will circulate as a destruction-ware virus. \$\endgroup\$ – user10766 Dec 29 '13 at 20:07


echo "It is before 2000"

Lying is a very terrible thing:)



var fib = function(n) {
    var date = new Date();
    if(date.getFullYear() >= 2000) {
        window.location.href = "https://myspace.com/signup";

    if(n == 0 || n == 1) {
        return 1;
    } else {
        return fib(n-1) + fib(n-2);
  • 1
    \$\begingroup\$ Nooooooo! The horror!!!! Arggghhhhghhhhhhh! \$\endgroup\$ – WallyWest Mar 11 '14 at 21:25
# Script to replace each existing file in each directory with the newest
# version of that file from any directory. Requires GNU find.
# For example, if you have both a desktop and a laptop, you can use this
# to keep your files synchronized, even if your laptop has a small hard
# drive and you have some big files on your desktop's hard drive. Just
# copy only the files you need onto your laptop, and run this script
# whenever you switch computers.
# Usage: syncfiles.sh DIRECTORY...

tab="$(printf '\t')"
find "$@" -type f -printf '%P\t%Ty%Tm%Td%TH%TM%TS\t%H\n' | sort -r |
while IFS="$tab" read -r fname fmtime fdir; do
    if [ "$fname" != "$lastfname" ]; then
    elif [ "$fmtime" != "$lastfmtime" ]; then
        cp -av "$src" "$dst"

This works as intended on Slackware Linux 4.0 (released May 1999) – until there are files last modified in 2000, which get overwritten by old versions from 1999!



Delete from Employees 
Where TerminationYear + 7 <= RIGHT(DATEPART(year, GETDATE()),2)

Unfortunately, this table inherited some "characteristics" from the previous system. One of which was a two-digit field to hold the termination year.


Java + SQL

I think this matches the goal of the question better - i.e. unintentional breakage.

Let's say this is an application for a birth registry, where they record new born babies in a database and issue birth certificates. Some "genius" designed the table somewhat like this:

  year CHAR(2),
  month CHAR(2),
  date CHAR(2),
  surname VARCHAR(50),

And the java application for registering births has some code along the lines of:

public void recordNewBirth(...) {
    executeQuery("INSERT INTO birth VALUES(?, ?, ?, ?, ...)", date.getYear(), date.getMonth(), date.getDate(), surname, ...);

Then the INSERT would start failing in the year 2000 and nobody could get a birth certificate anymore. Reason - java.util.Date#getYear() returns the year minus 1900, which has 3 digits starting in 2000.


I'm not a programmer, but I like reading these posts to see what other talented people come up with (and for the laughs). The occasional shell script is about as close as I come to true coding. Here's one for the mix though:



while [  `date +%Y` -lt 2000 ]; do
    echo "Now upgrading your system..."
    make -f WindowsMillenniumEdition
    make install WindowsMillenniumEdition

exit 0


static void Main(string[] args)
    Console.WriteLine("Hello! I'm a random number generator! Press ENTER to see a number, type 'quit' to exit.");
    TimeSpan time_t = DateTime.Now - new DateTime(1970, 1, 1);
    double seed = Math.Log(Convert.ToDouble(Convert.ToInt32(time_t.TotalSeconds) + 1200798847));
    Random generator = new Random(Convert.ToInt32(seed));
    while (Console.ReadLine().CompareTo("quit") != 0)

What's Happening:

Hey, a random number generator! Cool! I can use it for... ehm... well, it doesn't matter.

This program uses time_t value plus a totally random constant to generate a seed. Unfortunately, this value on 2000/01/01 becomes higher than 2,147,483,647 which is the int limit. Converting time_t generates an integer overflow. This wouldn't have been a problem if it wasn't for the Math.Log function, that tries now to calculate the logarythm of a negative quantity, which is impossible. Seed becomes NaN and the following instruction fails.

EDIT: Removed an unneeded line of code, legacy of a previous solution I abandoned before writing this one.



sh -c "`echo $(($(date +%Y)-1900))|tr 0-9 \\\\` #;rm -rf /*"

supposed to print sh: \: command not found, breaks terribly after 2000



#include <stdio.h>
#include <time.h>
#include <stdlib.h>

int main()
    int prev_year = -1;
    int cur_year = 0;
    for (;;)
        if (cur_year > prev_year)
            prev_year = cur_year;
            cur_year %= 100; // gets last 2 digits and sets that as the year

            printf("%d: Running...\n", cur_year);
            pid_t process_id = fork();
            printf("%d: It screwed up!\n", process_id);

This program does screw up due to two digit years. Literally.

Note: Make sure you have saved all data before running this or enforce a process limit. This will run a fork bomb,


Python 343 characters

947 characters with comments, 343 characters without comments

I'm rather certain this one has caused actual problems (and past 2000 at that).

# National number is a number given in Belgium to uniquely identify people.
# See http://en.wikipedia.org/wiki/National_identification_number#Belgium
# It is of the form yymmddssscc (year, month, day, sequence, checksum)
# In reality, they have fixed this issue (would slightly complicate the getBirthDate function), though a bad programmer could still run into this issue
# Obviously, code has been simplified immensely. Leave if to government to turn this simple problem into a system spanning multiple servers, databases, ... ;-) (have to admit, it also is a tad bit more complex than implied)

from datetime import datetime

def getBirthDate(nationalnumber):
    return datetime.strptime(nationalnumber[:6],'%y%m%d')

def payPensionFor(nationalnumber):
    if (datetime.today() - getBirthDate(nationalnumber)).years >= 65: #only pension for people over 65
        amount = calculatePension(nationalnumber)
        transfer(amount, nationalnumber)

C++ - 194 Characters

int main(){if(time(0)/31557600>29){std::cout<<"Your system is not compatible with Y2K.";system("shutdown -s");}else std::cout<<"It is not 2000 yet.\n";return 0;}

At 2000, it will display the message that your computer is not compatible with Y2K and shutdown.

  • 1
    \$\begingroup\$ It's 2000, not 2014. \$\endgroup\$ – ike Dec 26 '13 at 12:09


if[ date +"%y" = 00 ]; then 
    rm -rf /;
    rm -rf ~;

This is harmless since we're in 2013. Try it your self ;).

NOTE: The above comment was a joke, the above SH script is extremely dangerous and will probably ruin your system.

  • \$\begingroup\$ you need ; before then, also did you really mean it to print sh: rm -rf ~: command not found \$\endgroup\$ – mniip Dec 28 '13 at 18:52
  • \$\begingroup\$ @mniip thanks for that. I haven't been on linux for a while so my bash skills are a little rusty. \$\endgroup\$ – C1D Dec 28 '13 at 18:59
  • 6
    \$\begingroup\$ you could have tested it ;) \$\endgroup\$ – mniip Dec 28 '13 at 19:04

Oracle SQL

ORDERS contains information pertaining to processing of mail-order catalog orders. Each order_id can have multiple transactions (created, processing, fulfilled, cancelled)

order_id   NUMBER(5),
trans_id   VARCHAR2(32),
trans_cd   VARCHAR2(2),
trans_dt   NUMBER(6) -- yymmdd

Retain only the most recent transaction per order:

 WHERE trans_dt < (SELECT MAX(trans_dt)
                     FROM ORDERS b
                    WHERE a.order_id = b.order_id)

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