My substr method not working in js - javascript

What is the difference between the uncommented lines vs the commented(which is grabbing mm and multiplying by 60 then concatenating with ss)?
function getSeconds(str) {
// var mm = str.substr(0,2);
// var ss = str.substr(3,5);
// return mm*60+ss;
var nums = str.split(':'),
mm = +nums[0],
ss = +nums[1];
return mm * 60 + ss;
}
getSeconds("13:25");

In the working example, you are explicitly converting the strings into numbers using the + prefix.
In the commented out example, you are not. The minutes are implicitly converted into a number due to the multiplication, however the seconds are simply appended via a string concatenation.
You can resolve that by explicitly converting the two components this example as well:
function getSeconds(str) {
var mm = +str.substr(0,2);
var ss = +str.substr(3,2);
return mm*60+ss;
}
console.log(getSeconds("13:25"));

You need to convert to string before using .substring();
var myStr = value.toString().substring(2,4);

Related

NodeJS (JavaScript) - Fastest method to convert date?

In NodeJS, I'm reading and parsing a .txt file with more than 1.5M lines. Each line is in the format: date,number,number, where each date is yyyyMMddhhmmss. An example line is:
20170506014255,100.01,200.02
Using jFile, I can read and parse all 1.5M+ lines in about 2 seconds...
var jFile = require('jfile');
var data = [];
var dataFile = new jFile('./dataFile.txt');
dataFile.lines.forEach(function(line) {
data.push(line.split(','));
});
Works great! But, I'd like to change the date format to something else. For this, I am using date-format to do the conversion...
... same as previous, with new line within forEach() ...
var dateFormatter = require('date-format');
dataFile.lines.forEach(function(line) {
let tdata = line.split(',');
tdata[0] = dateFormatter('MM/dd/yy hh:mm:ss', dateFormatter.parse('yyyyMMddhhmmss', tdata[0]));
data.push(tdata);
});
Again, this works great! Mostly. What once took only 2 seconds now takes about 25 seconds. Gasp!
Ideally, the file would just have the dates formatted the correct way, but this is out of my hands.
Is there a faster way to do this conversion? Maybe there is a more native approach, or just a faster package?
Thanks for any insight!
I guess it is faster to hardcode the parsing:
function fixFormat(date) {
const yy = date.slice(2, 4);
const MM = date.slice(4, 6);
const dd = date.slice(6, 8);
const hh = date.slice(8, 10);
const mm = date.slice(10, 12);
const ss = date.slice(12, 14);
return `${MM}/${dd}/${yy} ${hh}:${mm}:${ss}`;
}
Or really really ugly:
const y = 2, M = 4, d = 6, h = 8, m = 10, s = 12;
const pattern = fn => date => fn(p => date[p] + date[p + 1])
const fixFormat = pattern(p => p(M) + "/" + p(d) + "/" + p(y) + " " + p(h) + ":" + p(m) + ":" + p(s));
It seems you want to play a game of coding golf to see who can write the fastest code for you.
Anything that parses the string, creates a Date, then generates a string from if it going to be slower than something that just reformats the string. Jonas' approach is valid, and probably fast enough, but all those slices must take their toll. A single match should be faster, but it's up to you:
// Convert a timestamp in yyyyMMddhhmmss format to MM/dd/yy hh:mm:ss
// where "hh" is assumed to be 24 hr
function formatDate(s) {
var b = s.match(/\d\d/g);
return `${b[2]}/${b[3]}/${b[1]} ${b[4]}:${b[5]}:${b[6]}`;
}
console.log(formatDate('20170506014255'));
I have no idea if that's faster, but it's certainly a lot less code. If you really want to make it fast, create the regular expression once:
// Convert a timestamp in yyyyMMddhhmmss format to MM/dd/yy hh:mm:ss
// where "hh" is assumed to be 24 hr
var formatDate = (function() {
var re = /\d\d/g;
return function (s) {
var b = s.match(re);
return `${b[2]}/${b[3]}/${b[1]} ${b[4]}:${b[5]}:${b[6]}`;
};
}());
console.log(formatDate('20170506014255'));

Javascript number like time regex format

