World Time Zone Map
The world's time zones in two layers: colored areas show the zone each piece of land keeps, and faint bands run from pole to pole, with each whole-hour offset from UTC labeled along the bottom.
About this map
Two layers of time zones
Time zones follow borders on land but run straight across the sea, so this map uses two geodata files: the zone areas on land, colored apart, and the full bands. The whole-hour offsets are labeled in a row along the bottom; the zones that are off by half or three quarters of an hour show theirs in the tooltip. The map shows standard time, without daylight saving.
Good for
- Scheduling across regions
- Travel and logistics pages
- Teams spread over several time zones
Think twice when
- The time right now in a few cities: a list of clocks is clearer
- Daylight saving matters: offsets change during the year
- Current offsets: a few countries have changed zones since this geodata was made
For developers
Get the code.
Built with amCharts 5, a JavaScript library. The code includes your theme and renderer (canvas or SVG), but not the changes you make with the controls.
For projects that use npm:
How it reads:
npm install @amcharts/amcharts5 and @amcharts/amcharts5-geodata. See Getting started.
The same chart as a JSON config. Chart Maker reads and writes this format, the library's JSON parser turns it into a chart, and the <am5-chart> element puts it on a page with no code.How it reads:
"type" is the class to create and "settings" what you would pass to its new() in code; "properties" fill in its parts, lists such as series and axes or templates such as columns.template; "refs" holds objects used in more than one place ("#series-0" stands for the one named series-0); a string starting with "@" takes a value from another object, such as "@series.get('fill')".
A complete page. Save it as an .html file and open it in a browser.
Paste this into an AI coding assistant to build the chart from scratch. More in amCharts & AI.
// Create root element
// https://docs.amcharts.com/v5/getting-started/#root-element
var root = am5.Root.new("chartdiv");
// Set themes
// https://docs.amcharts.com/v5/concepts/themes/
var responsive = am5themes_Responsive.new(root); // kept in a variable: a rule of its own is added below
root.setThemes([
am5themes_Animated.new(root),
responsive
]);
// Create the map chart
// https://docs.amcharts.com/v5/charts/map-chart/
var chart = root.container.children.push(
am5map.MapChart.new(root, {
minZoomLevel: 0.5, // the map can zoom out to half its fitted size
// go to the home view once the map is fitted
autoHome: true,
panX: "translateX", // drag the map to move it sideways...
panY: "translateY", // ...and up and down
// hold Shift and drag to zoom into the area you draw
boxZoom: "shift",
projection: am5map.geoEqualEarth() // equal-area: countries keep their true relative size
})
);
var colorSet = am5.ColorSet.new(root, {}); // the theme's colors, for the time zone areas
// Create series for the water: a faint fill behind the countries
// https://docs.amcharts.com/v5/charts/map-chart/map-polygon-series/#background-polygon
var waterSeries = chart.series.push(am5map.MapPolygonSeries.new(root, {
// the map fits the countries, not this rectangle around the whole world
affectsBounds: false
}));
waterSeries.mapPolygons.template.setAll({
fill: root.interfaceColors.get("alternativeBackground"), // the theme's contrast color...
fillOpacity: 0.05, // ...at 5%, a faint tint
strokeOpacity: 0 // no outline
});
waterSeries.data.push({
geometry: am5map.getGeoRectangle(90, 180, -90, -180) // north, east, south and west edges: the whole world
});
// Create graticule series: grid lines every 10 degrees
// https://docs.amcharts.com/v5/charts/map-chart/graticule-series/
var graticuleSeries = chart.series.push(am5map.GraticuleSeries.new(root, {
step: 10
}));
graticuleSeries.mapLines.template.setAll({
stroke: root.interfaceColors.get("alternativeBackground"), // the theme's contrast color...
strokeOpacity: 0.08 // ...very faint
});
// Create main polygon series for time zone areas: the land of each time zone,
// in a color of its own
// https://docs.amcharts.com/v5/charts/map-chart/map-polygon-series/
var areaSeries = chart.series.push(
am5map.MapPolygonSeries.new(root, {
geoJSON: am5geodata_worldTimeZoneAreasLow // the land, cut up by time zone
})
);
var areaPolygonTemplate = areaSeries.mapPolygons.template;
areaPolygonTemplate.setAll({ fillOpacity: 0.6 }); // slightly see-through
// each area takes the next color of the set, at half saturation for softer tones
areaPolygonTemplate.adapters.add("fill", function (fill, target) {
return am5.Color.saturate(
colorSet.getIndex(areaSeries.mapPolygons.indexOf(target)),
0.5
);
});
areaPolygonTemplate.states.create("hover", { fillOpacity: 0.8 }); // stronger under the mouse
// Create main polygon series for time zones: bands from pole to pole, shaded
// lightly, that run over the sea too
// https://docs.amcharts.com/v5/charts/map-chart/map-polygon-series/
var zoneSeries = chart.series.push(
am5map.MapPolygonSeries.new(root, {
geoJSON: am5geodata_worldTimeZonesLow, // the time zone bands
// the map fits the land, not the bands, which run from pole to pole
affectsBounds: false
})
);
var zonePolygonTemplate = zoneSeries.mapPolygons.template;
zonePolygonTemplate.setAll({
fill: root.interfaceColors.get("alternativeBackground"), // the theme's contrast color...
fillOpacity: 0.08, // ...very faint
interactive: true, // the bands react to the mouse
tooltipText: "{id}" // the zone's id from the map data
});
zonePolygonTemplate.states.create("hover", { fillOpacity: 0.3 }); // a band under the mouse shows stronger
// Create point series for the labels: a row of whole-hour offsets along the
// bottom of the map, one under each band
// https://docs.amcharts.com/v5/charts/map-chart/map-point-series/
var labelSeries = chart.series.push(am5map.MapPointSeries.new(root, {}));
labelSeries.bullets.push(function () {
return am5.Bullet.new(root, {
sprite: am5.Label.new(root, {
text: "{offset}",
populateText: true, // fills in {offset} from the data
centerX: am5.p50, // centered on its point
centerY: am5.p50,
fontSize: "0.7em" // 70% of the chart's text size
})
});
});
// The offsets, every step hours from -12 to +12
function offsetData(step) {
var data = [];
for (var hours = -12; hours <= 12; hours += step) {
data.push({
offset: hours > 0 ? "+" + hours : String(hours), // a plus sign before positive hours
// the bands of UTC-12 and UTC+12 are half as wide, at the date line
longitude: Math.max(-176, Math.min(176, hours * 15)),
latitude: -50 // 50 degrees south, below most of the land
});
}
return data;
}
labelSeries.data.setAll(offsetData(1)); // every whole hour
// Add zoom control
// https://docs.amcharts.com/v5/charts/map-chart/map-pan-zoom/#zoom-control
var zoomControl = chart.set("zoomControl", am5map.ZoomControl.new(root, {}));
zoomControl.homeButton.set("visible", true); // a button that goes back to the home view
// On a narrow chart (a phone) whole hours run together: the row shows every third offset, and the
// zoom buttons line up across the bottom corner instead of standing over the end of the row.
// The rule is undone on a wider chart
responsive.addRule({
relevant: function (width) { return width < 600; }, // the chart is under 600px wide
applying: function () {
labelSeries.data.setAll(offsetData(3)); // -12, -9, -6 and so on
zoomControl.set("layout", root.horizontalLayout); // the buttons side by side
},
removing: function () {
labelSeries.data.setAll(offsetData(1));
zoomControl.set("layout", root.verticalLayout);
}
});
// Make stuff animate on load
chart.appear(1000, 100);
More map tools.

SVG Map Generator
Any region, any projection
Pick a map and projection, simplify it and paint regions, then export SVG or PNG.
Pixel Map Generator
Dotted and pixel-art maps
Turn any map into dots, squares, hexagons or diamonds for posters and slides.

SVG Maps
427 maps, free to download
World, continents, countries and regions, with every region as its own named path.



