
Research
/Security News
Weaponizing Discord for Command and Control Across npm, PyPI, and RubyGems.org
Socket researchers uncover how threat actors weaponize Discord across the npm, PyPI, and RubyGems ecosystems to exfiltrate sensitive data.
@onereach/time-interpreter
Advanced tools
Convert dates, durations and time to canonical format (dates -> ISO 8601, durations -> milliseconds).
Parse a human readable time string into a canonical format:
date -> ISO8601: 2020-11-11T00:00:00+00:00, 2020-11-11T00:00:00Z,
datetime -> ISO8601: 2020-11-11T09:36:27+00:00, 2020-11-11T09:36:27Z,
time -> HH:mm:ssZ,
duration -> milliseconds
timezone -> time offset - +00:00
const timeInterpreter = require("@onereach/time-interpreter");
const converter = new timeInterpreter();
// will be deprecated
converter.formatDatetime(
"date string",
false /*ignore time*/,
"input timezone",
"output timezone"
); // optional: set timezones by name or time offset, default `Z`
// Input timezone is a default (assumed) timezone and it will be applied if the input date/time doesn't include timezone data
Since v1.0.21
:
converter.getISODatetime({
value: "date string",
ignoreTime: false /*ignore time*/,
inputTimezone: "input timezone",
outputTimezone: "output timezone",
assumedYear: 2022
});
let result = converter.formatDatetime("1995-02-04 10:00", false, "Europe/Kiev");
/* {
"date": "1995-02-04T10:00:00+02:00", // ISO8601 string
"timezoneOffset": "+02:00" // time offset
} */
converter.formatDatetime("12-12-2020 10:20+06:00", false, "Europe/Kiev");
/* {
"date": "12-12-2020T10:20:00+06:00", // ISO8601 string
"timezoneOffset": "+06:00" // time offset
} */
converter.formatDatetime("1995-02-04 10:00", false, "Europe/Kiev", "-03:00");
/* {
"date": "1995-02-04T05:00:00-03:00",
"timezoneOffset": "-03:00"
} */
converter.formatDatetime("1995-02-04 10:00", true).date; // "1995-02-04T10:00:00Z"
converter.formatDatetime("28OCT1990").date; // "1990-10-28T00:00:00Z"
// ISO8601 duration
converter.formatDatetime("PT444037H35M28S").date; // "2020-08-27T13:35:28Z"
converter.formatDatetime(
{
year: 2010,
month: 3,
day: 5,
hour: 15,
minute: 10,
second: 3,
millisecond: 123,
},
false,
"UTC"
); // "2010-04-05T15:10:03+00:00"
// Unix time
converter.formatDatetime(1318874398); // "2011-10-17T17:59:58.000Z"
converter.formatDatetime(1560211200000); // "2019-06-11T00:00:00.000Z"
// Particular format: time span of 3 years 6 months 4 days 12 hours 30 minutes and 17 seconds, starting from August 9, 2005 18 hours 31 minutes 42 seconds
converter.formatDatetime(
"2005-08-09T18:31:42/P3Y6M4DT12H30M17S",
false,
"+02:00"
);
/* {
date: '2009-02-12T07:01:59+02:00',
timezoneOffset: '+02:00',
zoneName: '',
offsetNum: 2
} */
// Output additional timezone data 1.0.8+
converter.formatDatetime("1995-02-04 10:00", false, "Europe/Kiev");
/* {
"date": "1995-02-04T10:00:00+02:00",
"timezoneOffset": "+02:00",
"zoneName": "Europe/Kiev",
"offsetNum": 2
} */
// Specify default year. It is used if the original date does not include year (default year current). 1.0.8+
converter.formatDatetime("11 August", true, "", "Europe/Kiev", 1999).date; // "1999-08-11"
converter.formatDatetime("September 23rd", false, "GMT+0", "").date; // "2021-09-23T00:00:00+00:00"
converter.formatDatetime(
"sixteenth December",
false,
"Europe/Kiev",
"GMT+0",
2020
).date; // "2020-12-15T22:00:00+00:00"
let timeOffset = converter.formatTimezone("+1"); // "+01:00"
converter.formatTimezone("America/Denver"); // "-07:00" (or "-06:00")
converter.formatTimezone("-0700"); // "-07:00"
converter.formatTimezone("-180"); // "-03:00"
// Specify 'true' as second param to output timezone object 1.0.8+
converter.formatTimezone("America/Denver", true);
/* {
"name": "America/Denver",
"offsetNum": -7,
"offsetText": "-07:00"
} */
// Invalid value 1.0.8+
converter.formatTimezone("30"); // null
converter.formatTimezone("Ukraine"); // null
If the time zone name is used to indicate the input timezone, and this zone has winter and summer time, then the time offset for the input time value is determined to rely on the current date.
converter.formatTime("time string", "input timezone"); // optional: set timezones by name or time offset, default `Z`
let time = converter.formatTime("12:30:10 am", "Europe/Kiev");
/* {
"time": "00:30:10+02:00",
"timezoneOffset": "+02:00"
} */
converter.formatTime("2020-11-06T06:30:00Z", "Europe/Kiev");
/* {
"time": "06:30:00Z",
"timezoneOffset": "+00:00"
} */
converter.formatTime({ seconds: 2, minutes: 2, hours: 2 }, "Europe/Kiev");
/* {
"time": "02:02:02+02:00",
"timezoneOffset": "+02:00"
} */
converter.formatTime("12-30-10").time; // "12:30:10"
converter.formatTime("183142").time; // "18:31:42Z"
converter.formatTime("283142").time; // as unix time in ms
// "00:04:43Z"
// Output additional timezone data 1.0.8+
converter.formatTime("12-30-10");
/* {
"time": '12:30:10Z',
"timezoneOffset": 'Z',
"zoneName": '',
"offsetNum": 0
} */
let duration = converter.formatDuration("10.2019"); // number of days in October
// 2678400000
converter.formatDuration("2w 1d5h"); // 1314000000
// ISO8601 duration
converter.formatDuration("P2Y2M16DT2H2M2S"); // 69732122000
// Invalid
converter.formatDuration("month"); // NaN
// v1.0.19
converter.formatDuration("2d"); // {asMilliseconds: 172800000, asObject: {days: 2}, humanized: "2 days"}
If you don't know what type of an input value: date, date/time or time, you can use converter.parse(value, input timezone, output timezone, input year, input date)
. Input year (YYYY) is a default year and it will be applied if the input date/time doesn't include year. Input date (in format YYYY-MM-DD
) will be applied if the input value type of time. Default year - current year, default date - null
, default input timezone - GMT+0
.
if input date is not indicated and the defined type of value is time, then the output timezone is ignored. If the defined type of value is date, then the time is set to 00:00:00
in input timezone (default GMT+0
).
If the time zone name is used to indicate the input timezone, and this zone has winter and summer time, and if value is time, then the time offset is determined to rely on the current date (unless otherwise specified).
Method tries to defind first if the value is a date. If input value is a sequence of numbers (for example, 234567
or "6453673"
) it will be parsed as unix time in seconds. If the value looks like these: "12-30-00"
, "20 45 50"
, "16.50.00"
, - the method will try to parse it as a date (MM-DD-YY, YY-MM-DD etc.) and if it's invalid date the value will be parsed as a time (hh mm ss). Values where separator is "/"
are parsed only as a date. Values where separator is ":"
are parsed only as a time.
// Sinse v1.0.21
converter.getParsed({
value: "time/date/datetime",
inputTimezone: "input timezone",
outputTimezone: "output zone",
assumedYear: "it is used if the original date does not include year (default year current)",
assumedDate: "it is used if the input value is time (default undefined)"
});
// will be deprecated
let parsed = converter.parse("Feb-1st-2021, 12:30:00am, America/Los_Angeles, Monday");
/* {
"time": {
"hourMinute12": "12:30",
"hourMinute24": "00:30",
"hour12": 12,
"hour24": 0,
"amPm": "am",
"minute": 30
},
"duration": 1612168200000, // milliseconds
"iso": "2021-02-01T00:30:00-08:00",
"date": {
"dayOfWeek": "Monday",
"isWeekend": false,
"day": 1,
"month": 2,
"monthName": "February",
"year": 2021
},
"timezone": {
"name": "America/Los_Angeles",
"offsetNum": -8,
"offsetText": "-08:00"
}
}*/
converter.parse("12.30.00Z+0200 may-twenty-second");
/*{
"time": {
"hourMinute12": "12:30",
"hourMinute24": "12:30",
"hour12": 12,
"hour24": 12,
"amPm": "pm",
"minute": 30
},
"duration": 1621679400000,
"iso": "2021-05-22T12:30:00+02:00",
"date": {
"dayOfWeek": "Saturday",
"isWeekend": true,
"day": 22,
"month": 5,
"monthName": "May",
"year": 2021
},
"timezone": {
"name": "",
"offsetNum": 2,
"offsetText": "+02:00"
}
}*/
converter.parse("Feb-1st 12:30");
/*{
"time": {
"hourMinute12": "12:30",
"hourMinute24": "12:30",
"hour12": 12,
"hour24": 12,
"amPm": "pm",
"minute": 30
},
"duration": 1612182600000, // milliseconds
"iso": "2021-02-01T12:30:00+00:00",
"date": {
"dayOfWeek": "Monday",
"isWeekend": false,
"day": 1,
"month": 2,
"monthName": "February",
"year": 2021
},
"timezone": {
"name": "GMT+0",
"offsetNum": 0,
"offsetText": "+00:00"
}
}*/
converter.parse("twenty-one/Apr 10 30 00pm", "GMT+0", "Europe/Kiev", 2004, "2020-22-10");
/*{
"time": {
"hourMinute12": "01:30",
"hourMinute24": "01:30",
"hour12": 1,
"hour24": 1,
"amPm": "am",
"minute": 30
},
"duration": 1082586600000, // milliseconds
"iso": "2004-04-22T01:30:00+03:00",
"date": {
"dayOfWeek": "Thursday",
"isWeekend": false,
"day": 22,
"month": 4,
"monthName": "April",
"year": 2004
},
"timezone": {
"name": "Europe/Kiev",
"offsetNum": 3,
"offsetText": "+03:00"
}
}*/
converter.parse("093042 PM");
/*{
"time": {
"hourMinute12": "09:30",
"hourMinute24": "21:30",
"hour12": 9,
"hour24": 21,
"amPm": "pm",
"minute": 30
},
"duration": 77442000, // milliseconds
"iso": "21:30:42+00:00",
"date": null,
"timezone": {
"name": "GMT+0",
"offsetNum": 0,
"offsetText": "+00:00"
}
}*/
converter.parse("093042 PM", "Europe/Kiev", "GMT+0", 2004, "2020-10-22");
/*{
"time": {
"hourMinute12": "06:30",
"hourMinute24": "18:30",
"hour12": 6,
"hour24": 18,
"amPm": "pm",
"minute": 30
},
"duration": 1603391442000, // milliseconds
"iso": "2020-10-22T18:30:42+00:00",
"date": {
"dayOfWeek": "Thursday",
"isWeekend": false,
"day": 22,
"month": 10,
"monthName": "October",
"year": 2020
},
"timezone": {
"name": "GMT+0",
"offsetNum": 0,
"offsetText": "+00:00"
}
}*/
converter.parse("093042 PM", "America/Denver");
/*{
"time": {
"hourMinute12": "09:30",
"hourMinute24": "21:30",
"hour12": 9,
"hour24": 21,
"amPm": "pm",
"minute": 30
},
"duration": 77442000, // milliseconds
"iso": "21:30:42-07:00",
"date": null,
"timezone": {
"name": "America/Denver",
"offsetNum": -7,
"offsetText": "-07:00"
}
}*/
converter.parse(34567890, "America/Denver");
/*{
"time": {
"hourMinute12": "02:11",
"hourMinute24": "02:11",
"hour12": 2,
"hour24": 2,
"amPm": "am",
"minute": 11
},
"duration": 34593090000,
"iso": "1971-02-05T02:11:30-07:00",
"date": {
"dayOfWeek": "Friday",
"isWeekend": false,
"day": 5,
"month": 2,
"monthName": "February",
"year": 1971
},
"timezone": {
"name": "America/Denver",
"offsetNum": -7,
"offsetText": "-07:00"
}
}*/
converter.parse({ days: 2, months: "2", years: "1999" }, "America/Denver");
/*{
"time": {
hourMinute12: '12:00',
hourMinute24: '00:00',
hour12: 12,
hour24: 0,
amPm: 'am',
minute: 0
},
"duration": 63087811200000,
"iso": "1999-03-02",
"date": {
"dayOfWeek": "Tuesday",
"isWeekend": false,
"day": 2,
"month": 3,
"monthName": "March",
"year": 1999
}
}*/
converter.parse("Friday 7 MAY 2021", "America/Denver");
/*{
"time": {
hourMinute12: '12:00',
hourMinute24: '00:00',
hour12: 12,
hour24: 0,
amPm: 'am',
minute: 0
},
"duration": 1620345600000,
"iso": "2021-05-07",
"date": {
"dayOfWeek": "Friday",
"isWeekend": false,
"day": 7,
"month": 5,
"monthName": "May",
"year": 2021
}
}*/
{
day: 2,
month: '5'
},
{
day: 2,
month: '5',
year: 2020
}
All permutations, case insensitive match separated with '-', '.', '/', ' ' (space) :
'MMMM-DD-YY'
)'YY-DD-MMMM'
)'YY-MMMM-DD' -> 'DD-MMMM-YY'
)'DD-MM-YYYY' -> 'MM-DD-YYYY'
)'YYYY-MM-DD' -> 'YYYY-DD-MM'
)'MM-DD-YY' -> 'DD-MM-YY' -> 'YY-MM-DD' -> 'YY-DD-MM'
)day + month (case insensitive), without year
Invalid date:
These formats can be parsable with converter.formatDatetime()
and converter.parse()
.
Case insensitive permutations of day, month and year (separated with '-', '.', '/', ' ' (space) ):
day:
month:
year in format of 4 digits: "2021"
Examples:
Date part combinated with weekday (case insensitive), time (case insensitive) and timezone (case sensitive). If the value contains both - time offset and timezone name, at the same time, then the timezone name is preferred.
weekday:
Examples:
Can include time part (case insensitive) and timezone (case sensitive) or time offset:
Date + time or time + date (may include weekday or timezone name between these parts), where date is:
"2nd oct 2021"
"2nd oct", "first september"
and where time part is:
Examples:
Another date formats:
"20/10/06 1:30:10 PM", "20.10.06 11:30:10", "1:30:10am 20-10-06", "1:30:10+03:00 20-10-06"
"20/Apr/06 1:30:10 PM", "20.10.August 11:30:10", "1:30:10am nov-10-06", "1:30:10+03:00 20-july-06"
"7 pm", "7pm", "123000am", "123000 am", "12:30 am", "12:30am", "12:30:00 am", "12:30:00am", "123000", "12:30+0200", "12:45-03:00", "2:30:00", "12:30:00", "12:30:00.123Z", "12:30:00Z", "12:30", "12:30:00+01:00", "12:30:00Z+01:00"
Timezone from the list that moment-timezone.js provides
Examples:
Case insensitive match with separators (':', '-', '.', ' ' (space)):
5422456
(as unix time in ms)h, hours, m, minutes, s, seconds, ms, milliseconds
)hhmm
); "123000", "183142", "150000 America/Los_Angeles" (hhmmss
). If the value is invalid time in these formats (hhmmss,hhmm) it'll be parsed as unix time.If the value contains both - time offset and timezone name, at the same time, then the timezone name is preferred.
Invalid time:
Case sensitive:
{
"seconds": 2,
"minutes": 2,
"hours": 2,
"days": 2,
"weeks": 2,
"months": "2",
"years": "2"
}
Invalid duration string:
Case sensitive:
Invalid values:
moment-timezone.js - dates and timezones parsing library.
FAQs
Convert dates, durations and time to canonical format (dates -> ISO 8601, durations -> milliseconds).
The npm package @onereach/time-interpreter receives a total of 1,203 weekly downloads. As such, @onereach/time-interpreter popularity was classified as popular.
We found that @onereach/time-interpreter demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
/Security News
Socket researchers uncover how threat actors weaponize Discord across the npm, PyPI, and RubyGems ecosystems to exfiltrate sensitive data.
Security News
Socket now integrates with Bun 1.3’s Security Scanner API to block risky packages at install time and enforce your organization’s policies in local dev and CI.
Research
The Socket Threat Research Team is tracking weekly intrusions into the npm registry that follow a repeatable adversarial playbook used by North Korean state-sponsored actors.