Skip to content

Commit

Permalink
Add Interval.toLocaleString()
Browse files Browse the repository at this point in the history
This method is like DateTime.toLocaleString() but for intervals. It
takes the same arguments. It uses the native
DateTimeFormat.formatRange() method, now well supported by browsers.
  • Loading branch information
fodier committed Nov 8, 2022
1 parent ee02e99 commit c932b3c
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 5 deletions.
5 changes: 5 additions & 0 deletions src/impl/formatter.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,11 @@ export default class Formatter {
return df.formatToParts();
}

formatInterval(interval, opts = {}) {
const df = this.loc.dtFormatter(interval.start, { ...this.opts, ...opts });
return df.dtf.formatRange(interval.start.toJSDate(), interval.end.toJSDate());
}

resolvedOptions(dt, opts = {}) {
const df = this.loc.dtFormatter(dt, { ...this.opts, ...opts });
return df.resolvedOptions();
Expand Down
40 changes: 35 additions & 5 deletions src/interval.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import Duration from "./duration.js";
import Settings from "./settings.js";
import { InvalidArgumentError, InvalidIntervalError } from "./errors.js";
import Invalid from "./impl/invalid.js";
import Formatter from "./impl/formatter.js";
import * as Formats from "./impl/formats.js";

const INVALID = "Invalid Interval";

Expand Down Expand Up @@ -32,7 +34,7 @@ function validateStartEnd(start, end) {
* * **Interrogation** To analyze the Interval, use {@link Interval#count}, {@link Interval#length}, {@link Interval#hasSame}, {@link Interval#contains}, {@link Interval#isAfter}, or {@link Interval#isBefore}.
* * **Transformation** To create other Intervals out of this one, use {@link Interval#set}, {@link Interval#splitAt}, {@link Interval#splitBy}, {@link Interval#divideEqually}, {@link Interval.merge}, {@link Interval.xor}, {@link Interval#union}, {@link Interval#intersection}, or {@link Interval#difference}.
* * **Comparison** To compare this Interval to another one, use {@link Interval#equals}, {@link Interval#overlaps}, {@link Interval#abutsStart}, {@link Interval#abutsEnd}, {@link Interval#engulfs}
* * **Output** To convert the Interval into other representations, see {@link Interval#toString}, {@link Interval#toISO}, {@link Interval#toISODate}, {@link Interval#toISOTime}, {@link Interval#toFormat}, and {@link Interval#toDuration}.
* * **Output** To convert the Interval into other representations, see {@link Interval#toString}, {@link Interval#toLocaleString}, {@link Interval#toISO}, {@link Interval#toISODate}, {@link Interval#toISOTime}, {@link Interval#toFormat}, and {@link Interval#toDuration}.
*/
export default class Interval {
/**
Expand Down Expand Up @@ -529,6 +531,30 @@ export default class Interval {
return `[${this.s.toISO()}${this.e.toISO()})`;
}

/**
* Returns a localized string representing this Interval. Accepts the same options as the
* Intl.DateTimeFormat constructor and any presets defined by Luxon, such as
* {@link DateTime.DATE_FULL} or {@link DateTime.TIME_SIMPLE}. The exact behavior of this method
* is browser-specific, but in general it will return an appropriate representation of the
* Interval in the assigned locale. Defaults to the system's locale if no locale has been
* specified.
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat
* @param {Object} [formatOpts=DateTime.DATE_SHORT] - Either a DateTime preset or
* Intl.DateTimeFormat constructor options.
* @param {Object} opts - Options to override the configuration of the start DateTime.
* @example Interval.fromISO('2022-11-07T09:00Z/2022-11-08T09:00Z').toLocaleString(); //=> 11/7/2022 – 11/8/2022
* @example Interval.fromISO('2022-11-07T09:00Z/2022-11-08T09:00Z').toLocaleString(DateTime.DATE_FULL); //=> November 7 – 8, 2022
* @example Interval.fromISO('2022-11-07T09:00Z/2022-11-08T09:00Z').toLocaleString(DateTime.DATE_FULL, { locale: 'fr-FR' }); //=> 7–8 novembre 2022
* @example Interval.fromISO('2022-11-07T17:00Z/2022-11-07T19:00Z').toLocaleString(DateTime.TIME_SIMPLE); //=> 6:00 – 8:00 PM
* @example Interval.fromISO('2022-11-07T17:00Z/2022-11-07T19:00Z').toLocaleString({ weekday: 'short', month: 'short', day: '2-digit', hour: '2-digit', minute: '2-digit' }); //=> Mon, Nov 07, 6:00 – 8:00 p
* @return {string}
*/
toLocaleString(formatOpts = Formats.DATE_SHORT, opts = {}) {
return this.isValid
? Formatter.create(this.s.loc.clone(opts), formatOpts).formatInterval(this)
: INVALID;
}

/**
* Returns an ISO 8601-compliant string representation of this Interval.
* @see https://en.wikipedia.org/wiki/ISO_8601#Time_intervals
Expand Down Expand Up @@ -564,10 +590,14 @@ export default class Interval {
}

/**
* Returns a string representation of this Interval formatted according to the specified format string.
* @param {string} dateFormat - the format string. This string formats the start and end time. See {@link DateTime#toFormat} for details.
* @param {Object} opts - options
* @param {string} [opts.separator = ' – '] - a separator to place between the start and end representations
* Returns a string representation of this Interval formatted according to the specified format
* string. **You may not want this.** See {@link Interval#toLocaleString} for a more flexible
* formatting tool.
* @param {string} dateFormat - The format string. This string formats the start and end time.
* See {@link DateTime#toFormat} for details.
* @param {Object} opts - Options.
* @param {string} [opts.separator = ' – '] - A separator to place between the start and end
* representations.
* @return {string}
*/
toFormat(dateFormat, { separator = " – " } = {}) {
Expand Down

0 comments on commit c932b3c

Please sign in to comment.