Code Monkey home page Code Monkey logo

date-and-time's Introduction

date-and-time

Circle CI

This JS library is just a collection of functions for manipulating date and time. It's small, simple, and easy to learn.

Why

Nowadays, JS modules have become larger, more complex, and dependent on many other modules. It is important to strive for simplicity and smallness, especially for modules that are at the bottom of the dependency chain, such as those that handle date and time.

Features

  • Minimalist. Approximately 2k. (minified and gzipped)
  • Extensible. Plugin system support.
  • Multi language support.
  • Universal / Isomorphic. Works anywhere.
  • TypeScript support.
  • Older browser support. Even works on IE6. :)

Install

npm i date-and-time

Recent Changes

  • 3.2.0

    • Refactored compile(), format(), and preparse() slightly improved performance.
  • 3.1.1

    • Fixed an issue where format() could output incorrect UTC times in locales with daylight savings time.
    • Refactored formatTZ() of timezone plugin.
  • 3.1.0

    • Improved accuracy of parseTZ() in timezone plugin.
    • Organized some test modules.

Usage

  • ES Modules:
import date from 'date-and-time';
  • CommonJS:
const date = require('date-and-time');
  • ES Modules for the browser:
<script type="module">
import date from '/path/to/date-and-time.es.min.js';
</script>
  • Older browser:
<script src="/path/to/date-and-time.min.js">
// You will be able to access the global variable `date`.
</script>

Note

  • If you want to use ES Modules in Node.js without the transpiler, you need to add "type": "module" in your package.json or change your file extension from .js to .mjs.

API

format(dateObj, arg[, utc])

  • @param {Date} dateObj - A Date object
  • @param {string|Array.<string>} arg - A format string or its compiled object
  • @param {boolean} [utc] - Output as UTC
  • @returns {string} A formatted string
const now = new Date();
date.format(now, 'YYYY/MM/DD HH:mm:ss');    // => '2015/01/02 23:14:05'
date.format(now, 'ddd, MMM DD YYYY');       // => 'Fri, Jan 02 2015'
date.format(now, 'hh:mm A [GMT]Z');         // => '11:14 PM GMT-0800'
date.format(now, 'hh:mm A [GMT]Z', true);   // => '07:14 AM GMT+0000'

const pattern = date.compile('ddd, MMM DD YYYY');
date.format(now, pattern);                  // => 'Fri, Jan 02 2015'

Available tokens and their meanings are as follows:

token meaning examples of output
YYYY four-digit year 0999, 2015
YY two-digit year 99, 01, 15
Y four-digit year without zero-padding 2, 44, 888, 2015
MMMM month name (long) January, December
MMM month name (short) Jan, Dec
MM month with zero-padding 01, 12
M month 1, 12
DD date with zero-padding 02, 31
D date 2, 31
dddd day of week (long) Friday, Sunday
ddd day of week (short) Fri, Sun
dd day of week (very short) Fr, Su
HH 24-hour with zero-padding 23, 08
H 24-hour 23, 8
hh 12-hour with zero-padding 11, 08
h 12-hour 11, 8
A meridiem (uppercase) AM, PM
mm minute with zero-padding 14, 07
m minute 14, 7
ss second with zero-padding 05, 10
s second 5, 10
SSS millisecond (high accuracy) 753, 022
SS millisecond (middle accuracy) 75, 02
S millisecond (low accuracy) 7, 0
Z time zone offset value +0100, -0800
ZZ time zone offset value with colon +01:00, -08:00

You can also use the following tokens by importing plugins. See PLUGINS.md for details.

token meaning examples of output
DDD ordinal notation of date 1st, 2nd, 3rd
AA meridiem (uppercase with ellipsis) A.M., P.M.
a meridiem (lowercase) am, pm
aa meridiem (lowercase with ellipsis) a.m., p.m.

Note 1. Comments

Parts of the given format string enclosed in square brackets are considered comments and are output as is, regardless of whether they are tokens or not.

date.format(new Date(), 'DD-[MM]-YYYY');    // => '02-MM-2015'
date.format(new Date(), '[DD-[MM]-YYYY]');  // => 'DD-[MM]-YYYY'

Note 2. Output as UTC

This function outputs the date and time in the local time zone of the execution environment by default. If you want to output in UTC, set the UTC option (the third argument) to true. To output in any other time zone, you will need a plugin.

date.format(new Date(), 'hh:mm A [GMT]Z');          // => '11:14 PM GMT-0800'
date.format(new Date(), 'hh:mm A [GMT]Z', true);    // => '07:14 AM GMT+0000'

Note 3. More Tokens

You can also define your own tokens. See EXTEND.md for details.

parse(dateString, arg[, utc])

  • @param {string} dateString - A date and time string
  • @param {string|Array.<string>} arg - A format string or its compiled object
  • @param {boolean} [utc] - Input as UTC
  • @returns {Date} A Date object
