now new from fechas fecha convertir comparar javascript datetime parsing date time

new - javascript date methods



¿Cuál es la mejor manera de analizar un momento en un objeto Date desde la entrada del usuario en Javascript? (17)

¿Por qué no utilizar la validación para restringir lo que un usuario puede poner y simplificar la lista para incluir solo los formatos que se pueden analizar (o analizar después de algunos ajustes).

No creo que sea demasiado pedirle a un usuario que ponga un tiempo en un formato compatible.

dd: dd A (m) / P (m)

dd A (m) / P (m)

dd

Estoy trabajando en un widget de formulario para que los usuarios ingresen una hora del día en una entrada de texto (para una aplicación de calendario). Usando JavaScript (estamos usando jQuery FWIW), quiero encontrar la mejor manera de analizar el texto que el usuario ingresa en un objeto JavaScript Date() para que pueda realizar fácilmente comparaciones y otras cosas en él.

parse() método parse() y es un poco exigente para mis necesidades. Esperaría que sea capaz de analizar con éxito los siguientes tiempos de entrada de ejemplo (además de otros formatos de tiempo lógicamente similares) como el mismo objeto Date() :

  • 13:00
  • 13:00
  • 1:00 p
  • 13:00
  • 13:00.
  • 1: 00p
  • 1 pm
  • 1 pm
  • 1 p
  • 13:00
  • 1 p.m.
  • 1p
  • 13:00
  • 13

Estoy pensando que podría usar expresiones regulares para dividir la entrada y extraer la información que quiero usar para crear mi objeto Date() . ¿Cuál es la mejor manera de hacer esto?



Aquí hay otro enfoque que cubre la respuesta original, cualquier cantidad razonable de dígitos, la entrada de datos por parte de los gatos y las falacias lógicas. El algoritmo sigue:

  1. Determine si el meridiano es post meridiem .
  2. Convierta dígitos de entrada en un valor entero.
  3. Tiempo entre 0 y 24: la hora es la en punto, no hay minutos (las horas 12 es PM).
  4. Tiempo entre 100 y 2359: horas div 100 es la en punto, minutos mod 100 restantes.
  5. Tiempo desde 2400 en adelante: horas es medianoche, con minutos restantes.
  6. Cuando las horas exceden 12, reste 12 y fuerce el post meridiem verdadero.
  7. Cuando los minutos exceden 59, fuerza a 59.

La conversión de las horas, los minutos y la publicación de meridianos a un objeto Date es un ejercicio para el lector (muchas otras respuestas muestran cómo hacerlo).

"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() ); }

Con jQuery, el prototipo de cadena recientemente definido se usa de la siguiente manera:

<input type="text" class="time" />

$(".time").change( function() { var $this = $(this); $(this).val( time.toTime() ); });


Aquí hay una mejora en la versión de Joe . Siéntase libre de editarlo más.

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]) ); }

Cambios:

  • Se agregó el parámetro radix a las llamadas a parseInt () (por lo que jslint no se quejará).
  • Hizo la regex case-insenstive por lo que "2:23 PM" funciona como "2:23 pm"

Aquí hay una solución más para todos aquellos que están usando un reloj de 24 horas que admite:

  • 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]) ); }


El paquete de time tiene un tamaño de 0.9kbs. Disponible con los gerentes de paquetes de NPM y bower.

Aquí hay un ejemplo directamente de 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


Encontré un par de problemas al implementar la solución de John Resig. Aquí está la función modificada que he estado usando en base a su respuesta:

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]) ); }


Este es un enfoque más robusto que tiene en cuenta cómo los usuarios pretenden utilizar este tipo de entrada. Por ejemplo, si un usuario ingresó "12", esperaría que fuera las 12 p.m. (mediodía) y no las 12 a.m. La función siguiente maneja todo esto. También está disponible aquí: 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() ); }

Este es un prototipo de cadena, por lo que puedes usarlo así:

var str = ''12am''; var date = str.parseTime();


He hecho algunas modificaciones a la función anterior para admitir algunos formatos más.

  • 1400 -> 2:00 p.m.
  • 1.30 -> 1:30 p.m.
  • 1: 30a -> 1:30 a.m.
  • 100 -> 1:00 a.m.

Aún no está limpio, pero funciona para todo lo que se me ocurre.

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]) ); }


La mayoría de las soluciones de expresiones regulares arrojan errores cuando no se puede analizar la cadena, y no muchas cuentan para cadenas como 1330 o 130pm . 130pm Aunque estos formatos no fueron especificados por el OP, los considero críticos para analizar las fechas ingresadas por humanos.

Todo esto me hizo pensar que usar una expresión regular podría no ser el mejor enfoque para esto.

Mi solución es una función que no solo analiza el tiempo, sino que también te permite especificar un formato de salida y un paso (intervalo) en el que redondear los minutos. En aproximadamente 70 líneas, sigue siendo ligero y analiza todos los formatos antes mencionados, así como los que no tienen dos puntos.

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]) ); }


Muchas respuestas, así que una más no hará daño.

/** * 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]) ); }

Para ser robusto, debe verificar que cada valor esté dentro del rango de valores permitidos, por ejemplo, si las horas am / pm deben ser de 1 a 12 inclusive, de lo contrario 0 a 24 inclusive, etc.


No estaba contento con las otras respuestas, así que hice otra más. Esta versión:

  • Reconoce segundos y milisegundos
  • Devuelve undefined en entradas no válidas como "13:00 pm" o "11:65"
  • Devuelve una hora local si proporciona un parámetro localDate ; de lo contrario, devuelve una hora UTC en la época de Unix (1 de enero de 1970).
  • Admite tiempo militar como 1330 (para deshabilitar, hacer el primer '':'' requerido en la expresión regular)
  • Permite una hora por sí sola, con un horario de 24 horas (es decir, "7" significa 7am).
  • Permite la hora 24 como sinónimo de la hora 0, pero la hora 25 no está permitida.
  • Requiere el tiempo para estar al principio de la cadena (para deshabilitar, eliminar ^/s* en la expresión regular)
  • Tiene un código de prueba que realmente detecta cuando la salida es incorrecta.

Editar: ahora es un package incluye un formateador npm i simplertime : 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.'');


No te molestes en hacerlo tú mismo, solo usa datejs .


Todos los ejemplos proporcionados no funcionan para las horas de 12:00 a.m. a 12:59 a.m. También arrojan un error si la expresión regular no coincide con un tiempo. Lo siguiente maneja esto:

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]) ); }

Esto funcionará para cadenas que contienen un tiempo en cualquier lugar dentro de ellas. Entonces, "abcde12: 00pmdef" se analizará y regresará a las 12 p. M. Si el resultado deseado es que solo devuelve un tiempo cuando la cadena solo contiene un tiempo en ellos, se puede usar la siguiente expresión regular siempre que reemplace "tiempo [4]" por "tiempo [6]".

/^(/d+)(:(/d/d))?/s*((a|(p))m?)?$/i


Una mejora de la solución de Patrick McElhaney (no maneja las 12 a.m. correctamente)

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]) ); }


Una solución rápida que funciona en la entrada que ha especificado:

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]) ); }

También debería funcionar para algunas otras variedades (incluso si se usa, todavía funcionará, por ejemplo). Obviamente, esto es bastante crudo, pero también es bastante ligero (mucho más barato de usar que una biblioteca completa, por ejemplo).

Advertencia: el código no funciona a las 12:00 a.m., etc.


/(/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 );

Gracias