I'm receiving from my database time like hh:mm:ss, and in javascript i would like to put the time like hh:mm
this is my code
var time = '10:01:30';
console.log(time);
var res = formatTime(time);
console.log(res);
function formatTime(time) {
var result = false, m;
var re = /^\s*([01]?\d|2[0-3]):?([0-5]\d)\s*$/;
if ((m = time.match(re))) {
result = (m[1].length === 2 ? "" : "0") + m[1] + ":" + m[2];
console.log(result);
}
}
The function doesn't work well since i receive "false", any help?
Thanks
May be I am missing something in the question, but if you simply want to extract the hh:mm part from hh:mm:ss, then this should work:
// var time = "hh:mm:ss";
var time = "10:01:30";
var splitTime = time.trim().split(":"); // trim to remove any leading and trailing spaces
var formattedTime = splitTime[0] +":"+ splitTime[1];
console.log( formattedTime );
Couldn't you just do the following?:
function formatTime(time) {
var array = time.split(':');
return array[0] + ':' + array[1];
}
The other answer (using split) is undoubtably the easier way to do this.
However, if you're wondering why your regex was not matching, it is because your regular expression was looking for the first (hh) block, and then the second (mm) block, but was then expecting whitespace after that until the end of the line - no allowance for the ss part.
I changed this rather heavy-handedly to allow anything after the mm part until the end of the line. see below.
Also, if you're wondering why your formatTime function returns undefined its because you forgot to return result
var time = '10:01:30';
console.log(time);
var res = formatTime(time);
console.log(res);
function formatTime(time) {
var result = false, m;
var re = /^\s*([01]?\d|2[0-3]):?([0-5]\d).*$/;
if ((m = time.match(re))) {
result = (m[1].length === 2 ? "" : "0") + m[1] + ":" + m[2];
console.log(result);
}
return result;
}
I would consider working with native Date object to do your formatting. This will do a few things for you:
Automatically validate the time value that is being input. No need for regex to do this. Either the input string is valid and the function works, or it is invalid and the function returns NaN.
Give you flexibility in how you work with the value. Need to convert time zones, convert to Unix timestamp, etc.? These are built in methods on Date object.
Gives flexibility on input values. You could potentially you other string input types here if needed as long as they can allow for instantiation of valid Date object. You need to modify regex to allow for multiple input types or anything like that.
Using this approach, example code might look like:
function stripSecondsFromTimeString(time) {
// create data object representing current date
// the date is not really important here other than allowing
// you to format a fully valid Date object with your time fragment
var day = new Date();
var dateInput = day.toDateString() + ' ' + time;
var date = new Date(dateInput);
// validate we were able to get useful Date object
if(isNaN(date.getHours())) {
return NaN;
}
// log out some values so you can see how you might more fully work with Date object
console.log(date.toString());
console.log(date.getDate());
console.log(date.getHours());
console.log(date.getMinutes());
// prepare to return string
var hours = '' + date.getHours();
if(hours.length === 1) {
hours = '0' + hours;
}
var minutes = '' + date.getMinutes();
if(minutes.length === 1) {
minutes = '0' + minutes;
}
return hours + ':' + minutes;
}
// Usage examples
// your input time fragment
var inputTime = '10:01:30';
var formattedTime = stripSecondsFromTimeString(inputTime);
console.log(formattedTime);
// example failure case
var invalidTime = 'foo';
console.log(stripSecondsFromTimeString(invalidTime));

conversion of string containing times to 24-hour times I can do math with - jQuery

I am trying to find a way in jQuery/javascript to reliably convert strings like these:
"10:30 am – 11:00 pm" or this "6:45 am – 9:50 pm"
into two pieces each, 1030 and 2300 or 645 and 2150 respectively. The end goal is to see if the current time is in between the two, I think I have that part down, but the conversion to 24-hour time is throwing me off.
Here is a (non)working example but it might help to better illustrate my idea: http://codepen.io/AlexBezuska/pen/LkxBb
Thanks!
Try something like this with some regex magic:
var str = '6:45 am – 9:50 pm';
var result = [],
regex = /(\d{1,2}):(\d{1,2})\s?(am|pm)/gi;
str.replace(regex, function(_, hours, minutes, meridian) {
hours =+ hours;
if (meridian.toLowerCase() == 'pm') hours += 12;
result.push( +(hours +''+ minutes));
});
console.log(result); //=> [645, 2150]
In the following code the input string is not validated for the correct format, it assumes the string is always in the correct format
function time24h(parts){
var elms = /^(\d+):(\d+)$/.exec(parts[0]);
return +elms[1] + (/^am$/i.test(parts[1]) ? 0 : 12) + elms[2];
}
function converter(string){
var array = [];
var regex = /^(\d+:\d+)\s+(am|pm)\s+.\s+(\d+:\d+)\s+(am|pm)$/;
var parts = regex.exec(string);
array.push(time24h([parts[1], parts[2]]));
array.push(time24h([parts[3], parts[4]]));
return array;
}
Demo: Fiddle
Like this:
/**
* Returns time numeric value
* #param timeIn12hours
* #return {*}
*/
function get24hoursTime(timeIn12hours)
{
timeIn12hours = timeIn12hours.replace(/^\s+|\s+$/g,'');
var timeParts = timeIn12hours.split(" ");
var timePeriod = timeParts[1];
var hourParts = timeParts[0].split(":");
if(timePeriod == 'pm')
return (12 + parseInt(hourParts[0])) + hourParts[1];
return hourParts[0] + hourParts[1];
}
/**
* Returns object with period numeric values
* #param periodIn12hours
* #return {Object}
*/
function get24hoursPeriod(periodIn12hours)
{
var parts = periodIn12hours.split("-");
return {
'from': get24hoursTime(parts[0]),
'to': get24hoursTime(parts[1])
}
}
val = get24hoursPeriod("6:45 am - 9:50 pm");
alert("From: " + val.from + ", to: "+ val.to);