date.parse('2015/01/02 23:14:05', 'YYYY/MM/DD HH:mm:ss');   // => Jan 2 2015 23:14:05 GMT-0800
date.parse('02-01-2015', 'DD-MM-YYYY');                     // => Jan 2 2015 00:00:00 GMT-0800
date.parse('11:14:05 PM', 'hh:mm:ss A');                    // => Jan 1 1970 23:14:05 GMT-0800
date.parse('11:14:05 PM', 'hh:mm:ss A', true);              // => Jan 1 1970 23:14:05 GMT+0000 (Jan 1 1970 15:14:05 GMT-0800)
date.parse('23:14:05 GMT+0900', 'HH:mm:ss [GMT]Z');         // => Jan 1 1970 23:14:05 GMT+0900 (Jan 1 1970 06:14:05 GMT-0800)
date.parse('Jam 1 2017', 'MMM D YYYY');                     // => Invalid Date
date.parse('Feb 29 2017', 'MMM D YYYY');                    // => Invalid Date

Available tokens and their meanings are as follows:

token meaning examples of acceptable form
YYYY four-digit year 0999, 2015
Y four-digit year without zero-padding 2, 44, 88, 2015
MMMM month name (long) January, December
MMM month name (short) Jan, Dec
MM month with zero-padding 01, 12
M month 1, 12
DD date with zero-padding 02, 31
D date 2, 31
HH 24-hour with zero-padding 23, 08
H 24-hour 23, 8
hh 12-hour with zero-padding 11, 08
h 12-hour 11, 8
A meridiem (uppercase) AM, PM
mm minute with zero-padding 14, 07
m minute 14, 7
ss second with zero-padding 05, 10
s second 5, 10
SSS millisecond (high accuracy) 753, 022
SS millisecond (middle accuracy) 75, 02
S millisecond (low accuracy) 7, 0
Z time zone offset value +0100, -0800
ZZ time zone offset value with colon +01:00, -08:00

You can also use the following tokens by importing plugins. See PLUGINS.md for details.

token meaning examples of acceptable form
YY two-digit year 90, 00, 08, 19
AA meridiem (uppercase with ellipsis) A.M., P.M.
a meridiem (lowercase) am, pm
aa meridiem (lowercase with ellipsis) a.m., p.m.
dddd day of week (long) Friday, Sunday
ddd day of week (short) Fri, Sun
dd day of week (very short) Fr, Su
SSSSSS microsecond (high accuracy) 123456, 000001
SSSSS microsecond (middle accuracy) 12345, 00001
SSSS microsecond (low accuracy) 1234, 0001

Note 1. Invalid Date

If this function fails to parse, it will return Invalid Date. Notice that the Invalid Date is a Date object, not NaN or null. You can tell whether the Date object is invalid as follows:

const today = date.parse('Jam 1 2017', 'MMM D YYYY');

if (isNaN(today.getTime())) {
    // Failure
}

Note 2. Input as UTC

This function uses the local time zone offset value of the execution environment by default if the given string does not contain a time zone offset value. To make it use UTC instead, set the UTC option (the third argument) to true. If you want it to use any other time zone, you will need a plugin.

date.parse('11:14:05 PM', 'hh:mm:ss A');          // => Jan 1 1970 23:14:05 GMT-0800
date.parse('11:14:05 PM', 'hh:mm:ss A', true);    // => Jan 1 1970 23:14:05 GMT+0000 (Jan 1 1970 15:14:05 GMT-0800)

Note 3. Default Date Time

Default date is January 1, 1970, time is 00:00:00.000. Values not passed will be complemented with them:

date.parse('11:14:05 PM', 'hh:mm:ss A');    // => Jan 1 1970 23:14:05 GMT-0800
date.parse('Feb 2000', 'MMM YYYY');         // => Feb 1 2000 00:00:00 GMT-0800

Note 4. Max Date / Min Date

Parsable maximum date is December 31, 9999, minimum date is January 1, 0001.

date.parse('Dec 31 9999', 'MMM D YYYY');    // => Dec 31 9999 00:00:00 GMT-0800
date.parse('Dec 31 10000', 'MMM D YYYY');   // => Invalid Date

date.parse('Jan 1 0001', 'MMM D YYYY');     // => Jan 1 0001 00:00:00 GMT-0800
date.parse('Jan 1 0000', 'MMM D YYYY');     // => Invalid Date

Note 5. 12-hour notation and Meridiem

If use hh or h (12-hour) token, use together A (meridiem) token to get the right value.

date.parse('11:14:05', 'hh:mm:ss');         // => Jan 1 1970 11:14:05 GMT-0800
date.parse('11:14:05 PM', 'hh:mm:ss A');    // => Jan 1 1970 23:14:05 GMT-0800

Note 6. Token invalidation

Any part of the given format string that you do not want to be recognized as a token should be enclosed in square brackets. They are considered comments and will not be parsed.

date.parse('12 hours 34 minutes', 'HH hours mm minutes');       // => Invalid Date
date.parse('12 hours 34 minutes', 'HH [hours] mm [minutes]');   // => Jan 1 1970 12:34:00 GMT-0800

