[{"data":1,"prerenderedAt":426},["ShallowReactive",2],{"guide-posix-time-2038-problem":3},{"id":4,"title":5,"body":6,"date":418,"description":419,"extension":420,"meta":421,"navigation":122,"path":422,"readingTime":138,"seo":423,"stem":424,"__hash__":425},"guides\u002Fguides\u002Fposix-time-2038-problem.md","The Unix Time 2038 Problem",{"type":7,"value":8,"toc":404},"minimark",[9,13,18,26,78,89,94,178,182,185,235,241,245,249,259,274,294,298,329,333,336,350,354,357,363,367,387,391,400],[10,11,12],"p",{},"On January 19, 2038, at 03:14:07 UTC, the Unix timestamp — the number of seconds elapsed since January 1, 1970 — will reach 2,147,483,647. That number is the maximum value a signed 32-bit integer can hold. One second later, it will roll over to -2,147,483,648, and systems interpreting the timestamp as a signed 32-bit value will believe the date is December 13, 1901. This is the Year 2038 problem, also known as Y2K38 or the Unix Millennium Bug.",[14,15,17],"h2",{"id":16},"what-causes-the-overflow","What Causes the Overflow",[10,19,20,21,25],{},"Unix time is stored as a single integer counting seconds from the epoch (January 1, 1970, 00:00:00 UTC). On 32-bit systems using a signed integer (",[22,23,24],"code",{},"int32_t"," in C), the range is:",[27,28,29,42],"table",{},[30,31,32],"thead",{},[33,34,35,39],"tr",{},[36,37,38],"th",{},"Property",[36,40,41],{},"Value",[43,44,45,54,62,70],"tbody",{},[33,46,47,51],{},[48,49,50],"td",{},"Min value",[48,52,53],{},"-2,147,483,648",[33,55,56,59],{},[48,57,58],{},"Max value",[48,60,61],{},"2,147,483,647",[33,63,64,67],{},[48,65,66],{},"Max timestamp",[48,68,69],{},"2038-01-19 03:14:07 UTC",[33,71,72,75],{},[48,73,74],{},"Min timestamp",[48,76,77],{},"1901-12-13 20:45:52 UTC",[10,79,80,81,84,85,88],{},"The overflow happens because binary addition wraps around. The binary representation of 2,147,483,647 is ",[22,82,83],{},"01111111 11111111 11111111 11111111",". Adding 1 produces ",[22,86,87],{},"10000000 00000000 00000000 00000000",", which in two's complement signed interpretation is -2,147,483,648.",[90,91,93],"h3",{"id":92},"quick-demonstration","Quick demonstration",[95,96,101],"pre",{"className":97,"code":98,"language":99,"meta":100,"style":100},"language-c shiki shiki-themes github-light github-dark","#include \u003Cstdio.h>\n#include \u003Ctime.h>\n\nint main() {\n    time_t t = 2147483647;\n    printf(\"Now:  %s\", ctime(&t));\n    t = t + 1;\n    printf(\"Next: %s\", ctime(&t));\n    \u002F\u002F On 32-bit systems: Next = Fri Dec 13 20:45:52 1901\n    \u002F\u002F On 64-bit systems: Next = Tue Jan 19 03:14:08 2038\n    return 0;\n}\n","c","",[22,102,103,111,117,124,130,136,142,148,154,160,166,172],{"__ignoreMap":100},[104,105,108],"span",{"class":106,"line":107},"line",1,[104,109,110],{},"#include \u003Cstdio.h>\n",[104,112,114],{"class":106,"line":113},2,[104,115,116],{},"#include \u003Ctime.h>\n",[104,118,120],{"class":106,"line":119},3,[104,121,123],{"emptyLinePlaceholder":122},true,"\n",[104,125,127],{"class":106,"line":126},4,[104,128,129],{},"int main() {\n",[104,131,133],{"class":106,"line":132},5,[104,134,135],{},"    time_t t = 2147483647;\n",[104,137,139],{"class":106,"line":138},6,[104,140,141],{},"    printf(\"Now:  %s\", ctime(&t));\n",[104,143,145],{"class":106,"line":144},7,[104,146,147],{},"    t = t + 1;\n",[104,149,151],{"class":106,"line":150},8,[104,152,153],{},"    printf(\"Next: %s\", ctime(&t));\n",[104,155,157],{"class":106,"line":156},9,[104,158,159],{},"    \u002F\u002F On 32-bit systems: Next = Fri Dec 13 20:45:52 1901\n",[104,161,163],{"class":106,"line":162},10,[104,164,165],{},"    \u002F\u002F On 64-bit systems: Next = Tue Jan 19 03:14:08 2038\n",[104,167,169],{"class":106,"line":168},11,[104,170,171],{},"    return 0;\n",[104,173,175],{"class":106,"line":174},12,[104,176,177],{},"}\n",[14,179,181],{"id":180},"who-is-affected","Who Is Affected",[10,183,184],{},"The impact depends on how time values are stored and processed:",[186,187,188,203,209,215,229],"ul",{},[189,190,191,195,196,199,200,202],"li",{},[192,193,194],"strong",{},"32-bit Linux kernels:"," The ",[22,197,198],{},"time_t"," type is 32-bit on 32-bit builds. Filesystem timestamps, process scheduling, and timer subsystems all use ",[22,201,198],{},".",[189,204,205,208],{},[192,206,207],{},"Embedded systems:"," Microcontrollers running RTOS or bare-metal C code often store timestamps in 32-bit fields. Many of these devices have deployment lifetimes spanning decades.",[189,210,211,214],{},[192,212,213],{},"Filesystems:"," ext3, FAT32, and other legacy filesystems store timestamps in 32-bit fields. Files created after the overflow date may show incorrect modification times.",[189,216,217,220,221,224,225,228],{},[192,218,219],{},"Databases:"," Columns defined as ",[22,222,223],{},"INT"," (32-bit) for timestamps will overflow. MySQL's ",[22,226,227],{},"TIMESTAMP"," type uses 32-bit storage and is affected through version 5.5.",[189,230,231,234],{},[192,232,233],{},"Binary protocols:"," Message formats that allocate 32 bits for timestamp fields — GPS protocols, industrial control systems, financial trading APIs — will break.",[10,236,237,238,240],{},"Systems already running 64-bit ",[22,239,198],{}," (modern Linux, macOS, Windows) are safe at the OS level, but application code and data formats may still carry 32-bit assumptions.",[14,242,244],{"id":243},"migration-paths","Migration Paths",[90,246,248],{"id":247},"switch-to-64-bit-time_t","Switch to 64-bit time_t",[10,250,251,252,254,255,258],{},"The most straightforward fix: compile with a 64-bit ",[22,253,198],{},". GNU C Library (glibc) 2.34+, musl 1.2+, and FreeBSD 13+ all support ",[22,256,257],{},"_TIME_BITS=64"," for 32-bit builds:",[95,260,262],{"className":97,"code":261,"language":99,"meta":100,"style":100},"# Compile with 64-bit time_t on 32-bit platforms\nCFLAGS += -D_TIME_BITS=64 -D_FILE_OFFSET_BITS=64\n",[22,263,264,269],{"__ignoreMap":100},[104,265,266],{"class":106,"line":107},[104,267,268],{},"# Compile with 64-bit time_t on 32-bit platforms\n",[104,270,271],{"class":106,"line":113},[104,272,273],{},"CFLAGS += -D_TIME_BITS=64 -D_FILE_OFFSET_BITS=64\n",[10,275,276,277,279,280,283,284,286,287,289,290,293],{},"This redefines ",[22,278,198],{}," as ",[22,281,282],{},"int64_t",", extending the range to approximately year 292 billion. Existing source code that uses ",[22,285,198],{}," correctly compiles without changes. However, any code that casts ",[22,288,198],{}," to ",[22,291,292],{},"int"," or serializes it as 4 bytes will need updates.",[90,295,297],{"id":296},"upgrade-database-columns","Upgrade database columns",[95,299,303],{"className":300,"code":301,"language":302,"meta":100,"style":100},"language-sql shiki shiki-themes github-light github-dark","-- MySQL: Convert TIMESTAMP to DATETIME (8-byte storage after MySQL 5.6.4)\nALTER TABLE events MODIFY created_at DATETIME(3);\n\n-- PostgreSQL: Use TIMESTAMPTZ (always 8 bytes)\n-- Already safe — no action needed\n","sql",[22,304,305,310,315,319,324],{"__ignoreMap":100},[104,306,307],{"class":106,"line":107},[104,308,309],{},"-- MySQL: Convert TIMESTAMP to DATETIME (8-byte storage after MySQL 5.6.4)\n",[104,311,312],{"class":106,"line":113},[104,313,314],{},"ALTER TABLE events MODIFY created_at DATETIME(3);\n",[104,316,317],{"class":106,"line":119},[104,318,123],{"emptyLinePlaceholder":122},[104,320,321],{"class":106,"line":126},[104,322,323],{},"-- PostgreSQL: Use TIMESTAMPTZ (always 8 bytes)\n",[104,325,326],{"class":106,"line":132},[104,327,328],{},"-- Already safe — no action needed\n",[90,330,332],{"id":331},"redesign-binary-protocols","Redesign binary protocols",[10,334,335],{},"For protocols that cannot change field sizes, consider:",[186,337,338,341],{},[189,339,340],{},"Epoch shifting: use a more recent epoch (e.g., 2000-01-01) to extend the positive range",[189,342,343,344,289,346,349],{},"Unsigned integers: switching from ",[22,345,24],{},[22,347,348],{},"uint32_t"," extends the range to 2106-02-07 (but loses pre-1970 dates)",[14,351,353],{"id":352},"lessons-from-y2k","Lessons from Y2K",[10,355,356],{},"The Year 2000 problem taught the industry that date-related bugs seem far away until they are not. Banks and insurance companies began hitting Y2K bugs in the 1990s because their 30-year mortgages and life insurance policies extended past 2000. Similarly, systems that compute future dates — loan amortization, certificate expiry, long-term archiving — are already encountering 2038 limits in 2026.",[10,358,359,360,362],{},"The key insight from Y2K: early, systematic remediation is far cheaper than emergency patches. auditing codebases for ",[22,361,24],{}," timestamp usage, testing with dates beyond 2038, and scheduling upgrades during regular maintenance cycles all reduce risk and cost.",[14,364,366],{"id":365},"key-takeaways","Key Takeaways",[186,368,369,372,375,381,384],{},[189,370,371],{},"The 2038 overflow occurs when the Unix timestamp exceeds 2,147,483,647, the maximum signed 32-bit integer.",[189,373,374],{},"32-bit Linux kernels, embedded systems, legacy databases, and binary protocols are most at risk.",[189,376,377,378,380],{},"Compiling with ",[22,379,257],{}," is the simplest migration path for C applications on 32-bit platforms.",[189,382,383],{},"Systems that calculate future dates are already affected and should be audited now.",[189,385,386],{},"Proactive remediation during scheduled maintenance is cheaper than last-minute emergency fixes.",[14,388,390],{"id":389},"try-it-yourself","Try It Yourself",[10,392,393,394,399],{},"Working with timestamps? Use the ",[395,396,398],"a",{"href":397},"\u002Ftools\u002Ftimestamp-converter","Timestamp Converter"," to convert between Unix timestamps and human-readable dates — including dates past 2038 on 64-bit systems.",[401,402,403],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":100,"searchDepth":113,"depth":113,"links":405},[406,409,410,415,416,417],{"id":16,"depth":113,"text":17,"children":407},[408],{"id":92,"depth":119,"text":93},{"id":180,"depth":113,"text":181},{"id":243,"depth":113,"text":244,"children":411},[412,413,414],{"id":247,"depth":119,"text":248},{"id":296,"depth":119,"text":297},{"id":331,"depth":119,"text":332},{"id":352,"depth":113,"text":353},{"id":365,"depth":113,"text":366},{"id":389,"depth":113,"text":390},"2026-05-28","Why 32-bit Unix timestamps overflow on January 19, 2038 and how systems are preparing.","md",{"immutable":122},"\u002Fguides\u002Fposix-time-2038-problem",{"title":5,"description":419},"guides\u002Fposix-time-2038-problem","ew6KhtAMC8HtYPDWcyvITRfXRlX8exLFNMm85ch_Z0k",1780401335880]