JavaScript Time Until

I need to do the simplest thing, take an input date/time and write out the hours:minutes:seconds until that time. I haven't been able to figure it out. I even tried using Datejs which is great, but doesn't seem to have this functionality built in.
The time is going to be somewhere in the range of 0 mins -> 20 minutes
Thanks!
Don't bother with a library for something so simple. You must know the format of the input date string whether you use a library or not, so presuming ISO8601 (like 2013-02-08T08:34:15Z) you can do something like:
// Convert string in ISO8601 format to date object
// e.g. 2013-02-08T02:40:00Z
//
function isoToObj(s) {
var b = s.split(/[-TZ:]/i);
return new Date(Date.UTC(b[0], --b[1], b[2], b[3], b[4], b[5]));
}
function timeToGo(s) {
// Utility to add leading zero
function z(n) {
return (n < 10? '0' : '') + n;
}
// Convert string to date object
var d = isoToObj(s);
var diff = d - new Date();
// Allow for previous times
var sign = diff < 0? '-' : '';
diff = Math.abs(diff);
// Get time components
var hours = diff/3.6e6 | 0;
var mins = diff%3.6e6 / 6e4 | 0;
var secs = Math.round(diff%6e4 / 1e3);
// Return formatted string
return sign + z(hours) + ':' + z(mins) + ':' + z(secs);
}
You may need to play with the function that converts the string to a date, but not much. You should be providing a UTC timestring anyway, unless you can be certain that the local time of the client is set to the timezone of the supplied datetime value.
Instead of Date.js, try Moment.js.

Is there a way to increment time using javascript?

So I am storing times as '01:30:00'. I have a start time and a date time dropdown. I want the dropdown to be set to the start time + 1hr. Is there a way to add the time via javascript or jquery?
Here's my current code:
$(".start_time").change(function(){
$(".end_time").val($(this).val());
});
Try this:
find the selected index of the start time
bump it up by 2 to find your end time index (given that you've got half hour increments)
use the mod operator % to wrap back to index 0 or 1 (for 00:00 and 00:30 respectively)
$(".start_time").change(function(){
var sel =$(this).attr('selectedIndex');
var endIdx = (sel + 2) % 48; // 47 is 23:30, so 48 should go back to index 0
$(".end_time").attr('selectedIndex', endIdx);
});
Try it out on JSBin.
There are two separate problems here: the first is parsing out the time from your .start_time input, and the second is incrementing it to be an hour later.
The first is really a string-manipulation exercise. Once you have parsed out the pieces of the string, e.g. via a regex, you could either turn them into a Date instance and use setHours, or you could just manipulate the components as numbers and them reassemble them into a string in the format you desire.
An example of this might be as follows:
var TIME_PARSING_REGEX = /([0-9]{2}):([0-9]{2}):([0-9]{2})/;
function padToTwoDigits(number) {
return (number < 10 ? "0" : "") + number;
}
$(".start_time").change(function () {
var stringTime = $(this).val();
var regexResults = TIME_PARSING_REGEX.exec(stringTime);
var hours = parseInt(regexResults[1], 10);
var newHours = (hours + 1) % 24;
var newHoursString = padToTwoDigits(newHours);
var minutesString = regexResults[2];
var secondsString = regexResults[3];
var newTimeString = newHoursString + ":" + minutesString + ":" + secondsString;
$(".end_time").val(newTimeString);
});
Basic example...
var date = new Date();
var h = date.getHours() + 1;
var m = date.getMinutes();
var s = date.getSeconds();
alert('One hour from now: ' + h + ':' + m + ':' + s);
Demo: http://jsfiddle.net/fBaDM/2/
After you parse you date/time string, you can use methods such as .setHours in your date object (more info at Mozilla Developer Center).
I highly recommend the DateJS library for working with date and time. I'm sure it'll be very handy for you.
protip: try to avoid replacing JavaScript with "jQuery markup"; it's all JS, after all. :)

Categories

Resources