Skip to content

Instantly share code, notes, and snippets.

@Dobby233Liu
Last active January 18, 2026 07:43
Show Gist options
  • Select an option

  • Save Dobby233Liu/ee82a44ad57b277a3cffb17d7b7bf727 to your computer and use it in GitHub Desktop.

Select an option

Save Dobby233Liu/ee82a44ad57b277a3cffb17d7b7bf727 to your computer and use it in GitHub Desktop.
import datetime
def validate_build_id(build_id):
return build_id.isupper() \
and len(build_id) in (5, 6) \
and build_id[0].isalpha() \
and build_id[3:4+1].isdigit() \
and (not len(build_id) == 6 or build_id[5].isalpha())
# only ones that used this build ID format
VERSIONS = {
"A": ("Mainline & early JB - L", None),
"C": ("Cupcake", "1.5"), "D": ("Donut", "1.6"),
"E": ("Eclair", "2.0-2.1"), "F": ("Froyo", "2.2"), "G": ("Gingerbread", "2.3"),
"H": ("Honeycomb", "3.x"), "I": ("Ice Cream Sandwich", "4.0"),
"J": ("Jelly Bean", "4.1-4.3"), "K": ("KitKat", "4.4(W)"),
"L": ("Lollipop", "5.x"), "M": ("Marshmallow", "6.x"),
"N": ("Nougat", "7.x"), "O": ("Oreo (early)", None)
}
def parse_version(a):
name, num = VERSIONS.get(a, (None, None))
return f"{name if name is not None else "Undefined"}{f" ({num})" if num is not None else ""}"
# this is basically why this format was replaced
START_YEAR = 2009 # Cupcake
QUARTER_MAX = 4
# it actually doesn't matter how many days a quarter generally has
# months that Q corresponds to are fixed here regardless of the year
MONTHS_PER_QUARTER = 3
def parse_date(quarter_a, day, ver='C'):
qnum = 0
# Marshmallow dev started around Jan 2015 (Q1), so check for Y
# Second rotation ended at P (Q2 2019)
# TODO: Hopefully there's no master tags from this era out there
if (ord(ver) == ord('M') and ord(quarter_a) < ord('Y')) or ord(ver) > ord('M'):
qnum += ord('Z') - ord('A') + 1 # overflow to A (Q3 2015)
qnum += ord(quarter_a) - ord('A') + 1
year = START_YEAR + (qnum - 1) // QUARTER_MAX
quarter = 1 + (qnum - 1) % QUARTER_MAX
q_month = 1 + (quarter - 1) * MONTHS_PER_QUARTER
date = datetime.date(year, q_month, 1) + datetime.timedelta(days=day - 1)
bad = date.month >= (q_month + MONTHS_PER_QUARTER) or date.month < q_month
return date.strftime("%d %B %Y"), "invalid" if bad else f"Q{quarter} {year}"
build_id = input("Build id: ").strip()
if not validate_build_id(build_id):
print("Invalid id")
else:
print("Version: " + parse_version(build_id[0]))
print("Branch: " + build_id[1])
date, quarter = parse_date(build_id[2], int(build_id[3:4+1]), ver=build_id[0])
print(f"Initial date (does not reflect revision): {date} ({quarter})")
print("Revision: " + (build_id[5] if len(build_id) == 6 else "-"))
input("Press any key to continue. . . ")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment