La hora en México es (JS)
¿Que hora es en México en este mismo momento? Para eso aquí un gadget por si publicas en otros paises y quieres te contacten y deseas sepan de mera casualidad la hora en México.
El resultado será:
 <script id="rendered-js" type="module">
class Mexico extends HTMLElement {
	static tagName = "hr-mx";
	static prefix = "hr-mx--";
	static attr = {
		template: "data-Mexico",
		ready: "ready",
		defer: "defer-hydration"
	};
	static onceCache = new Map();
	static onReady = new Map();
	static fallback = {
		":not(hr-mx,:defined,[defer-hydration])": (readyPromise, node, prefix) => {
			// remove from document to prevent web component init
			let cloned = document.createElement(prefix + node.localName);
			for (let attr of node.getAttributeNames()) {
				cloned.setAttribute(attr, node.getAttribute(attr));
			}
			// Declarative Shadow DOM (with polyfill)
			let shadowroot = node.shadowRoot;
			if (!shadowroot) {
				let tmpl = node.querySelector(
					":scope > template:is([shadowrootmode], [shadowroot])"
				);
				if (tmpl) {
					let mode =
						tmpl.getAttribute("shadowrootmode") ||
						tmpl.getAttribute("shadowroot") ||
						"closed";
					shadowroot = node.attachShadow({ mode }); // default is closed
					shadowroot.appendChild(tmpl.content.cloneNode(true));
				}
			}
			// Cheers to https://gist.github.com/developit/45c85e9be01e8c3f1a0ec073d600d01e
			if (shadowroot) {
				cloned
					.attachShadow({ mode: shadowroot.mode })
					.append(...shadowroot.childNodes);
			}
			// Keep *same* child nodes to preserve state of children (e.g. details->summary)
			cloned.append(...node.childNodes);
			node.replaceWith(cloned);
			return readyPromise.then(() => {
				// Restore original children and shadow DOM
				if (cloned.shadowRoot) {
					node.shadowRoot.append(...cloned.shadowRoot.childNodes);
				}
				node.append(...cloned.childNodes);
				cloned.replaceWith(node);
			});
		}
	};
	constructor() {
		super();
		// Internal promises
		this.ready = new Promise((resolve) => {
			this.readyResolve = resolve;
		});
	}
	// any parents of `el` that are <hr-mx> (with conditions)
	static getParents(el, stopAt = false) {
		let nodes = [];
		while (el) {
			if (el.matches && el.matches(Mexico.tagName)) {
				if (stopAt && el === stopAt) {
					break;
				}
				if (Conditions.hasConditions(el)) {
					nodes.push(el);
				}
			}
			el = el.parentNode;
		}
		return nodes;
	}
	static async ready(el, parents) {
		if (!parents) {
			parents = Mexico.getParents(el);
		}
		if (parents.length === 0) {
			return;
		}
		let imports = await Promise.all(parents.map((p) => p.wait()));
		// return innermost module import
		if (imports.length) {
			return imports[0];
		}
	}
	forceFallback() {
		if (window.Mexico) {
			Object.assign(Mexico.fallback, window.Mexico.fallback);
		}
		for (let selector in Mexico.fallback) {
			// Reverse here as a cheap way to get the deepest nodes first
			let components = Array.from(this.querySelectorAll(selector)).reverse();
			// with thanks to https://gist.github.com/cowboy/938767
			for (let node of components) {
				if (!node.isConnected) {
					continue;
				}
				let parents = Mexico.getParents(node);
				// must be in a leaf Mexico (not nested deep)
				if (parents.length === 1) {
					let p = Mexico.ready(node, parents);
					Mexico.fallback[selector](p, node, Mexico.prefix);
				}
			}
		}
	}
	wait() {
		return this.ready;
	}
	async connectedCallback() {
		// Only use fallback content with loading conditions
		if (Conditions.hasConditions(this)) {
			// Keep fallback content without initializing the components
			this.forceFallback();
		}
		await this.hydrate();
	}
	getTemplates() {
		return this.querySelectorAll(`template[${Mexico.attr.template}]`);
	}
	replaceTemplates(templates) {
		// replace <template> with the live content
		for (let node of templates) {
			// if the template is nested inside another child <hr-mx> inside, skip
			if (Mexico.getParents(node, this).length > 0) {
				continue;
			}
			let value = node.getAttribute(Mexico.attr.template);
			// get rid of the rest of the content on the Mexico
			if (value === "replace") {
				let children = Array.from(this.childNodes);
				for (let child of children) {
					this.removeChild(child);
				}
				this.appendChild(node.content);
				break;
			} else {
				let html = node.innerHTML;
				if (value === "once" && html) {
					if (Mexico.onceCache.has(html)) {
						node.remove();
						return;
					}
					Mexico.onceCache.set(html, true);
				}
				node.replaceWith(node.content);
			}
		}
	}
	async hydrate() {
		let conditions = [];
		if (this.parentNode) {
			// wait for all parents before hydrating
			conditions.push(Mexico.ready(this.parentNode));
		}
		let attrs = Conditions.getConditions(this);
		for (let condition in attrs) {
			if (Conditions.map[condition]) {
				conditions.push(Conditions.map[condition](attrs[condition], this));
			}
		}
		// Loading conditions must finish before dependencies are loaded
		await Promise.all(conditions);
		this.replaceTemplates(this.getTemplates());
		for (let fn of Mexico.onReady.values()) {
			await fn.call(this, Mexico);
		}
		this.readyResolve();
		this.setAttribute(Mexico.attr.ready, "");
		// Remove [defer-hydration]
		this.querySelectorAll(`[${Mexico.attr.defer}]`).forEach((node) =>
			node.removeAttribute(Mexico.attr.defer)
		);
	}
}
class Conditions {
	static map = {
		visible: Conditions.visible,
		idle: Conditions.idle,
		interaction: Conditions.interaction,
		media: Conditions.media,
		"save-data": Conditions.saveData
	};
	static hasConditions(node) {
		return Object.keys(Conditions.getConditions(node)).length > 0;
	}
	static getConditions(node) {
		let map = {};
		for (let key of Object.keys(Conditions.map)) {
			if (node.hasAttribute(`on:${key}`)) {
				map[key] = node.getAttribute(`on:${key}`);
			}
		}
		return map;
	}
	static visible(noop, el) {
		if (!("IntersectionObserver" in window)) {
			// runs immediately
			return;
		}
		return new Promise((resolve) => {
			let observer = new IntersectionObserver((entries) => {
				let [entry] = entries;
				if (entry.isIntersecting) {
					observer.unobserve(entry.target);
					resolve();
				}
			});
			observer.observe(el);
		});
	}
	// Warning: on:idle is not very useful with other conditions as it may resolve long before.
	static idle() {
		let onload = new Promise((resolve) => {
			if (document.readyState !== "complete") {
				window.addEventListener("load", () => resolve(), { once: true });
			} else {
				resolve();
			}
		});
		if (!("requestIdleCallback" in window)) {
			// run immediately
			return onload;
		}
		// both idle and onload
		return Promise.all([
			new Promise((resolve) => {
				requestIdleCallback(() => {
					resolve();
				});
			}),
			onload
		]);
	}
	static interaction(eventOverrides, el) {
		let events = ["click", "touchstart"];
		// event overrides e.g. on:interaction="mouseenter"
		if (eventOverrides) {
			events = (eventOverrides || "").split(",").map((entry) => entry.trim());
		}
		return new Promise((resolve) => {
			function resolveFn(e) {
				resolve();
				// cleanup the other event handlers
				for (let name of events) {
					el.removeEventListener(name, resolveFn);
				}
			}
			for (let name of events) {
				el.addEventListener(name, resolveFn, { once: true });
			}
		});
	}
	static media(query) {
		let mm = {
			matches: true
		};
		if (query && "matchMedia" in window) {
			mm = window.matchMedia(query);
		}
		if (mm.matches) {
			return;
		}
		return new Promise((resolve) => {
			mm.addListener((e) => {
				if (e.matches) {
					resolve();
				}
			});
		});
	}
	static saveData(expects) {
		// return early if API does not exist
		if (
			!("connection" in navigator) ||
			navigator.connection.saveData === (expects !== "false")
		) {
			return;
		}
		// dangly promise
		return new Promise(() => {});
	}
}
// Should this auto define? Folks can redefine later using { component } export
if ("customElements" in window) {
	window.customElements.define(Mexico.tagName, Mexico);
	window.Mexico = Mexico;
}
export {
	Mexico,
	Mexico as component // Backwards compat only: recommend `Mexico` export
};
// TODO remove in 4.0
export const ready = Mexico.ready; // Backwards compat only: recommend `Mexico` export
    </script><hr-mx on:visible="">
	<template data-Mexico="">
		<local-time><span lang="en">Time in Mexico City:</span> <span id="current-live-time"></span>
		</local-time>
		<script>
			let options = {
				timeZone: 'America/Mexico_City',
				hour: 'numeric',
				minute: 'numeric',
			}
			function updateTime() {
				document.getElementById('current-live-time').textContent = (new Date()).toLocaleString([], options);
			}
			updateTime();
			window.setInterval(updateTime, 1000);
		</script>
		<script></script>
	</template>
</hr-mx>
Por cierto, sabias que en español es correcto escribir dos mil (separado, no junto) y es correcto veintidós (con tilde).
View on Instagram View on Flickr View on Twitter