Note 7. Wildcard

Whitespace acts as a wildcard token. This token will not parse the corresponding parts of the date and time strings. This behavior is similar to enclosing part of a format string in square brackets (Token invalidation), but with the flexibility that the contents do not have to match, as long as the number of characters in the corresponding parts match.

// This will be an error.
date.parse('2015/01/02 11:14:05', 'YYYY/MM/DD');            // => Invalid Date
// Adjust the length of the format string by appending white spaces of the same length as a part to ignore to the end of it.
date.parse('2015/01/02 11:14:05', 'YYYY/MM/DD         ');   // => Jan 2 2015 00:00:00 GMT-0800

Note 8. Ellipsis

... token ignores subsequent corresponding date and time strings. Use this token only at the end of a format string. The above example can be also written like this:

date.parse('2015/01/02 11:14:05', 'YYYY/MM/DD...');   // => Jan 2 2015 00:00:00 GMT-0800

compile(formatString)

  • @param {string} formatString - A format string
  • @returns {Array.<string>} A compiled object

If you are going to execute the format(), the parse() or the isValid() so many times with one string format, recommended to precompile and reuse it for performance.

  const pattern = date.compile('MMM D YYYY h:m:s A');

  date.parse('Mar 22 2019 2:54:21 PM', pattern);
  date.parse('Jul 27 2019 4:15:24 AM', pattern);
  date.parse('Dec 25 2019 3:51:11 AM', pattern);

  date.format(new Date(), pattern); // => Mar 16 2020 6:24:56 PM

preparse(dateString, arg)

  • @param {string} dateString - A date and time string
  • @param {string|Array.<string>} arg - A format string or its compiled object
  • @returns {Object} A pre-parsed result object

This function takes exactly the same parameters with the parse(), but returns a date structure as follows unlike that:

date.preparse('Fri Jan 2015 02 23:14:05 GMT-0800', '    MMM YYYY DD HH:mm:ss [GMT]Z');

{
    Y: 2015,        // Year
    M: 1,           // Month
    D: 2,           // Day
    H: 23,          // 24-hour
    A: 0,           // Meridiem
    h: 0,           // 12-hour
    m: 14,          // Minute
    s: 5,           // Second
    S: 0,           // Millisecond
    Z: 480,         // Timsezone offset
    _index: 33,     // Pointer offset
    _length: 33,    // Length of the date string
    _match: 7       // Token matching count
}

This date structure provides a parsing result. You will be able to tell from it how the date string was parsed(, or why the parsing was failed).

isValid(arg1[, arg2])

  • @param {Object|string} arg1 - A pre-parsed result object or a date and time string
  • @param {string|Array.<string>} [arg2] - A format string or its compiled object
  • @returns {boolean} Whether the date and time string is a valid date and time

This function takes either exactly the same parameters with the parse() or a date structure which the preparse() returns, evaluates the validity of them.

date.isValid('2015/01/02 23:14:05', 'YYYY/MM/DD HH:mm:ss'); // => true
date.isValid('29-02-2015', 'DD-MM-YYYY');                   // => false
const result = date.preparse('2015/01/02 23:14:05', 'YYYY/MM/DD HH:mm:ss');
date.isValid(result);   // => true

transform(dateString, arg1, arg2[, utc])

  • @param {string} dateString - A date and time string
  • @param {string|Array.<string>} arg1 - A format string or its compiled object before transformation
  • @param {string|Array.<string>} arg2 - A format string or its compiled object after transformation
  • @param {boolean} [utc] - Output as UTC
  • @returns {string} A formatted string

This function transforms the format of a date string. The 2nd parameter, arg1, is the format string of it. Available token list is equal to the parse()'s. The 3rd parameter, arg2, is the transformed format string. Available token list is equal to the format()'s.

// 3/8/2020 => 8/3/2020
date.transform('3/8/2020', 'D/M/YYYY', 'M/D/YYYY');

// 13:05 => 01:05 PM
date.transform('13:05', 'HH:mm', 'hh:mm A');

addYears(dateObj, years[, utc])

  • @param {Date} dateObj - A Date object
  • @param {number} years - Number of years to add
  • @param {boolean} [utc] - Calculates as UTC Added in: v3.0.0
  • @returns {Date} The Date object after adding the value

Adds years to the date object.

const now = new Date();
const next_year = date.addYears(now, 1);

Exceptional behavior of the calculation for the last day of the month:

const now = new Date(Date.UTC(2020, 1, 29));                // => Feb 29 2020
const next_year = date.addYears(now, 1, true);              // => Feb 28 2021
const next_next_year = date.addYears(next_year, 1, true);   // => Feb 28 2022

addMonths(dateObj, months[, utc])

  • @param {Date} dateObj - A Date object
  • @param {number} months - Number of months to add
  • @param {boolean} [utc] - Calculates as UTC Added in: v3.0.0
  • @returns {Date} The Date object after adding the value

Adds months to the date object.

const now = new Date();
const next_month = date.addMonths(now, 1);

Exceptional behavior of the calculation for the last day of the month:

