summaryrefslogtreecommitdiff
path: root/std/datetime
diff options
context:
space:
mode:
Diffstat (limited to 'std/datetime')
m---------std0
-rw-r--r--std/datetime/README.md39
-rw-r--r--std/datetime/mod.ts146
-rw-r--r--std/datetime/test.ts96
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);
+ }
+});