// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
// This module is browser compatible.

import { DateTimeFormatter } from "./_date_time_formatter.ts";

/** Options for {@linkcode format}. */
export interface FormatOptions {
  /**
   * Whether returns the formatted date in UTC instead of local time.
   *
   * @default {false}
   */
  utc?: boolean;
}

/**
 * Formats a date to a string with the specified format.
 *
 * The following symbols from
 * {@link https://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table | unicode LDML}
 * are supported:
 * - `yyyy` - numeric year
 * - `yy` - 2-digit year
 * - `M` - numeric month
 * - `MM` - 2-digit month
 * - `d` - numeric day
 * - `dd` - 2-digit day
 * - `H` - numeric hour (0-23 hours)
 * - `HH` - 2-digit hour (00-23 hours)
 * - `h` - numeric hour (1-12 hours)
 * - `hh` - 2-digit hour (01-12 hours)
 * - `m` - numeric minute
 * - `mm` - 2-digit minute
 * - `s` - numeric second
 * - `ss` - 2-digit second
 * - `S` - 1-digit fractional second
 * - `SS` - 2-digit fractional second
 * - `SSS` - 3-digit fractional second
 * - `a` - dayPeriod, either `AM` or `PM`
 * - `'foo'` - quoted literal
 * - `./-` - unquoted literal
 *
 * @param date The date to be formatted.
 * @param formatString The date time string format.
 * @param options The options to customize the formatting of the date.
 * @return The formatted date string.
 *
 * @example Basic usage
 * ```ts no-eval
 * import { format } from "@std/datetime/format";
 * import { assertEquals } from "@std/assert";
 *
 * const date = new Date(2019, 0, 20, 16, 34, 23, 123);
 *
 * assertEquals(format(date, "dd-MM-yyyy"), "20-01-2019");
 *
 * assertEquals(format(date, "MM-dd-yyyy HH:mm:ss.SSS"), "01-20-2019 16:34:23.123");
 *
 * assertEquals(format(date, "'today:' yyyy-MM-dd"), "today: 2019-01-20");
 * ```
 *
 * @example UTC formatting
 *
 * Enable UTC formatting by setting the `utc` option to `true`.
 *
 * ```ts no-eval
 * import { format } from "@std/datetime/format";
 * import { assertEquals } from "@std/assert";
 *
 * const date = new Date(2019, 0, 20, 16, 34, 23, 123);
 *
 * assertEquals(format(date, "yyyy-MM-dd HH:mm:ss", { utc: true }), "2019-01-20 05:34:23");
 * ```
 */
export function format(
  date: Date,
  formatString: string,
  options: FormatOptions = {},
): string {
  const formatter = new DateTimeFormatter(formatString);
  return formatter.format(
    date,
    options.utc ? { timeZone: "UTC" } : undefined,
  );
}

// denoCacheMetadata={"headers":{"server":"cloudflare","content-security-policy":"default-src 'none'; script-src 'none'; style-src 'none'; img-src 'none'; font-src 'none'; connect-src 'none'; frame-src 'none'; object-src 'none'; frame-ancestors 'none'; sandbox; form-action 'none';","date":"Tue, 28 Jul 2026 12:31:14 GMT","age":"112265","access-control-expose-headers":"*","cf-ray":"a223e6564f597db6-LAX","cross-origin-resource-policy":"cross-origin","x-content-type-options":"nosniff","alt-svc":"h3=\":443\"; ma=86400","content-length":"2494","x-jsr-backend":"modules","etag":"\"2498f208012db7b6df94d46c8408a970\"","vary":"Origin","nel":"{\"report_to\":\"cf-nel\",\"success_fraction\":0.0,\"max_age\":604800}","cf-cache-status":"HIT","content-type":"text/typescript","accept-ranges":"bytes","x-robots-tag":"noindex","cache-control":"public, max-age=31536000, immutable","report-to":"{\"group\":\"cf-nel\",\"max_age\":604800,\"endpoints\":[{\"url\":\"https://a.nel.cloudflare.com/report/v4?s=s0Eyk9OWSpeH7YWt%2BrjwWbK05xyIqRXlIvHo73gDzykTU0dg8t9oDoZV7roq7cCR4%2BenKvRukIttZsARPKxEk%2FC0TBMkPW3yiXD79dbo88KZoSBUQg1w4Q4%3D\"}]}","set-cookie":"__cf_bm=zY1fFUYimvwxri5lazMgLaVMuMI7vrB3x3YR5Pv_CeM-1785241874.9712286-1.0.1.1-EOUo_7YoBNO3qUe7.r8R37n.jrCvOih5QsBed.b8CAsPz8bvfLKi1fOitcD44MwYXteX6VHgLc2y0yw0BEp.h3p88UcYmQjUji_jWQq5..ZBfFAbf25fA1cAWHFsD3Gn; HttpOnly; SameSite=None; Secure; Path=/; Domain=jsr.io; Expires=Tue, 28 Jul 2026 13:01:14 GMT","access-control-allow-origin":"*"},"url":"https://jsr.io/@std/datetime/0.224.5/format.ts","time":1785241874}