const now = new Date(Date.UTC(2023, 0, 31));                    // => Jan 31 2023
const next_month = date.addMonths(now, 1, true);                // => Feb 28 2023
const next_next_month = date.addMonths(next_month, 1, true);    // => Mar 28 2023

addDays(dateObj, days[, utc])

  • @param {Date} dateObj - A Date object
  • @param {number} days - Number of days to add
  • @param {boolean} [utc] - Calculates as UTC Added in: v3.0.0
  • @returns {Date} The Date object after adding the value
const now = new Date();
const yesterday = date.addDays(now, -1);

addHours(dateObj, hours[, utc])

  • @param {Date} dateObj - A Date object
  • @param {number} hours - Number of hours to add
  • @param {boolean} [utc] - Calculates as UTC Added in: v3.0.0
  • @returns {Date} The Date object after adding the value
const now = new Date();
const an_hour_ago = date.addHours(now, -1);

addMinutes(dateObj, minutes[, utc])

  • @param {Date} dateObj - A Date object
  • @param {number} minutes - Number of minutes to add
  • @param {boolean} [utc] - Calculates as UTC Added in: v3.0.0
  • @returns {Date} The Date object after adding the value
const now = new Date();
const two_minutes_later = date.addMinutes(now, 2);

addSeconds(dateObj, seconds[, utc])

  • @param {Date} dateObj - A Date object
  • @param {number} seconds - Number of seconds to add
  • @param {boolean} [utc] - Calculates as UTC Added in: v3.0.0
  • @returns {Date} The Date object after adding the value
const now = new Date();
const three_seconds_ago = date.addSeconds(now, -3);

addMilliseconds(dateObj, milliseconds[, utc])

  • @param {Date} dateObj - A Date object
  • @param {number} milliseconds - Number of milliseconds to add
  • @param {boolean} [utc] - Calculates as UTC Added in: v3.0.0
  • @returns {Date} The Date object after adding the value
const now = new Date();
const a_millisecond_later = date.addMilliseconds(now, 1);

subtract(date1, date2)

  • @param {Date} date1 - A Date object
  • @param {Date} date2 - A Date object
  • @returns {Object} The result object of subtracting date2 from date1
const today = new Date(2015, 0, 2);
const yesterday = new Date(2015, 0, 1);

date.subtract(today, yesterday).toDays();           // => 1 = today - yesterday
date.subtract(today, yesterday).toHours();          // => 24
date.subtract(today, yesterday).toMinutes();        // => 1440
date.subtract(today, yesterday).toSeconds();        // => 86400
date.subtract(today, yesterday).toMilliseconds();   // => 86400000

isLeapYear(y)

  • @param {number} y - A year to check
  • @returns {boolean} Whether the year is a leap year
date.isLeapYear(2015);  // => false
date.isLeapYear(2012);  // => true

isSameDay(date1, date2)

  • @param {Date} date1 - A Date object
  • @param {Date} date2 - A Date object
  • @returns {boolean} Whether the two dates are the same day (time is ignored)
const date1 = new Date(2017, 0, 2, 0);          // Jan 2 2017 00:00:00
const date2 = new Date(2017, 0, 2, 23, 59);     // Jan 2 2017 23:59:00
const date3 = new Date(2017, 0, 1, 23, 59);     // Jan 1 2017 23:59:00
date.isSameDay(date1, date2);   // => true
date.isSameDay(date1, date3);   // => false

locale([locale])

  • @param {Function|string} [locale] - A locale installer or language code
  • @returns {string} The current language code

It returns the current language code if called without any parameters.

date.locale();  // => "en"

To switch to any other language, call it with a locale installer or a language code.

import es from 'date-and-time/locale/es';

date.locale(es);  // Switch to Spanish

See LOCALE.md for details.

extend(extension)

  • @param {Object} extension - An extension object
  • @returns {void}

It extends this library. See EXTEND.md for details.

plugin(plugin)

  • @param {Function|string} plugin - A plugin installer or plugin name
  • @returns {void}

Plugin is a named extension object. By installing predefined plugins, you can easily extend this library. See PLUGINS.md for details.

Browser Support

Chrome, Firefox, Safari, Edge, and Internet Explorer 6+.

License

MIT

date-and-time's People

Contributors

angelortiz1 avatar dependabot[bot] avatar dominiso avatar id0sch avatar knowledgecode avatar lilnoes avatar oliverbock avatar theoludwig avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

date-and-time's Issues

Sudden invalid date

Hey! We had a flawlessly working system and our "working" code suddenly starts giving us Invalid Date outputs
I have tried code from months back and give the same error

    const date = interaction.options.getString("event-date");
    console.log(date);
    const pattern = datetime.compile("D-M-YYYY h:m A");
    let parsedDate = datetime.parseTZ(date, pattern, "Asia/Kolkata");
13-2-2023 9:45 PM
Invalid Date

System Info

NODE - v18.13.0
Linux localhost.localdomain 5.15.85-gentoo-dist #1 SMP Thu Dec 22 12:11:58 -00 2022 x86_64 AMD A8-7410 APU with AMD Radeon R5 Graphics AuthenticAMD GNU/Linux

Changing locale not possible

Hey there,

I am not able to change the locale to 'de' with version 1.0.0.

import DateTime from 'date-and-time';

DateTime.locale('de');
console.log(DateTime.locale()); // => still "en"

const {format} = DateTime;
{format(new Date(), 'ddd DD. MMM YYYY')} // instead of "Di" it says "Thu"

Can you reproduce this?

Parsing ISO 8601 Dates

Is there any way how to correctly parse ISO 8601 date-time string?

This formatter 'YYYY-MM-DDTHH:mm:ss[Z]' is working fine for it but it also works if the last character is for example 'K'. Is there any solution how to make 'Z' required?

Example:

import * as date from 'date-and-time'
import 'date-and-time/plugin/day-of-week'

date.plugin('day-of-week')

const formatter = 'YYYY-MM-DDTHH:mm:ss[Z]'
const dateTime = '1994-11-05T13:15:30Z'
const dateTime2 = '1994-11-05T13:15:30K'

date.parse(dateTime, formatter, true) // Valid Date
date.parse(dateTime2, formatter, true) // Valid Date - should be Invalid tho

Can we substract year?

In your example about substract date, it's just return days or hours or seconds, but not year
image
Can we substract date and return year?

ESM version exposed to environments that don't support ESM (e.g. jest 28)

Description

The package.json exports field declares that the browser will always get the ESM version of the library.

Jest v28 with jsdom will honour exports, but does not babelize files in node_modules. Therefore it will crash if you import this library.

  "exports": {
    ".": {
      "browser": "./esm/date-and-time.es.js",
      "import": "./esm/date-and-time.mjs",
      "require": "./date-and-time.js"
    },
  }

How to reproduce

Run this script:

# install jest and uuid
yarn add jest jest-environment-jsdom date-and-time

# create test scenario
cat << TESTFILE > ./tests.spec.js
test("should import date-and-time without crashing", () => require("date-and-time"));
TESTFILE

yarn jest --env jsdom

Expected behavior

non-nodejs CJS code that imports uuid should receive the CJS version of the library.

Swedish locale

I have used the danish locale file to make a swedish one.
Here it is:

(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, (global.date = global.date || {}, global.date.locale = global.date
.locale || {}, global.date.locale.sv = factory()));
})(this, (function () { 'use strict';

/**
 * @preserve date-and-time.js locale configuration
 * @preserve Swedish (SV)
 * @preserve It is using moment.js locale configuration as a reference.
 */

var sv = function (date) {
    var code = 'sv';

    date.locale(code, {
        res: {
            MMMM: ['januari', 'februari', 'mars', 'april', 'maj', 'juni', 'juli', 'augusti', 'september', 'oktober', 'november', 'december'],
            MMM: ['jan', 'feb', 'mar', 'apr', 'maj', 'jun', 'jul', 'aug', 'sep', 'okt', 'nov', 'dec'],
            dddd: ['söndag', 'måndag', 'tisdag', 'onsdag', 'torsdag', 'fredag', 'lördag'],
            ddd: ['sön', 'mån', 'tis', 'ons', 'tor', 'fre', 'lör'],
            dd: ['sö', 'må', 'ti', 'on', 'to', 'fr', 'lö']
        }
    });
    return code;
};

return sv;

}));

AM after 12:00

Running the following:

date.format(date.parse('12:40', 'hh:mm'), 'hh:mm A')

the result is: 12:40 "am" instead of "pm".

EDIT: my mistake, it should be:

date.parse('12:40', 'HH:mm')

Safari problem

I have issue with safari browser! he is give me NaN from JSON Api format liker "2018-04-01 00:00:00".
This package can solve my problem? I did not try to use yet this package.
May be someone had this problem before?

Missing D letter

There was a missing 'D' in your time parser for some reason, just wanted to point it ou to you.

Ru locale problems

Hello! Please, change days of week in ru locale:
"dddd: ['Воскресенье', 'Понедельник', 'Вторник', 'Среда', 'Четверг', 'Пятница', 'Суббота']"
Thank you very much!

Format(tz) fails when timezone string is greater than +1200 (i.e +1300)

When providing a time string of 2022-02-22T14:00:00.000+1200 and a time format of YYYY-MM-DD[T]HH:mm:ss.SSSZ, formatTZ will succeed.

When providing a time string of 2022-02-22T14:00:00.000+1300 with the same time format, formatTZ will fail with RangeError: Invalid time value.

This might be due to NZDT (New Zealand Daylight Time) being forgotten and the range of "Z" only goes up to 12

formatTZ returns wrong locale

import date from "date-and-time";
import timezone from "date-and-time/plugin/timezone";
date.plugin(timezone);
import de from "date-and-time/locale/de";
date.locale(de);

