input-time-helper
v0.5.0
Published
Intuitively (by using local time) get/set the value of a date- or time-based HTML input element.
Readme
input-time-helper
Intuitively (by using local time) get/set the value of a date- or time-based HTML input element.
Motives
By default, the value of a date- or time-based HTML input element is in UTC, which is confusing.
For example, a user lives in an area where the timezone is GMT-8, and he/she fills in an input[type="date"] element with 2010-01-11. However, the following code shows him/her the date is 2010-01-10...
const element = document.querySelector("input[type='date']");
const date = element.valueAsDate;
console.log(`${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`);Moreover, the value/min/max attributes of these kinds of elements are formatted in specific patterns. We need to format our data into strings.
Usage
Get and Set the Value of an Input Element
import { getValueAsLocalDate, setValueAsLocalDate } from "input-time-helper";
const element = document.querySelector<HTMLInputElement>("input[type='date']")!;
const date = getValueAsLocalDate(element); // a `Date` in local time, or `null` if the input is empty
setValueAsLocalDate(element, new Date(2000, 1 - 1, 1));
setValueAsLocalDate(element, 946656000000); // a timestamp also works
setValueAsLocalDate(element, null); // clears the valueinput[type="date"], input[type="time"], and input[type="datetime-local"] are supported. Other types throw a TypeError.
- For
date, the time of the returnedDateis midnight. - For
time, the date of the returnedDateis 1970-01-01, the same asvalueAsDate. - For
timeanddatetime-local,setValueAsLocalDaterounds the time down to a multiple of thestepattribute (60 seconds by default), so the value does not cause a step mismatch. Setstep="any"to keep milliseconds.TimeUnitprovides commonstepvalues.
Format and Parse Strings
import {
formatDate,
formatDatetime,
formatTime,
parseDate,
parseDateAndTime,
parseDatetime,
parseTime,
} from "input-time-helper";
const date = new Date(2000, 1 - 1, 1, 13, 30);
console.log(formatDate(date)); // 2000-01-01
console.log(formatTime(date)); // 13:30
console.log(formatTime(date, { precision: "second" })); // 13:30:00
console.log(formatDatetime(date)); // 2000-01-01T13:30
console.log(formatDatetime(date, { separator: " " })); // 2000-01-01 13:30 (for SQL)
document.querySelector<HTMLInputElement>("input[type='date']")!.min = formatDate(new Date());
console.log(parseDate("2000-01-01")); // 2000-01-01 00:00 in local time
console.log(parseTime("13:30")); // 1970-01-01 13:30 in local time
console.log(parseDatetime("2000-01-01T13:30")); // 2000-01-01 13:30 in local time
console.log(parseDateAndTime("2000-01-01", "13:30")); // 2000-01-01 13:30 in local time
console.log(parseDate("")); // nullThe format functions accept a Date or a timestamp and return an empty string for an invalid date, so their results can be assigned to the value, min, or max attribute directly. The parse functions return null for an empty or invalid string.
Local ISO Strings
import { formatLocalISOString, formatTimezoneOffset } from "input-time-helper";
const date = new Date(2000, 1 - 1, 1);
console.log(formatLocalISOString(date)); // 2000-01-01T00:00:00.000+08:00
console.log(formatLocalISOString(date, { precision: "second" })); // 2000-01-01T00:00:00+08:00
console.log(formatTimezoneOffset(date.getTimezoneOffset())); // +08:00Unlike Date.prototype.toISOString, formatLocalISOString keeps the local time and appends the time zone offset. The result can be parsed back by new Date(string).
Migrating from 0.4
| 0.4 | 0.5 |
| ------------------------------------------------------ | ----------------------------------------------------- |
| formatDateToDateString(date) | formatDate(date) |
| formatDateToTimeString(date) | formatTime(date) |
| formatDateToDatetimeString(date, " ") | formatDatetime(date, { separator: " " }) |
| parseDateStringToDate(value) | parseDate(value) |
| parseDatetimeStringToDate(value) | parseDatetime(value) |
| parseDateAndTimeStringToDate(dateValue, timeValue) | parseDateAndTime(dateValue, timeValue) |
| formatTimezoneOffsetToString(offset) | formatTimezoneOffset(offset) |
| formatDateToLocalISOString(date) | formatLocalISOString(date) |
| toLocalISOString(date, { ignoreMilliseconds: true }) | formatLocalISOString(date, { precision: "second" }) |
| getTimestamp(element) | getValueAsLocalDate(element)?.getTime() |
| setTimestampDate(element, date) | setValueAsLocalDate(element, date) |
| setTimestampDateTime(element, date) | setValueAsLocalDate(element, date) |
- The parse functions and
getValueAsLocalDatereturnnullinstead of an invalidDateorNaN. formatLocalISOStringreturns an empty string for an invalid date, whiletoLocalISOStringthrew aRangeError.TimeUnitis a plain object instead of an enum, andTimeUnit.Millisecondis fixed from0.1to0.001.- The time zone offset of the given date is used instead of the current one, so dates across DST changes are no longer shifted by an hour.
