Каков наилучший способ проанализировать время в объект даты из пользовательского ввода в Javascript?
Я работаю над виджетом формы для пользователей, чтобы ввести время суток в текстовый ввод (для приложения календаря). Используя JavaScript (мы используем jQuery FWIW), я хочу найти лучший способ проанализировать текст, который пользователь вводит в JavaScript Date()
объект, поэтому я могу легко проанализировать сравнения и другие вещи на нем.
Я пробовал parse()
метод и это немного слишком придирчивы для моих нужд. Я ожидал бы, что он сможет успешно проанализировать следующий пример ввода время (в дополнение к другим логически подобным форматам времени) как то же самое
18 ответов:
быстрое решение, которое работает на входе, который вы указали:
function parseTime( t ) { var d = new Date(); var time = t.match( /(\d+)(?::(\d\d))?\s*(p?)/ ); d.setHours( parseInt( time[1]) + (time[3] ? 12 : 0) ); d.setMinutes( parseInt( time[2]) || 0 ); return d; } var tests = [ '1:00 pm','1:00 p.m.','1:00 p','1:00pm','1:00p.m.','1:00p','1 pm', '1 p.m.','1 p','1pm','1p.m.', '1p', '13:00','13', '1a', '12', '12a', '12p', '12am', '12pm', '2400am', '2400pm', '2400', '1000', '100', '123', '2459', '2359', '2359am', '1100', '123p', '1234', '1', '9', '99', '999', '9999', '99999', '0000', '0011', '-1', 'mioaw' ]; for ( var i = 0; i < tests.length; i++ ) { console.log( tests[i].padStart( 9, ' ' ) + " = " + parseTime(tests[i]) ); }
Он должен работать и для нескольких других разновидностей (даже если используется A. M., Он все равно будет работать - например). Очевидно, что это довольно грубо, но это также довольно легкий (гораздо дешевле использовать это, чем полную библиотеку, например).
предупреждение: этот код не работает с 12:00 утра, и т. д.
все приведенные примеры не работать с 12:00 до 12:59 утра. Они также выдают ошибку, если регулярное выражение не соответствует времени. Следующее обрабатывает это:
function parseTime(timeString) { if (timeString == '') return null; var time = timeString.match(/(\d+)(:(\d\d))?\s*(p?)/i); if (time == null) return null; var hours = parseInt(time[1],10); if (hours == 12 && !time[4]) { hours = 0; } else { hours += (hours < 12 && time[4])? 12 : 0; } var d = new Date(); d.setHours(hours); d.setMinutes(parseInt(time[3],10) || 0); d.setSeconds(0, 0); return d; } var tests = [ '1:00 pm','1:00 p.m.','1:00 p','1:00pm','1:00p.m.','1:00p','1 pm', '1 p.m.','1 p','1pm','1p.m.', '1p', '13:00','13', '1a', '12', '12a', '12p', '12am', '12pm', '2400am', '2400pm', '2400', '1000', '100', '123', '2459', '2359', '2359am', '1100', '123p', '1234', '1', '9', '99', '999', '9999', '99999', '0000', '0011', '-1', 'mioaw' ]; for ( var i = 0; i < tests.length; i++ ) { console.log( tests[i].padStart( 9, ' ' ) + " = " + parseTime(tests[i]) ); }
это будет работать для строк, которые содержат время в любом месте внутри них. Таким образом," abcde12:00pmdef " будет проанализирован и возвращен в 12 часов дня. Если желаемый результат заключается в том, что он возвращает только время, когда строка содержит только время в них следующее регулярное выражение может быть используется при условии замены "time[4] "на"time[6]".
/^(\d+)(:(\d\d))?\s*((a|(p))m?)?$/i
Не беспокоить делать это самостоятельно, просто используйте datejs.
большинство решений регулярных выражений здесь выбрасывают ошибки, когда строка не может быть проанализирована, и не многие из них учитывают такие строки, как
1330
или130pm
. Несмотря на то, что эти форматы не были указаны OP, я нахожу их критичными для анализа дат, вводимых людьми.все это заставило меня думать, что использование регулярного выражения может быть не лучшим подходом для этого.
мое решение-это функция, которая не только анализирует время, но и позволяет задать формат вывода и шаг (интервал), на котором округлить минут до. Примерно в 70 строках он по-прежнему легкий и анализирует все вышеупомянутые форматы, а также без двоеточий.
function parseTime(time, format, step) { var hour, minute, stepMinute, defaultFormat = 'g:ia', pm = time.match(/p/i) !== null, num = time.replace(/[^0-9]/g, ''); // Parse for hour and minute switch(num.length) { case 4: hour = parseInt(num[0] + num[1], 10); minute = parseInt(num[2] + num[3], 10); break; case 3: hour = parseInt(num[0], 10); minute = parseInt(num[1] + num[2], 10); break; case 2: case 1: hour = parseInt(num[0] + (num[1] || ''), 10); minute = 0; break; default: return ''; } // Make sure hour is in 24 hour format if( pm === true && hour > 0 && hour < 12 ) hour += 12; // Force pm for hours between 13:00 and 23:00 if( hour >= 13 && hour <= 23 ) pm = true; // Handle step if( step ) { // Step to the nearest hour requires 60, not 0 if( step === 0 ) step = 60; // Round to nearest step stepMinute = (Math.round(minute / step) * step) % 60; // Do we need to round the hour up? if( stepMinute === 0 && minute >= 30 ) { hour++; // Do we need to switch am/pm? if( hour === 12 || hour === 24 ) pm = !pm; } minute = stepMinute; } // Keep within range if( hour <= 0 || hour >= 24 ) hour = 0; if( minute < 0 || minute > 59 ) minute = 0; // Format output return (format || defaultFormat) // 12 hour without leading 0 .replace(/g/g, hour === 0 ? '12' : 'g') .replace(/g/g, hour > 12 ? hour - 12 : hour) // 24 hour without leading 0 .replace(/G/g, hour) // 12 hour with leading 0 .replace(/h/g, hour.toString().length > 1 ? (hour > 12 ? hour - 12 : hour) : '0' + (hour > 12 ? hour - 12 : hour)) // 24 hour with leading 0 .replace(/H/g, hour.toString().length > 1 ? hour : '0' + hour) // minutes with leading zero .replace(/i/g, minute.toString().length > 1 ? minute : '0' + minute) // simulate seconds .replace(/s/g, '00') // lowercase am/pm .replace(/a/g, pm ? 'pm' : 'am') // lowercase am/pm .replace(/A/g, pm ? 'PM' : 'AM'); } var tests = [ '1:00 pm','1:00 p.m.','1:00 p','1:00pm','1:00p.m.','1:00p','1 pm', '1 p.m.','1 p','1pm','1p.m.', '1p', '13:00','13', '1a', '12', '12a', '12p', '12am', '12pm', '2400am', '2400pm', '2400', '1000', '100', '123', '2459', '2359', '2359am', '1100', '123p', '1234', '1', '9', '99', '999', '9999', '99999', '0000', '0011', '-1', 'mioaw' ]; for ( var i = 0; i < tests.length; i++ ) { console.log( tests[i].padStart( 9, ' ' ) + " = " + parseTime(tests[i]) ); }
вот улучшение на Джо версия. Не стесняйтесь редактировать его дальше.
function parseTime(timeString) { if (timeString == '') return null; var d = new Date(); var time = timeString.match(/(\d+)(:(\d\d))?\s*(p?)/i); d.setHours( parseInt(time[1],10) + ( ( parseInt(time[1],10) < 12 && time[4] ) ? 12 : 0) ); d.setMinutes( parseInt(time[3],10) || 0 ); d.setSeconds(0, 0); return d; } var tests = [ '1:00 pm','1:00 p.m.','1:00 p','1:00pm','1:00p.m.','1:00p','1 pm', '1 p.m.','1 p','1pm','1p.m.', '1p', '13:00','13', '1a', '12', '12a', '12p', '12am', '12pm', '2400am', '2400pm', '2400', '1000', '100', '123', '2459', '2359', '2359am', '1100', '123p', '1234', '1', '9', '99', '999', '9999', '99999', '0000', '0011', '-1', 'mioaw' ]; for ( var i = 0; i < tests.length; i++ ) { console.log( tests[i].padStart( 9, ' ' ) + " = " + parseTime(tests[i]) ); }
изменения:
- добавлен параметр radix в вызовы parseInt () (поэтому jslint не будет жаловаться).
- сделал регулярное выражение нечувствительным к регистру, поэтому "2: 23 PM" работает как "2: 23 pm"
я наткнулся на пару перегибов в реализации решения Джона отставки. Здесь-модифицированная функция, которую я использую на основе его ответа:
function parseTime(timeString) { if (timeString == '') return null; var d = new Date(); var time = timeString.match(/(\d+)(:(\d\d))?\s*(p?)/); d.setHours( parseInt(time[1]) + ( ( parseInt(time[1]) < 12 && time[4] ) ? 12 : 0) ); d.setMinutes( parseInt(time[3]) || 0 ); d.setSeconds(0, 0); return d; } // parseTime() var tests = [ '1:00 pm','1:00 p.m.','1:00 p','1:00pm','1:00p.m.','1:00p','1 pm', '1 p.m.','1 p','1pm','1p.m.', '1p', '13:00','13', '1a', '12', '12a', '12p', '12am', '12pm', '2400am', '2400pm', '2400', '1000', '100', '123', '2459', '2359', '2359am', '1100', '123p', '1234', '1', '9', '99', '999', '9999', '99999', '0000', '0011', '-1', 'mioaw' ]; for ( var i = 0; i < tests.length; i++ ) { console.log( tests[i].padStart( 9, ' ' ) + " = " + parseTime(tests[i]) ); }
The времени пакет 0.9 КБС в размер. Доступно с менеджерами пакетов NPM и bower.
вот пример прямо из
README.md
:var t = Time('2p'); t.hours(); // 2 t.minutes(); // 0 t.period(); // 'pm' t.toString(); // '2:00 pm' t.nextDate(); // Sep 10 2:00 (assuming it is 1 o'clock Sep 10) t.format('hh:mm AM') // '02:00 PM' t.isValid(); // true Time.isValid('99:12'); // false
это более надежный подход, который учитывает, как пользователи намерены использовать этот тип ввода. Например, если пользователь ввел "12", они ожидали бы, что это будет 12 вечера (полдень), а не 12 утра. Ниже функция обрабатывает все это. Он также доступен здесь:http://blog.de-zwart.net/2010-02/javascript-parse-time/
/** * Parse a string that looks like time and return a date object. * @return Date object on success, false on error. */ String.prototype.parseTime = function() { // trim it and reverse it so that the minutes will always be greedy first: var value = this.trim().reverse(); // We need to reverse the string to match the minutes in greedy first, then hours var timeParts = value.match(/(a|p)?\s*((\d{2})?:?)(\d{1,2})/i); // This didnt match something we know if (!timeParts) { return false; } // reverse it: timeParts = timeParts.reverse(); // Reverse the internal parts: for( var i = 0; i < timeParts.length; i++ ) { timeParts[i] = timeParts[i] === undefined ? '' : timeParts[i].reverse(); } // Parse out the sections: var minutes = parseInt(timeParts[1], 10) || 0; var hours = parseInt(timeParts[0], 10); var afternoon = timeParts[3].toLowerCase() == 'p' ? true : false; // If meridian not set, and hours is 12, then assume afternoon. afternoon = !timeParts[3] && hours == 12 ? true : afternoon; // Anytime the hours are greater than 12, they mean afternoon afternoon = hours > 12 ? true : afternoon; // Make hours be between 0 and 12: hours -= hours > 12 ? 12 : 0; // Add 12 if its PM but not noon hours += afternoon && hours != 12 ? 12 : 0; // Remove 12 for midnight: hours -= !afternoon && hours == 12 ? 12 : 0; // Check number sanity: if( minutes >= 60 || hours >= 24 ) { return false; } // Return a date object with these values set. var d = new Date(); d.setHours(hours); d.setMinutes(minutes); return d; } var tests = [ '1:00 pm','1:00 p.m.','1:00 p','1:00pm','1:00p.m.','1:00p','1 pm', '1 p.m.','1 p','1pm','1p.m.', '1p', '13:00','13', '1a', '12', '12a', '12p', '12am', '12pm', '2400am', '2400pm', '2400', '1000', '100', '123', '2459', '2359', '2359am', '1100', '123p', '1234', '1', '9', '99', '999', '9999', '99999', '0000', '0011', '-1', 'mioaw' ]; for ( var i = 0; i < tests.length; i++ ) { console.log( tests[i].padStart( 9, ' ' ) + " = " + tests[i].parseTime() ); }
это прототип строки, так что вы можете использовать его так:
var str = '12am'; var date = str.parseTime();
вот решение больше для всех тех, кто использует 24h часы, которые поддерживают:
- 0820 -> 08:20
- 32 -> 03:02
- 124 -> 12:04
function parseTime(text) { var time = text.match(/(\d?\d):?(\d?\d?)/); var h = parseInt(time[1], 10); var m = parseInt(time[2], 10) || 0; if (h > 24) { // try a different format time = text.match(/(\d)(\d?\d?)/); h = parseInt(time[1], 10); m = parseInt(time[2], 10) || 0; } var d = new Date(); d.setHours(h); d.setMinutes(m); return d; } var tests = [ '1:00 pm','1:00 p.m.','1:00 p','1:00pm','1:00p.m.','1:00p','1 pm', '1 p.m.','1 p','1pm','1p.m.', '1p', '13:00','13', '1a', '12', '12a', '12p', '12am', '12pm', '2400am', '2400pm', '2400', '1000', '100', '123', '2459', '2359', '2359am', '1100', '123p', '1234', '1', '9', '99', '999', '9999', '99999', '0000', '0011', '-1', 'mioaw' ]; for ( var i = 0; i < tests.length; i++ ) { console.log( tests[i].padStart( 9, ' ' ) + " = " + parseTime(tests[i]) ); }
Я внес некоторые изменения в функцию выше, чтобы поддержать еще несколько форматов.
- 1400 -> 2:00 вечера
- 1.30 -> 1:30 вечера
- 1: 30a - > 1:30 AM
- 100 -> 1:00 утра
еще не очистил его, но работает для всего, что я могу придумать.
function parseTime(timeString) { if (timeString == '') return null; var time = timeString.match(/^(\d+)([:\.](\d\d))?\s*((a|(p))m?)?$/i); if (time == null) return null; var m = parseInt(time[3], 10) || 0; var hours = parseInt(time[1], 10); if (time[4]) time[4] = time[4].toLowerCase(); // 12 hour time if (hours == 12 && !time[4]) { hours = 12; } else if (hours == 12 && (time[4] == "am" || time[4] == "a")) { hours += 12; } else if (hours < 12 && (time[4] != "am" && time[4] != "a")) { hours += 12; } // 24 hour time else if(hours > 24 && hours.toString().length >= 3) { if(hours.toString().length == 3) { m = parseInt(hours.toString().substring(1,3), 10); hours = parseInt(hours.toString().charAt(0), 10); } else if(hours.toString().length == 4) { m = parseInt(hours.toString().substring(2,4), 10); hours = parseInt(hours.toString().substring(0,2), 10); } } var d = new Date(); d.setHours(hours); d.setMinutes(m); d.setSeconds(0, 0); return d; } var tests = [ '1:00 pm','1:00 p.m.','1:00 p','1:00pm','1:00p.m.','1:00p','1 pm', '1 p.m.','1 p','1pm','1p.m.', '1p', '13:00','13', '1a', '12', '12a', '12p', '12am', '12pm', '2400am', '2400pm', '2400', '1000', '100', '123', '2459', '2359', '2359am', '1100', '123p', '1234', '1', '9', '99', '999', '9999', '99999', '0000', '0011', '-1', 'mioaw' ]; for ( var i = 0; i < tests.length; i++ ) { console.log( tests[i].padStart( 9, ' ' ) + " = " + parseTime(tests[i]) ); }
Почему бы не использовать проверку, чтобы сузить то, что пользователь может ввести и упростить список, чтобы включать только форматы, которые могут быть проанализированы (или проанализированы после некоторой настройки).
Я не думаю, что прошу слишком многого требовать от пользователя поставить время в поддерживаемом формате.
dd:dd A(m)/P (m)
dd A(m)/P (m)
dd
/(\d+)(?::(\d\d))(?::(\d\d))?\s*([pP]?)/ // added test for p or P // added seconds d.setHours( parseInt(time[1]) + (time[4] ? 12 : 0) ); // care with new indexes d.setMinutes( parseInt(time[2]) || 0 ); d.setSeconds( parseInt(time[3]) || 0 );
спасибо
много ответов, так что еще один не повредит.
/** * Parse a time in nearly any format * @param {string} time - Anything like 1 p, 13, 1:05 p.m., etc. * @returns {Date} - Date object for the current date and time set to parsed time */ function parseTime(time) { var b = time.match(/\d+/g); // return undefined if no matches if (!b) return; var d = new Date(); d.setHours(b[0]>12? b[0] : b[0]%12 + (/p/i.test(time)? 12 : 0), // hours /\d/.test(b[1])? b[1] : 0, // minutes /\d/.test(b[2])? b[2] : 0); // seconds return d; } var tests = [ '1:00 pm','1:00 p.m.','1:00 p','1:00pm','1:00p.m.','1:00p','1 pm', '1 p.m.','1 p','1pm','1p.m.', '1p', '13:00','13', '1a', '12', '2400', '1000', '100', '123', '2459', '2359', '2359am', '1100', '123p', '1234', '1', '9', '99', '999', '9999', '99999', '0000', '0011', '-1', 'mioaw' ]; for ( var i = 0; i < tests.length; i++ ) { console.log( tests[i].padStart( 9, ' ' ) + " = " + parseTime(tests[i]) ); }
чтобы быть должным образом надежным, он должен проверить, что каждое значение находится в пределах допустимых значений, например, если часы am/pm должны быть от 1 до 12 включительно, в противном случае от 0 до 24 включительно и т. д.
вот еще один подход, который охватывает исходный ответ, любое разумное количество цифр, ввод данных кошками и логические ошибки. Алгоритм следующий:
- определить, является ли Меридиан post meridiem.
- преобразование входных цифр в целочисленное значение.
- время между 0 и 24: час-это часы, без минут (часы 12-PM).
- время между 100 и 2359: часы div 100-это часы, минуты mod 100 остаток.
- время с 2400: часы-полночь, с остатком минут.
- Когда часа превышает 12, вычесть 12 и силы после полудня правда.
- когда минут превышает 59, сила до 59.
преобразование часов, минут и post meridiem в объект даты-это упражнение для читателя (многочисленные другие ответы показывают, как это сделать).
"use strict"; String.prototype.toTime = function () { var time = this; var post_meridiem = false; var ante_meridiem = false; var hours = 0; var minutes = 0; if( time != null ) { post_meridiem = time.match( /p/i ) !== null; ante_meridiem = time.match( /a/i ) !== null; // Preserve 2400h time by changing leading zeros to 24. time = time.replace( /^00/, '24' ); // Strip the string down to digits and convert to a number. time = parseInt( time.replace( /\D/g, '' ) ); } else { time = 0; } if( time > 0 && time < 24 ) { // 1 through 23 become hours, no minutes. hours = time; } else if( time >= 100 && time <= 2359 ) { // 100 through 2359 become hours and two-digit minutes. hours = ~~(time / 100); minutes = time % 100; } else if( time >= 2400 ) { // After 2400, it's midnight again. minutes = (time % 100); post_meridiem = false; } if( hours == 12 && ante_meridiem === false ) { post_meridiem = true; } if( hours > 12 ) { post_meridiem = true; hours -= 12; } if( minutes > 59 ) { minutes = 59; } var result = (""+hours).padStart( 2, "0" ) + ":" + (""+minutes).padStart( 2, "0" ) + (post_meridiem ? "PM" : "AM"); return result; }; var tests = [ '1:00 pm','1:00 p.m.','1:00 p','1:00pm','1:00p.m.','1:00p','1 pm', '1 p.m.','1 p','1pm','1p.m.', '1p', '13:00','13', '1a', '12', '12a', '12p', '12am', '12pm', '2400am', '2400pm', '2400', '1000', '100', '123', '2459', '2359', '2359am', '1100', '123p', '1234', '1', '9', '99', '999', '9999', '99999', '0000', '0011', '-1', 'mioaw' ]; for ( var i = 0; i < tests.length; i++ ) { console.log( tests[i].padStart( 9, ' ' ) + " = " + tests[i].toTime() ); }
С помощью jQuery вновь определенный прототип строки используется следующим образом:
<input type="text" class="time" />
$(".time").change( function() { var $this = $(this); $(this).val( time.toTime() ); });
улучшение к решению Патрик McElhaney (его не обрабатывает 12я правильно)
function parseTime( timeString ) { var d = new Date(); var time = timeString.match(/(\d+)(:(\d\d))?\s*([pP]?)/i); var h = parseInt(time[1], 10); if (time[4]) { if (h < 12) h += 12; } else if (h == 12) h = 0; d.setHours(h); d.setMinutes(parseInt(time[3], 10) || 0); d.setSeconds(0, 0); return d; } var tests = [ '1:00 pm','1:00 p.m.','1:00 p','1:00pm','1:00p.m.','1:00p','1 pm', '1 p.m.','1 p','1pm','1p.m.', '1p', '13:00','13', '1a', '12', '2400', '1000', '100', '123', '2459', '2359', '2359am', '1100', '123p', '1234', '1', '9', '99', '999', '9999', '99999', '0000', '0011', '-1', 'mioaw' ]; for ( var i = 0; i < tests.length; i++ ) { console.log( tests[i].padStart( 9, ' ' ) + " = " + parseTime(tests[i]) ); }
Я не был доволен другими ответами, поэтому я сделал еще один. Эта версия:
- распознает секунды и миллисекунды
- возвращает
undefined
при недопустимом вводе, таком как" 13:00pm "или"11:65"- возвращает местное время, если вы предоставляете
localDate
параметр, в противном случае возвращает время UTC в эпоху Unix (1 января 1970 года).- поддерживает военное время, как
1330
(чтобы отключить, сделайте первый': 'требуется в регулярное выражение)- позволяет час сам по себе, с 24-часовым временем (т. е. "7" означает 7 утра).
- позволяет час 24 в качестве синонима для часа 0, но час 25 не допускается.
- требуется время, чтобы быть в начале строки (чтобы отключить, удалить
^\s*
в регулярном выражении)- имеет тестовый код, который фактически определяет, когда вывод неверен.
Edit: теперь это пакета в том числе
timeToString
форматер:npm i simplertime
/** * Parses a string into a Date. Supports several formats: "12", "1234", * "12:34", "12:34pm", "12:34 PM", "12:34:56 pm", and "12:34:56.789". * The time must be at the beginning of the string but can have leading spaces. * Anything is allowed after the time as long as the time itself appears to * be valid, e.g. "12:34*Z" is OK but "12345" is not. * @param {string} t Time string, e.g. "1435" or "2:35 PM" or "14:35:00.0" * @param {Date|undefined} localDate If this parameter is provided, setHours * is called on it. Otherwise, setUTCHours is called on 1970/1/1. * @returns {Date|undefined} The parsed date, if parsing succeeded. */ function parseTime(t, localDate) { // ?: means non-capturing group and ?! is zero-width negative lookahead var time = t.match(/^\s*(\d\d?)(?::?(\d\d))?(?::(\d\d))?(?!\d)(\.\d+)?\s*(pm?|am?)?/i); if (time) { var hour = parseInt(time[1]), pm = (time[5] || ' ')[0].toUpperCase(); var min = time[2] ? parseInt(time[2]) : 0; var sec = time[3] ? parseInt(time[3]) : 0; var ms = (time[4] ? parseFloat(time[4]) * 1000 : 0); if (pm !== ' ' && (hour == 0 || hour > 12) || hour > 24 || min >= 60 || sec >= 60) return undefined; if (pm === 'A' && hour === 12) hour = 0; if (pm === 'P' && hour !== 12) hour += 12; if (hour === 24) hour = 0; var date = new Date(localDate!==undefined ? localDate.valueOf() : 0); var set = (localDate!==undefined ? date.setHours : date.setUTCHours); set.call(date, hour, min, sec, ms); return date; } return undefined; } var testSuite = { '1300': ['1:00 pm','1:00 P.M.','1:00 p','1:00pm','1:00p.m.','1:00p','1 pm', '1 p.m.','1 p','1pm','1p.m.', '1p', '13:00','13', '1:00:00PM', '1300', '13'], '1100': ['11:00am', '11:00 AM', '11:00', '11:00:00', '1100'], '1359': ['1:59 PM', '13:59', '13:59:00', '1359', '1359:00', '0159pm'], '100': ['1:00am', '1:00 am', '0100', '1', '1a', '1 am'], '0': ['00:00', '24:00', '12:00am', '12am', '12:00:00 AM', '0000', '1200 AM'], '30': ['0:30', '00:30', '24:30', '00:30:00', '12:30:00 am', '0030', '1230am'], '1435': ["2:35 PM", "14:35:00.0", "1435"], '715.5': ["7:15:30", "7:15:30am"], '109': ['109'], // Three-digit numbers work (I wasn't sure if they would) '': ['12:60', '11:59:99', '-12:00', 'foo', '0660', '12345', '25:00'], }; var passed = 0; for (var key in testSuite) { let num = parseFloat(key), h = num / 100 | 0; let m = num % 100 | 0, s = (num % 1) * 60; let expected = Date.UTC(1970, 0, 1, h, m, s); // Month is zero-based let strings = testSuite[key]; for (let i = 0; i < strings.length; i++) { var result = parseTime(strings[i]); if (result === undefined ? key !== '' : key === '' || expected !== result.valueOf()) { console.log(`Test failed at ${key}:"${strings[i]}" with result ${result ? result.toUTCString() : 'undefined'}`); } else { passed++; } } } console.log(passed + ' tests passed.');