const now = new Date();
this.CalendarOptions.weekday = date.format(now, "dddd"); // returns 'Donnerstag'
this.CalendarOptions.weekdayTZ = date.formatTZ(now, "dddd", "Europe/Berlin"); // returns 'Thursday'

When using timezones, I cannot get the german locals weekdays from date.formatTZ.
Is that a bug, or am I missing something?

thanks!

Format formats incorrect month

code used:

const date = require('date-and-time'),
	now = new Date(2023, 02, 29);
const eNow = date.format(now, 'YYYY-MM-DD'); // normal date
console.log(eNow);

log:

2023-03-29

Error in detection of bogus input formats

Hi!

I'm seeing some odd behavior with isValid() and parse(), probably associated with the regEx for the input format:

console.log(Dates.isValid('31/12/1985', 'humbug'));  // false 👍
console.log(Dates.isValid('31/12/1985', 'foo'));    // true 😞
console.log(Dates.isValid('31/12/1985', 'bar'));      // true 😞
console.log(Dates.isValid('31/12/1985', 'boom'));     // true 😞
console.log(Dates.isValid('31/12/1985', 'spazz'));    // true 😞

console.log(Dates.parse('31/12/1985', 'spazz')); // Thu Jan 01 1970 00:00:31 GMT-0500 (EST)

GHSL-2020-349: seeking security contact for your project

The GitHub Security Lab reported a potential security vulnerability (GHSL-2020-349) in your project (knowledgecode/date-and-time). We are approaching 90 days since our initial report and as per our coordinated disclosure policy, we intend to publish a public advisory detailing this issue. If you wish to discuss or further coordinate a response to this issue with the GitHub Security Lab, please contact us at [email protected] within the next 7 days in reference to GHSL-2020-349 and we would love to help you resolve these issues. If not, feel free to close this issue and we will proceed with advisory publication on expiration.

Case insensitive parse

parse function is case sensitive.
So this example won't work
date.parse('29 jul 1990', 'DD MMM YYYY');

But this one, will work
date.parse('29 Jul 1990', 'DD MMM YYYY');

Shouldn't it be case insensitive? Seems like a simple feature

Ver 0.6.2 request error dump

2018-07-09T20:52:34.185664+00:00 app[web.1]: /app/node_modules/date-and-time/date-and-time.js:231

2018-07-09T20:52:34.185668+00:00 app[web.1]: return new Date(dateObj.getTime() + milliseconds);

2018-07-09T20:52:34.185670+00:00 app[web.1]: ^

2018-07-09T20:52:34.185671+00:00 app[web.1]:

2018-07-09T20:52:34.185672+00:00 app[web.1]: TypeError: dateObj.getTime is not a function

2018-07-09T20:52:34.185674+00:00 app[web.1]: at Object.date.addMilliseconds (/app/node_modules/date-and-time/date-and-time.js:231:33)

2018-07-09T20:52:34.185675+00:00 app[web.1]: at Object.date.addMinutes (/app/node_modules/date-and-time/date-and-time.js:211:21)

2018-07-09T20:52:34.185676+00:00 app[web.1]: at Object.date.format (/app/node_modules/date-and-time/date-and-time.js:84:22)

Parsing & Performance

Hi,

I've noticed that parsing requires quite a bit of computation, with regex's and parsing; based on my own performance benchmarking of my code; I can see the parse call contributes about 35% of my Javascript code's running time.

I was wondering if you could please see what you can do to better do precomputation. For example, for parsing, the string format is usually known upfront; and can be "precomputed" into the data structures you would need; so you can do your translations later.

There may be other ideas, but this is one that comes to mind.

Thanks,

Ronak

Add transformTZ

If you already have a date string, but in the wrong time zone, you have to transform, then parse and then format it back in order to get it to the correct timezone. It would be nice if there were a transformTZ option.

Though I understand the use case is rather limited and probably not necessary in most cases. My use case is the API I'm working with gives me a random timezone each time I call it. So I know the format before I even know the time. 🙃

It would just save me an extra parse and format call. If there really isn't a need for it, don't worry about it.

export default issue

I'm used to import your (nice) lib like this:

import DateTime from 'date-and-time'

However, after I've updated to 0.11. I get this warning:

export 'default' (imported as 'DateTime') was not found in 'date-and-time'

Did you remove this intentionally or accidentally?

Conflicts can occur when importing multiple plugins or changing locales

Due to the specification that each plugin and locale can change the default behavior, importing multiple plugins or changing locales can cause unexpected behavior. To resolve this issue, we would have to accept changes to the plugin and locale specifications.

For instance:

  • Locales must not add new tokens to the default locale (English).
  • Plugins must not change the behavior of the default tokens.
  • Plugins should not be affected by locale changes.
  • The behavior changed by plugins should be retained even if the locale changed.

With these changes, some of the existing plugins will be modified or deprecated.

All upper case long Month name

This may be more of a question, but is there a way to parse the following?:

DECEMBER 10TH 2020

I tried MMMM D[TH] YYYY but I would get Invalid Date.

If I transformed the input string to December 10TH 2020 it would successfully parse the date.

