[{"data":1,"prerenderedAt":460},["ShallowReactive",2],{"/projects/you-tz":3,"/projects/you-tz-surround":445},{"id":4,"title":5,"additionalTags":6,"body":7,"description":419,"excerpt":420,"extension":421,"featured":422,"meta":423,"name":426,"navigation":422,"openSource":427,"path":428,"projectDate":429,"projectFolder":72,"seo":430,"sitemap":431,"status":435,"stem":436,"subtitle":437,"tags":438,"thumbnail":443,"__hash__":444},"projects/projects/7.you-tz.md","You Tz",[],{"type":8,"value":9,"toc":401},"minimark",[10,14,25,30,33,39,46,51,54,64,67,74,78,81,87,91,94,135,138,146,149,153,156,160,163,167,170,201,204,208,247,250,253,272,275,279,305,309,329,333,350,354],[11,12],"stats-table",{":stats":13},"[{\"label\": \"release date\", \"value\": \"2026\"}]",[15,16,17],"p",{},[18,19],"img",{"alt":20,"className":21,"src":23,"width":24},"Screenshot",[22],"w-full","/projects/you-tz/now.png",640,[26,27,29],"h2",{"id":28},"the-problem","The Problem",[15,31,32],{},"Every Front-end developer has been there... you have a date string — say:",[15,34,35],{},[36,37,38],"code",{},"2026-05-08T15:42:51.714709",[15,40,41,42,45],{},"and you go to display it in relative time format that should say \"just now\" but instead shows \"in X hours.\" The eagle-eyed would have spotted the missing ",[36,43,44],{},"Z"," suffix (or similar offset). While still a valid ISO 8601 date format; most date libraries will silently coerce into local time instead of UTC without a specified offset.",[47,48,50],"h3",{"id":49},"zulu-or-bust","Zulu or bust",[15,52,53],{},"The primary use case that motivated you-tz is the \"missing Z problem.\" Consider:",[55,56,61],"pre",{"className":57,"code":59,"language":60},[58],"language-text","2026-05-08T15:42:51.714709      ← no Z, parsed as local time\n2026-05-08T15:42:51.714709Z     ← Z present, parsed as UTC\n","text",[36,62,59],{"__ignoreMap":63},"",[15,65,66],{},"These look almost identical. But depending on your timezone, they can be hours apart. And different libraries handle the ambiguity differently — some assume local time, some assume UTC, some require explicit configuration.",[15,68,69,73],{},[70,71,72],"strong",{},"you-tz"," makes this difference visible. You paste a string, and the library comparison immediately show which ones interpreted it as local time versus UTC depending of how you're using it.",[47,75,77],{"id":76},"how-it-works","How it works",[15,79,80],{},"Paste any ISO string, see how it is handled in popular JavaScript date libraries, and visualize it on a world map across timezones of your choosing.",[15,82,83,84,86],{},"Whether you're just jumping into an existing project and seeing something weird or switching your date library; I built ",[70,85,72],{}," to help debug these exact issues.",[47,88,90],{"id":89},"cross-library-comparison","Cross-Library Comparison",[15,92,93],{},"The core of you-tz is a side-by-side comparison of how different date libraries handle the same input. The project currently supports:",[95,96,97,104,110,116,122],"ul",{},[98,99,100,103],"li",{},[70,101,102],{},"Moment.js"," — the classic, now deprecated, but still relevant",[98,105,106,109],{},[70,107,108],{},"date-fns"," — the modern functional approach",[98,111,112,115],{},[70,113,114],{},"Luxon"," — Moment's successor with built-in timezone support",[98,117,118,121],{},[70,119,120],{},"Day.js"," — the lightweight drop-in Moment replacement",[98,123,124,127,128,131,132],{},[70,125,126],{},"Vanilla JS"," — native JS ",[36,129,130],{},"Date"," and ",[36,133,134],{},"Intl",[15,136,137],{},"and in the works:",[95,139,140],{},[98,141,142,145],{},[70,143,144],{},"Temporal API"," — the upcoming ECMAScript standard",[15,147,148],{},"This is exactly the kind of comparison that takes 15 minutes of console or debugging work and turns it into a single glance.",[47,150,152],{"id":151},"world-map-visualization","World Map Visualization",[15,154,155],{},"Using MapLibre, you-tz plots selected timezones on a world map. Markers are positioned by GMT offset and labeled with timezone names. You can add or remove timezones to see how the same instant looks across different parts of the world.",[26,157,159],{"id":158},"building-with-ai","Building with AI",[15,161,162],{},"I utilized OpenCode + various different AI models during the initial planning, development and prototyping phases.",[47,164,166],{"id":165},"planning-phase","Planning Phase",[15,168,169],{},"Before writing any code, I used AI to help structure the architecture. The initial conversation covered:",[95,171,172,175,178,195,198],{},[98,173,174],{},"What the project needed to accomplish",[98,176,177],{},"How the UI should be organized (landing page → debug view)",[98,179,180,181,184,185,184,188,184,191,194],{},"Which composables to extract (",[36,182,183],{},"useDateParsing",", ",[36,186,187],{},"useTimezones",[36,189,190],{},"useLibraries",[36,192,193],{},"useTheme",")",[98,196,197],{},"The routing strategy (regex-based routes for ISO strings)",[98,199,200],{},"How to handle URL serialization for shareability",[15,202,203],{},"Having an AI that could reason about Vue 3 patterns, Pinia stores, and route configuration in real time meant I could iterate on architecture decisions without context-switching between documentation tabs.",[47,205,207],{"id":206},"rapid-prototyping","Rapid Prototyping",[15,209,210,211,184,214,184,217,184,220,223,224,227,228,231,232,184,235,238,239,242,243,246],{},"The individual library components — ",[36,212,213],{},"LibMoment.vue",[36,215,216],{},"LibDateFns.vue",[36,218,219],{},"LibLuxon.vue",[36,221,222],{},"LibDayjs.vue"," — all follow the same pattern: a ",[36,225,226],{},"\u003Cscript setup>"," that defines ",[36,229,230],{},"rows"," with ",[36,233,234],{},"category",[36,236,237],{},"method",", and ",[36,240,241],{},"result"," fields, passed to a shared ",[36,244,245],{},"LibTable.vue"," component.",[15,248,249],{},"This pattern emerged through AI-assisted iteration. The first version of the Luxon component might have used a different structure. By the time we got to Day.js, the pattern was stable, and the AI could generate new library components that were immediately consistent with the existing ones.",[15,251,252],{},"When I decided to add Vanilla JS and Temporal API support, the AI was able to:",[254,255,256,259,266,269],"ol",{},[98,257,258],{},"Create new components following the established pattern",[98,260,261,262,265],{},"Implement relative time logic for Vanilla JS (no library — just ",[36,263,264],{},"Date.now()"," math)",[98,267,268],{},"Set up dynamic polyfill loading for the Temporal API",[98,270,271],{},"Update the library registry, imports, and template rendering",[15,273,274],{},"This is the kind of work that would take hours of manual copy-paste-refactor. With AI assistance, it took minutes — and the result was immediately consistent with the existing codebase.",[26,276,278],{"id":277},"lessons-learned","Lessons Learned",[254,280,281,287,293,299],{},[98,282,283,286],{},[70,284,285],{},"AI excels at pattern replication."," Once a pattern is established (like the date library component structure), AI can generate new instances with high consistency.",[98,288,289,292],{},[70,290,291],{},"AI is strongest when you have a clear mental model."," I knew what the app should do and how it should be structured. AI helped me translate that vision into code faster than I could alone.",[98,294,295,298],{},[70,296,297],{},"AI struggles with \"the last 10%.\""," Edge cases, specific browser behavior, and Tailwind CSS quirks still required manual debugging. AI gets you to 90% quickly; the last 10% is where domain knowledge matters.",[98,300,301,304],{},[70,302,303],{},"The planning conversations were as valuable as the code generation."," Talking through architecture decisions with an AI forced me to articulate my thinking, which often revealed gaps in my own design.",[26,306,308],{"id":307},"whats-next","What's Next",[95,310,311,317,323],{},[98,312,313,316],{},[70,314,315],{},"More date libraries"," — Still highly experimental the Temporal API is on track to becoming the defacto replacement for using the standard Date API.",[98,318,319,322],{},[70,320,321],{},"Expanded library comparisons"," — I want to add more categories to the comparison tables. For example how different libraries handle date manipulation, like checking greater than or less than.",[98,324,325,328],{},[70,326,327],{},"i18n"," - I'd like to add internationalization to make this tool more accessible.",[26,330,332],{"id":331},"try-it","Try It",[15,334,335,336,343,344,349],{},"The project is currently live at ",[337,338,342],"a",{"href":339,"rel":340},"https://you-tz.com",[341],"nofollow","you-tz.com",". Paste any ISO string, quickly sanity-check it against the most popular Date libraries, and share the result with your team. You can also use ",[337,345,348],{"href":346,"rel":347},"https://you-tz.com/now",[341],"you-tz.com/now"," to use the current time as a starting snapshot.",[26,351,353],{"id":352},"technologies-utilized","Technologies Utilized",[355,356,357,367],"table",{},[358,359,360],"thead",{},[361,362,363],"tr",{},[364,365,366],"th",{},"Frontend",[368,369,370,376,381,386,391,396],"tbody",{},[361,371,372],{},[373,374,375],"td",{},"Vue 3",[361,377,378],{},[373,379,380],{},"Tailwind",[361,382,383],{},[373,384,385],{},"TypeScript",[361,387,388],{},[373,389,390],{},"MapLibre",[361,392,393],{},[373,394,395],{},"Pinia w/ persisted state",[361,397,398],{},[373,399,400],{},"Vite+",{"title":63,"searchDepth":402,"depth":402,"links":403},2,[404,411,415,416,417,418],{"id":28,"depth":402,"text":29,"children":405},[406,408,409,410],{"id":49,"depth":407,"text":50},3,{"id":76,"depth":407,"text":77},{"id":89,"depth":407,"text":90},{"id":151,"depth":407,"text":152},{"id":158,"depth":402,"text":159,"children":412},[413,414],{"id":165,"depth":407,"text":166},{"id":206,"depth":407,"text":207},{"id":277,"depth":402,"text":278},{"id":307,"depth":402,"text":308},{"id":331,"depth":402,"text":332},{"id":352,"depth":402,"text":353},"A tool to help developers visualize date parsing across timezones and popular JavaScript date libraries.",null,"md",true,{"items":424},[425],"/projects/you-tz/home-dark.jpg","You-TZ",false,"/projects/you-tz","2026-05-27T00:00:00.000Z",{"description":419},{"loc":428,"lastmod":432,"changefreq":433,"priority":434},"2026-05-27","monthly",0.8,"draft","projects/7.you-tz","Timezones = fun",[439,440,441,442,108,114,380,385],"Vue","AI","Tooling","Moment","/projects/you-tz/thumb.webp","-KwIi-6g14QwpJhxgTdfS06tREUNViY_X97r8V9X_JY",[446,420],{"title":447,"path":448,"stem":449,"name":447,"description":450,"subtitle":451,"thumbnail":452,"tags":453,"children":-1},"Sushi Stacks","/projects/sushi-stacks","projects/6.sushi-stacks","A fun app made for conveyor-belt sushi lovers.","Web Development + Hybrid App development","/projects/sushi/thumb.webp",[454,455,456,457,458,459],"AngularJS","Graphic Design","Firebase","Hybrid App","Cordova","jQuery",1780955968229]