- Lab
-
Libraries: If you want this lab, consider one of these libraries.
- Core Tech
The Global Clock: Localizing Dates with JavaScript
In this lab you'll build a small global event display that formats the same date and time for different audiences. You'll practice using JavaScript's built-in internationalization APIs to choose locale-aware date, time, and time zone options without hard-coding display strings.
Lab Info
Table of Contents
-
Challenge
Step 1: Understand the date display problem
Welcome to The Global Clock: Localizing Dates with JavaScript Code Lab.
Showing one instant to people around the world is less about changing the data and more about presenting it in a form each audience can read naturally. In this lab, you will work on a global event display where clarity depends on locale-aware dates, times, and time zones.
You'll also build a command-line schedule that formats shared event timestamps for New York, London, and Tokyo and organizes the presentation logic into reusable helpers. To begin, you'll distinguish the stored instant from its regional display so later changes preserve the event data.
The
applicationdirectory already contains the project with event data, rendering functions, and formatter stubs ready for your implementations. You will be responsible for modifying code within thesrcsubdirectory.
Note: If you're feeling stuck, check out the matching
solution/stepN/folder for the step you're on to see a working implementation. Give it a try on your own first. The solution folder is your safety net, not your starting point.Lastly, you can manually run a validation test in the terminal with the command
./runTest.sh taskXif you'd like to view the results in a larger window. ReplacetaskXwith the specific task number, of which there are 10 in this lab. -
Challenge
Step 2: Format dates with `Intl.DateTimeFormat`
With the difference between stored timestamps and displayed values clear, you can make the schedule readable without altering its source data. You will build
formatDateTimein stages, then route event rendering through it. This gives you a reusable locale-aware date and time path based onIntl.DateTimeFormat. ### Locale-aware calendar formattingAn ISO timestamp identifies an instant, while
Intl.DateTimeFormatcontrols how that instant is presented for a locale. Parse the timestamp withDate, configure the formatter with calendar fields such as year, month, and day, and format the parsed value. The general shape isnew Intl.DateTimeFormat(languageTag, displayOptions).format(new Date(timestampText)), where the identifiers are placeholders for runtime inputs. ### Combined date and time optionsAn
Intl.DateTimeFormatoptions object can describe calendar and clock fields together. Adding hour and minute fields lets the formatter follow the locale's ordering, punctuation, and hour-cycle conventions. Prefer formatter options over manually assembling numeric date and time pieces. ### Formatter composition in a rendererA renderer should compose the formatter rather than repeat date-formatting rules.
Array.map()can transform each event into a display line beforejoin()builds the multiline schedule. A placeholder pattern isrecords.map((record) => formatValue(record.value, region)).join(separator). -
Challenge
Step 3: Compare locales and time zones
Readable dates now flow through the renderer, which lets audience settings vary independently from event data. You will define regional profiles, add time-zone formatting, and compose single-audience sections into a grouped schedule. This makes the role of locale versus time zone concrete while keeping one source instant. ### Locale and time-zone profiles
Audience profiles keep regional presentation settings as data instead of scattering them through rendering logic. Each profile associates a display label and locale with an IANA time-zone identifier. A placeholder profile has the shape
{ label: "Region", locale: "xx-YY", timeZone: "Area/City" }. ### Locale versus time zoneA locale controls language and display conventions, while a time zone controls which local clock time represents an instant. The same
Datevalue can therefore produce different output when only the formatter'stimeZoneoption changes. Prefer IANA identifiers such asArea/Citybecause they encode regional time-zone rules. ### Rendering for one audienceA focused rendering helper can bind a collection of events to one audience's presentation settings. It should use the profile's locale and time zone for every timestamp while keeping the source events unchanged. A placeholder transformation is
items.map((item) => formatForContext(item, profile)). ### Mapping profiles to sectionsOnce one helper renders a single audience section, mapping all profiles through that helper scales the same behavior across the schedule. Joining the resulting strings creates one grouped display while leaving both input arrays unchanged. A placeholder pattern is
profiles.map((profile) => renderSection(items, profile)).join(sectionBreak). -
Challenge
Step 4: Create reusable formatter helpers
Audience-specific schedules are in place, so you can centralize how formatters and event lines are constructed. You will extract a formatter factory, add an event display helper, and delegate renderer work to that helper. This leaves each function with a focused responsibility and makes presentation rules easier to reuse. ### Formatter factories
A factory packages formatter configuration into a reusable
Intl.DateTimeFormatinstance. Returning the configured instance lets callers use itsformat()method without rebuilding the options themselves. A placeholder factory has the shape(settings) => new Formatter(settings). ### Event-line formattingFormatting one event line is a distinct responsibility from assembling an audience section. A dedicated helper can combine event data, audience settings, and the existing date-time formatter into a consistent line. Keeping the bullet prefix in that helper gives every renderer caller the same presentation. ### Delegating display responsibilities
Delegation keeps the schedule renderer focused on section structure while a specialized helper owns event-line formatting. Importing and calling that helper also prevents the two modules from developing separate display rules. A placeholder pattern is
items.map((item) => renderItem(item, context)). Congratulations on completing the global event display!You built a command-line schedule that presented shared event timestamps for New York, London, and Tokyo without changing their stored instants. You used locales and IANA time zones to produce audience-specific date and time strings.
You also separated formatter creation, event-line formatting, and schedule rendering into reusable helpers. Those boundaries give you a transferable pattern for keeping internationalized presentation logic consistent across a JavaScript application.
About the author
Real skill practice before real-world application
Hands-on Labs are real environments created by industry experts to help you learn. These environments help you gain knowledge and experience, practice without compromising your system, test without risk, destroy without fear, and let you learn from your mistakes. Hands-on Labs: practice your skills before delivering in the real world.
Learn by doing
Engage hands-on with the tools and technologies you’re learning. You pick the skill, we provide the credentials and environment.
Follow your guide
All labs have detailed instructions and objectives, guiding you through the learning process and ensuring you understand every step.
Turn time into mastery
On average, you retain 75% more of your learning if you take time to practice. Hands-on labs set you up for success to make those skills stick.