Any guidance would be greatly appreciated!

If this currently is not supported, I would also think the variations that would be great to support would be any casing of:

  1. Month name (long and short)
  2. Day of week (long, short, and very short)

Thanks again and great work!

Unable to parse datetime strings with six millisecond digits

Hi

I'm having some trouble parsing strings with six millisecond digits using .parse().

The strings look like this: 2019-11-13T10:22:16.866122Z 2019-11-11T10:23:23.392706Z

I've tried these formats:

"YYYY-MM-DDTHH:mm:ss.SSSSSSZ" (not listed as a supported format)
"YYYY-MM-DDTHH:mm:ss.SSSZ" (listed as a supported format for 3 ms digits)
"YYYY-MM-DDTHH:mm:ss"

If the string is shortened to 2019-11-13T10:22:16Z, the format YYYY-MM-DDTHH:mm:ssZ works just fine.

Also, if the string is shortened to just 3 millisecond digits 2019-11-13T10:22:16.866Z, the format YYYY-MM-DDTHH:mm:ss.SSSZ works just fine.

To play with it you can use https://npm.runkit.com/date-and-time
and paste in this:

var dateAndTime = require("date-and-time")

var timestamp = "2019-11-13T10:22:16.866122Z";
var res = dateAndTime.parse(timestamp, "YYYY-MM-DDTHH:mm:ss.SSSSSSZ");
console.log(res);

More flexibility for AM/PM formats

Hello!

I think the regEx for AM/PM in times could use some work as well:

console.log(dateAndTime.parse('11:23 p.m.', 'hh:mm A')) // Thu Jan 01 1970 23:23:00 GMT-0500 (EST)
console.log(dateAndTime.parse('11:23 P.M.', 'hh:mm A'))   // NaN
console.log(dateAndTime.parse('11:23 PM', 'hh:mm A'))   // NaN
console.log(dateAndTime.parse('11:23 pm', 'hh:mm A'))   // NaN

I may submit a PR when I have a second, but just wanted to document it in the meantime. Thank you!

YYYY Year parsing bug

Hi,

Parsing strings "1/1/1", "1/1/01", "1/1/001" with D/M/YYYY format yields 1 Jan 2001 date. That is correct.

However, parsing string "1/1/0001" with D/M/YYYY format should yield 1 January 1 year, however it yields 1 Jan 2001.

So effectively, this is not possible to enter close to Christmas dates :)

Consider adding native support for Typescript types

Instead of letting a non-synchronized package (@types/date-and-time) do the job, why don't you just add a "types" definition directly to this package?

It would be far better, it is more comfortable for whom uses the types and, generally, very more reliable.

The @types/date-and-time for instance have not been not updated since two years ago and do not support the plugins

image

Even if your code is not Typescript code, it is extremely easy to create the types declaration for javascript code https://www.typescriptlang.org/docs/handbook/declaration-files/dts-from-js.html and could even be automatized with a github action!

transformTZ doesn't work properly when original time zone is +0000

transformTZ doesn't handle timezones with UTC.

Steps to reproduce:

const challongeTimeFormat = date.compile('YYYY-MM-DD[T]HH:mm:ss.SSSZ');
const desiredTimeFormat = date.compile('MMM D h:mmA [GMT]Z');


		let initialTimeString = reformatChallongeTime(element.tournament['start_at']);
		let finalTime;
		try {
		finalTime = date.transformTZ(initialTimeString['time'],challongeTimeFormat,desiredTimeFormat,'America/New_York',initialTimeString['UTC']);
		}
		catch (e){
			fs.writeFileSync('G:/Coding Projects/stdout/timeshit.txt','Initial Time String: ' +JSON.stringify(element.tournament['start_at'])+'\nPost Colon Removal: '+JSON.stringify(initialTimeString)+'\nConverted Time Zone: '+JSON.stringify(convertedTimezone)+'\n',{ flag: 'a' });
			throw e;
		}

initialTimeString values:
{ time: '2022-03-06T16:00:00.000-0600', UTC: false }
{ time: '2022-03-06T23:00:00.000+0100', UTC: false }
{ time: '2022-03-06T22:00:00.000+0000', UTC: true }

Expected output:
"Mar 6 5:00PM GMT-0500" for all

Actual output:
-0600 and +0100 output: "Mar 6 5:00PM GMT-0500"

+0000 output: "Mar 6 11:00PM GMT-0500"

I remember having to set the UTC to true when I was using parse and format in order to state explicitly that the timezone that was being used was +0000. Don't know why it was necessary but that worked. It seems the transformTZ has the same issue but doesn't take the optional UTC variable. So maybe two birds with one stone here.

Cannot find module './locale/it'

Hello!
Please, help me. I include import date from "date-and-time" within my module which working for frontend (client side).
Without using date.locale('it'); that's all working. But when I added date.locale('it'); there was an error: Cannot find module './locale/it'.

Maybe that don't related with your module, however I hope you can help me.

error result while use addDays

for(let i=0; i<7; i++) {
console.log(date.format(date.addDays(fromDate,-7*i),'YYYY-MM-DD'));
}

