diff options
Diffstat (limited to 'std/datetime')
m--------- | std | 0 | ||||
-rw-r--r-- | std/datetime/README.md | 39 | ||||
-rw-r--r-- | std/datetime/mod.ts | 146 | ||||
-rw-r--r-- | std/datetime/test.ts | 96 |
4 files changed, 281 insertions, 0 deletions
diff --git a/std b/std deleted file mode 160000 -Subproject 43aafbf33285753e7b42230f0eb7969b300f71c diff --git a/std/datetime/README.md b/std/datetime/README.md new file mode 100644 index 000000000..177532239 --- /dev/null +++ b/std/datetime/README.md @@ -0,0 +1,39 @@ +# datetime + +Simple helper to help parse date strings into `Date`, with additional functions. + +## Usage + +### parseDate / parseDateTime + +- `parseDate()` - Take an input string and a format to parse the date. Supported + formats are exported in `DateFormat`. +- `parseDateTime()` - Take an input string and a format to parse the dateTime. + Supported formats are exported in `DateTimeFormat`. + +```ts +import { parseDate, parseDateTime } from 'https://deno.land/std/datetime/mod.ts' + +parseDate("03-01-2019", "dd-mm-yyyy") // output : new Date(2019, 1, 3) +parseDate("2019-01-03", "yyyy-mm-dd") // output : new Date(2019, 1, 3) +... + +parseDateTime("01-03-2019 16:34", "mm-dd-yyyy hh:mm") // output : new Date(2019, 1, 3, 16, 34) +parseDateTime("16:34 01-03-2019", "hh:mm mm-dd-yyyy") // output : new Date(2019, 1, 3, 16, 34) +... +``` + +### dayOfYear / currentDayOfYear + +- `dayOfYear()` - Returns the number of the day in the year. +- `currentDayOfYear()` - Returns the number of the current day in the year. + +```ts +import { + dayOfYear, + currentDayOfYear +} from "https://deno.land/std/datetime/mod.ts"; + +dayOfYear(new Date("2019-03-11T03:24:00")); // output: 70 +currentDayOfYear(); // output: ** depends on when you run it :) ** +``` diff --git a/std/datetime/mod.ts b/std/datetime/mod.ts new file mode 100644 index 000000000..efa6e09fe --- /dev/null +++ b/std/datetime/mod.ts @@ -0,0 +1,146 @@ +// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. +import { pad } from "../strings/pad.ts"; + +export type DateFormat = "mm-dd-yyyy" | "dd-mm-yyyy" | "yyyy-mm-dd"; + +/** + * Parse date from string using format string + * @param dateStr Date string + * @param format Format string + * @return Parsed date + */ +export function parseDate(dateStr: string, format: DateFormat): Date { + let m, d, y: string; + let datePattern: RegExp; + + switch (format) { + case "mm-dd-yyyy": + datePattern = /^(\d{2})-(\d{2})-(\d{4})$/; + [, m, d, y] = datePattern.exec(dateStr)!; + break; + case "dd-mm-yyyy": + datePattern = /^(\d{2})-(\d{2})-(\d{4})$/; + [, d, m, y] = datePattern.exec(dateStr)!; + break; + case "yyyy-mm-dd": + datePattern = /^(\d{4})-(\d{2})-(\d{2})$/; + [, y, m, d] = datePattern.exec(dateStr)!; + break; + default: + throw new Error("Invalid date format!"); + } + + return new Date(Number(y), Number(m) - 1, Number(d)); +} + +export type DateTimeFormat = + | "mm-dd-yyyy hh:mm" + | "dd-mm-yyyy hh:mm" + | "yyyy-mm-dd hh:mm" + | "hh:mm mm-dd-yyyy" + | "hh:mm dd-mm-yyyy" + | "hh:mm yyyy-mm-dd"; + +/** + * Parse date & time from string using format string + * @param dateStr Date & time string + * @param format Format string + * @return Parsed date + */ +export function parseDateTime( + datetimeStr: string, + format: DateTimeFormat +): Date { + let m, d, y, ho, mi: string; + let datePattern: RegExp; + + switch (format) { + case "mm-dd-yyyy hh:mm": + datePattern = /^(\d{2})-(\d{2})-(\d{4}) (\d{2}):(\d{2})$/; + [, m, d, y, ho, mi] = datePattern.exec(datetimeStr)!; + break; + case "dd-mm-yyyy hh:mm": + datePattern = /^(\d{2})-(\d{2})-(\d{4}) (\d{2}):(\d{2})$/; + [, d, m, y, ho, mi] = datePattern.exec(datetimeStr)!; + break; + case "yyyy-mm-dd hh:mm": + datePattern = /^(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2})$/; + [, y, m, d, ho, mi] = datePattern.exec(datetimeStr)!; + break; + case "hh:mm mm-dd-yyyy": + datePattern = /^(\d{2}):(\d{2}) (\d{2})-(\d{2})-(\d{4})$/; + [, ho, mi, m, d, y] = datePattern.exec(datetimeStr)!; + break; + case "hh:mm dd-mm-yyyy": + datePattern = /^(\d{2}):(\d{2}) (\d{2})-(\d{2})-(\d{4})$/; + [, ho, mi, d, m, y] = datePattern.exec(datetimeStr)!; + break; + case "hh:mm yyyy-mm-dd": + datePattern = /^(\d{2}):(\d{2}) (\d{4})-(\d{2})-(\d{2})$/; + [, ho, mi, y, m, d] = datePattern.exec(datetimeStr)!; + break; + default: + throw new Error("Invalid datetime format!"); + } + + return new Date(Number(y), Number(m) - 1, Number(d), Number(ho), Number(mi)); +} + +/** + * Get number of the day in the year + * @return Number of the day in year + */ +export function dayOfYear(date: Date): number { + const dayMs = 1000 * 60 * 60 * 24; + const yearStart = new Date(date.getFullYear(), 0, 0); + const diff = + date.getTime() - + yearStart.getTime() + + (yearStart.getTimezoneOffset() - date.getTimezoneOffset()) * 60 * 1000; + return Math.floor(diff / dayMs); +} + +/** + * Get number of current day in year + * @return Number of current day in year + */ +export function currentDayOfYear(): number { + return dayOfYear(new Date()); +} + +/** + * Parse a date to return a IMF formated string date + * RFC: https://tools.ietf.org/html/rfc7231#section-7.1.1.1 + * IMF is the time format to use when generating times in HTTP + * headers. The time being formatted must be in UTC for Format to + * generate the correct format. + * @param date Date to parse + * @return IMF date formated string + */ +export function toIMF(date: Date): string { + function dtPad(v: string, lPad = 2): string { + return pad(v, lPad, { char: "0" }); + } + const d = dtPad(date.getUTCDate().toString()); + const h = dtPad(date.getUTCHours().toString()); + const min = dtPad(date.getUTCMinutes().toString()); + const s = dtPad(date.getUTCSeconds().toString()); + const y = date.getUTCFullYear(); + const days = ["Sun", "Mon", "Tue", "Wed", "Thus", "Fri", "Sat"]; + const months = [ + "Jan", + "Feb", + "Mar", + "May", + "Jun", + "Jul", + "Aug", + "Sep", + "Oct", + "Nov", + "Dec" + ]; + return `${days[date.getUTCDay()]}, ${d} ${ + months[date.getUTCMonth()] + } ${y} ${h}:${min}:${s} GMT`; +} diff --git a/std/datetime/test.ts b/std/datetime/test.ts new file mode 100644 index 000000000..ecf844a41 --- /dev/null +++ b/std/datetime/test.ts @@ -0,0 +1,96 @@ +// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. +import { test } from "../testing/mod.ts"; +import { assertEquals, assertThrows } from "../testing/asserts.ts"; +import * as datetime from "./mod.ts"; + +test(function parseDateTime(): void { + assertEquals( + datetime.parseDateTime("01-03-2019 16:30", "mm-dd-yyyy hh:mm"), + new Date(2019, 0, 3, 16, 30) + ); + assertEquals( + datetime.parseDateTime("03-01-2019 16:31", "dd-mm-yyyy hh:mm"), + new Date(2019, 0, 3, 16, 31) + ); + assertEquals( + datetime.parseDateTime("2019-01-03 16:32", "yyyy-mm-dd hh:mm"), + new Date(2019, 0, 3, 16, 32) + ); + assertEquals( + datetime.parseDateTime("16:33 01-03-2019", "hh:mm mm-dd-yyyy"), + new Date(2019, 0, 3, 16, 33) + ); + assertEquals( + datetime.parseDateTime("16:34 03-01-2019", "hh:mm dd-mm-yyyy"), + new Date(2019, 0, 3, 16, 34) + ); + assertEquals( + datetime.parseDateTime("16:35 2019-01-03", "hh:mm yyyy-mm-dd"), + new Date(2019, 0, 3, 16, 35) + ); +}); + +test(function invalidParseDateTimeFormatThrows(): void { + assertThrows( + (): void => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (datetime as any).parseDateTime("2019-01-01 00:00", "x-y-z"); + }, + Error, + "Invalid datetime format!" + ); +}); + +test(function parseDate(): void { + assertEquals( + datetime.parseDate("01-03-2019", "mm-dd-yyyy"), + new Date(2019, 0, 3) + ); + assertEquals( + datetime.parseDate("03-01-2019", "dd-mm-yyyy"), + new Date(2019, 0, 3) + ); + assertEquals( + datetime.parseDate("2019-01-03", "yyyy-mm-dd"), + new Date(2019, 0, 3) + ); +}); + +test(function invalidParseDateFormatThrows(): void { + assertThrows( + (): void => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (datetime as any).parseDate("2019-01-01", "x-y-z"); + }, + Error, + "Invalid date format!" + ); +}); + +test(function DayOfYear(): void { + assertEquals(1, datetime.dayOfYear(new Date("2019-01-01T03:24:00"))); + assertEquals(70, datetime.dayOfYear(new Date("2019-03-11T03:24:00"))); + assertEquals(365, datetime.dayOfYear(new Date("2019-12-31T03:24:00"))); +}); + +test(function currentDayOfYear(): void { + assertEquals(datetime.currentDayOfYear(), datetime.dayOfYear(new Date())); +}); + +test({ + name: "[DateTime] to IMF", + fn(): void { + const actual = datetime.toIMF(new Date(Date.UTC(1994, 3, 5, 15, 32))); + const expected = "Tue, 05 May 1994 15:32:00 GMT"; + assertEquals(actual, expected); + } +}); + +test({ + name: "[DateTime] to IMF 0", + fn(): void { + const actual = datetime.toIMF(new Date(0)); + const expected = "Thus, 01 Jan 1970 00:00:00 GMT"; + assertEquals(actual, expected); + } +}); |