output:

2017-04-07
2017-03-31
2017-03-24
2017-03-17
2017-03-09 -----------error from here
2017-03-02
2017-02-23

Force a 4-digit YYYY

I validate the user input with date.parse(input, 'DD/MM/YYYY HH:mm').

To my surprise, the following inputs are valid:

  • 11/11/1 11:11
  • 11/11/12 11:11
  • 11/11/123 11:11

I would expect only the following one to pass:

  • 11/11/1234 11:11

Is there a format token available to force a 4-digit year?

Get current date in nodeJS?

Hi,

Docs say to get current date use new Date(). That's only available in the browser, I'd like to get the current date via the server. Is there a method to achieve this?

addMonth to 2022-03-01 does not add full month

consider following code:

const date_and_time = require('date-and-time')
const d = new Date(Date.UTC(2022,2,1)) // 1st of March
const nextMonth = date_and_time.addMonths(d, 1) // nextMonth should be 1st of April
console.log(nextMonth)

yields
2022-03-31T23:00:00.000Z

tested on Node v18, MacOS, German locale.

Escaping of non-date text in a date format

I have a date in Spanish given in the following format: 26 de junio de 2015.
I would like to have ability to escape non-date symbols which can be confused with date tokens.
For example, how it's done in moment.js: D [de] MMMM [de] YYYY.

TypeError: dateObj.getTimezoneOffset is not a function

I tried to run
date.format(new Date().toLocaleString("en-US", { timeZone: "Asia/Kuala_Lumpur" }), 'DD-MM-YYYY hh:mma', true);

However it returns:

d = date.addMinutes(dateObj, utc ? dateObj.getTimezoneOffset() : 0),
^

TypeError: dateObj.getTimezoneOffset is not a function at Object.date.format (/Users/JKnet/erider-function-source/node_modules/date-and-time/date-and-time.js:156:56) at [stdin]:8:6 at Script.runInThisContext (vm.js:132:18) at Object.runInThisContext (vm.js:309:38) at internal/process/execution.js:77:19 at [stdin]-wrapper:6:22 at evalScript (internal/process/execution.js:76:60) at internal/main/eval_stdin.js:29:5 at Socket.<anonymous> (internal/process/execution.js:198:5) at Socket.emit (events.js:326:22)

Does it mean I cannot give a timezone aware object?

Invalid Date error trying to parse a string containing AM or PM

const date = require('date-and-time');
let d = date.parse('Dec, 25 2019 at 3:51 AM', 'MMM, D YYYY at h:m A');
//same error with following line also
//let d = date.parse('Dec, 25 2019 at 3:51 AM', 'MMM, D YYYY at h:m AA (*)');
console.log(d);

output:
Invalid Date

parse() doesn't support timezone offset?

This returns NaN right now:

dateAndTime.parse("2019-02-21T07:48:28-0800", "YYYY-MM-DDThh:mm:ssZ");

I'm working around it using this undocumented behavior, which is good enough for me at this point (the formatter's going to remove all the spaces, but in my code there are enough to make it pass):

dateAndTime.parse("2019-02-21T07:48:28-0800", "YYYY-MM-DDThh:mm:ss ");

But I'm wondering if I've misunderstood something. Is that first line supposed to work?

Support clock change for .transform()

date-and-time v. 2.3.1

I'm based in the Netherlands and we have clock change for winter and summer time.

Winter time: UTC+1
Summer time: UTC+2

Source: https://www.timeanddate.com/time/zone/netherlands/amsterdam

Right now when I'm trying to .transform() time string, the library wrongly assumes that it's winter time.

// Now it is 11:45 May 25th in the Netherlands.

const timeStr = "11:45+02:00";
const timeStrTransformed = date.transform(timeStr, "HH:mmZZ", "HH:mm");

console.log(timeStrTransformed); // 10:45
// but expected 11:45 instead of 10:45 

When I use .format() with date object, it assumes everything correctly.

// Now it is 11:45 May 25th in the Netherlands.

const now = new Date();

const timeStr01 = date.format(now, "HH:mmZZ");
const timeStr02 = date.format(now, "HH:mm");
const timeStr03 = date.transform(timeStr01, "HH:mmZZ", "HH:mm")

console.log(`timeStr01: ${timeStr01}`); // "timeStr01: 11:45+02:00"
console.log(`timeStr02: ${timeStr02}`); // "timeStr02: 11:45"
console.log(`timeStr03: ${timeStr03}`); // "timeStr03: 10:45"
// Expected timeStr03 to be 11:45 as well

I really like this library and would appreciate clock change support for .transform()

More explanatory for NaN response

Hello,

In the below examples, both of these dates return with NaN, but their reasons are different. Could you please add more clarity for return values?

1) date.parse('Jam 1 2017', 'MMM D YYYY');                     // => NaN
2) date.parse('Feb 29 2017', 'MMM D YYYY');                    // => NaN 

  1. No such month name
  2. Not in the right range for month

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.