jQuery UI Timepicker off by 1 minute - jquery-ui-timepicker

I'm maintaining an application which uses the jQuery UI Timepicker and trying to troubleshoot a bug.
Basically, this is how to re-create it:
There are 2 timepickers, start time and end time
1. on the start-time, select 6:00am (from the hour area)
2. on the end-time, select 12:00pm (from the hour area)
3. go back to the start-time and select 00 from the minute area
Then some code runs to determine the elapsed time in minutes. That code is:
function setDuration() {
var $startTime = $(".field.times input[name$='StartTime']");
var $endTime = $(".field.times input[name$='EndTime']");
var $durationHours = $(".field.duration input[name$='DurationHours']");
var $durationMinutes = $(".field.duration input[name$='DurationMinutes']");
if ($startTime.val() != "" && $endTime.val() != "") {
var startTime = $startTime.timepicker ? $startTime.timepicker('getTimeAsDate') : Date.parse('01 jan 01 ' + $startTime.val(), "hh:mm tt");
var endTime = $endTime.timepicker ? $endTime.timepicker('getTimeAsDate') : Date.parse('01 jan 01 ' + $endTime.val(), "hh:mm tt");
var duration = (endTime - startTime) / 1000 / 60;
//check whether spanning multiple days
if (startTime > endTime) {
duration = duration + (60 * 24);
}
$durationHours.val(Math.floor(duration / 60));
$durationMinutes.val(duration % 60);
}
}
I have found that after completing steps 1 and 2, everything is fine.
But, if I complete step 3, the endTime local variable is assigned a date object which has a time component of 11:59 and not 12:00.
Off by 1 minute.
If I then go to the End Time picker and select 00 from the minute area, as I did with the Start Time picker, the elapsed time rights itself again.
As an interesting observation when debugging, both timepickers are 1 minute behind after steps 1 and 2. That is, they are at 5:59 and 11:59. The elapsed time is correct, as the difference is important. But as a said, as soon as a user selects 00 from the hours area, it seems to "right itself" for that picker and the difference is out by 1 minute (until the same thing is done for the other picker).
Javascript dates are hard! Help would be great.

Yeah, figured it out. I guess it is an opinionated component which holds the opinion that the user must select a minutes figure from the minutes area. Because if they don't, the minutes will be -1.
Fair enough.
To fix this bug, in the onSelect handler, I wrote some code similar to this:
$('#timepicker').timepicker({
onSelect: function (time, inst) {
if (inst.minutes < 0)
inst.minutes = 0;
}
});
In our app, if they don't select '00' or any other minutes, it will be presumed to be 0.

Related

Inaccurate DispatchTime.now() in Swift 3.0

I'm using DispatchTime.now() to measure elapsed time between events. Sometimes it works correctly, but occasionally it generates values that are far below what I would expect.
My current usage:
var t = DispatchTime.now()
var pt = DispatchTime.now()
// called when an event happens
t = DispatchTime.now()
var elapsed = Double(t.uptimeNanoseconds - pt.uptimeNanoseconds)
elapsed *= 32768/1000000000
pt = t
Such that t and pt are current and previous times, elapsed takes the difference in nanoseconds, converts to double, and scales such that 1 second = 32768. When this technique fails the data recorded is about 100 times smaller than what is expected. The scaling is not the issue, I've checked the rawValue of t and pt. My assumption would be that the clock that runs DispatchTime is running at a slower speed, maybe because of debugging, but in general I would think iOS would compensate for something like this.
As #AlexanderMomchliov suggested NSDate is a better approach than DispatchTime.
Implemented as:
var t: TimeInterval = 0
var pt: TimeInterval = NSDate().timeIntervalSinceReferenceDate
// called when an event happens
t = NSDate().timeIntervalSinceReferenceDate
var elapsed: Double = t - pt
elapsed *= 32768
pt = t
You are performing integer division which will result in inaccurate elapsed time:
elapsed *= 32768/1000000000
You should either wrap these as Double or end them with a decimal (i.e. 32768.0/1000000000.0):
elapsed *= Double(32768)/Double(1000000000)
Additionally, NSEC_PER_SEC is defined as a global variable as part of the Dispatch framework:
elapsed *= Double(32768)/Double(NSEC_PER_SEC)
NSDate or Date may be adjusted by the system and should not be used for reliably measuring elapsed time. DispatchTime or CACurrentMediaTime would be good solutions and are both based on mach absolute time. However, if the app is put in the background during measurement, then using Date would be a good fallback.
Also recommend checking out this question for further discussion.

How to set dynamic minorTickInterval according to the datarange in Highstock?

I used configured Highstock's "tickPositioner" to set ticks dynamically for different ranges of data. For example, if the range is 1 hour max => 1 tick every 10 minutes. Here is some code of the function I put in tickPositioner (which is in xAxis config):
if (xDataRange <= oneHour) {
// If range is 1 hour max => 1 tick every 10 minutes
increment = oneMinute*10;
positions.info.unitName = "minute";
} else if (xDataRange > oneHour && xDataRange <= oneDay) {
// If range is between 1 hour and 1 day => 1 tick every hour
increment = oneHour;
positions.info.unitName = "hour";
} else { ... }
Here is an illustrating fiddle : http://jsfiddle.net/E6GHC/124/
(I know that the range choices are not the best here.)
The QUESTION: I would like to do the same with the minorTicks.
As you can see in the Fiddle, when you click on the month button the ticks are positionned each week and minorTicks are each day. But this is static configuration (minorTickInterval: oneDay).
I have some ideas and I have tried them and nothing seems to work out..
So if someone have any suggestion ? I would be veryyy thankful.
The perfect thing would have been to be have to set/update the minorTickInterval in tickPositioner function.

How to get time interval until date

I would like to get the time interval from the present date and time until a certain date in the future. All I could manage to do is get the interval but with a minus in front of all, because i used this:
let elapsedTime = NSDate().timeIntervalSinceDate(GeneralUtils.dateFromString(endDate))
let formatter = NSDateComponentsFormatter()
formatter.unitsStyle = .Abbreviated
let countdown = formatter.stringFromTimeInterval(elapsedTime)
timerLabel.text! = "\(countdown!)"
How could I fix it to show me the positive interval?
Now it shows me something like this "-1d 3h 23m 10s"
Just use abs() so the time interval is always positive. (Just me being insane)
Of course Russell points out you could just swap the dates around...
let elapsedTime = GeneralUtils.dateFromString(endDate).timeIntervalSinceNow

UI Slider Time of Day Beyond Midnight?

So this is a unique situation. I have a double slider I made using swift to make a time range picker like the one Kayak has. Unfortunately mine needs to be a time range between 00:00 all the way to 04:00 the following morning.
It was easy to get it from 00:00 to 23:59 using a scale of 86340 seconds for my slider control. I simply plug that into this little function and out pops the correct range on both ends/knobs:
func getTimeStringFromSeconds(seconds: Double) -> String {
let dcFormatter = NSDateComponentsFormatter()
dcFormatter.zeroFormattingBehavior = NSDateComponentsFormatterZeroFormattingBehavior.Pad
dcFormatter.allowedUnits = [NSCalendarUnit.Hour, NSCalendarUnit.Minute]
dcFormatter.unitsStyle = NSDateComponentsFormatterUnitsStyle.Positional
return dcFormatter.stringFromTimeInterval(seconds)!
}
As you can see in the screenshot above though I have 100740 seconds instead as the scale. How can I get it to go beyond 23:59, then reset to 00:00 and go into the next day? I can make it go to 28:00 as seen above which would technically be 4am but I want it to start over and show 04:00, not 28:00. What's a good solution for this?
Just as a note, my only solution so far was a sort of hack to make the label say 0:00 by resetting the seconds to 0.00 once it goes over 86340. The scale is still 100740 but there's some math like the following to make the label say otherwise without messing with the value of the knob (upperValue):
if upperKnobLayer.highlighted {
upperValue += valueDelta
upperValue = max(min(maximumValue, upperValue), lowerValue)
var upperDouble = Double(round(upperValue))
if upperDouble > 86340.00 {
let newValue = upperDouble - 86340
upperDouble = 0.00 + newValue
}
upperTime = getTimeStringFromSeconds(upperDouble)
}
It would help to post the implementation of your picker but generally you want the sliders value type to be NSTimeIntervals. Then you can have a reference date which will be midnight 00:00 of today. You can use NSDate(timeIntervalSince:referenceDate) to then get an NSDate representing any date since that reference date which can be formatted accordingly and display to the screen. The added benefit of this way is that the actual day of the date will be correct if your timeInterval makes it spill over to the next day
How about normalizing to a day's worth of seconds.
return dcFormatter.stringFromTimeInterval(seconds % 86340)!

How to get rid of the vacant weekend in the candlestick chart

I've read some articles about the weekend problem with teechart and the suggestions are the foolowing steps:
TChart1.Series(0).XValues.DateTime = False
Use continuous numbers as Xvalues
replace the X label with datetime.
The problem is: I draw the real time candlesticks according to the date,hour and minute and I must keep TChart1.Series(0).XValues.DateTime = True
So are there any ways to get rid of the null weekend (not only the weekend, even some time in a day as from 5:15 to 6:00 need to be removed) so that the candlesticks are shown continuously (the Xvalues must keep datetime style all the time)?
thanks.
(BTW, I use Teechart2011 Eval & VB6)
TeeChart draws each point according to its X and Y values in the associated axes.
You can work with Break Axis tool to obtain a discontinuous effect in an axis, but the easiest way to draw the points continuously in the horizontal axis is having continuous X values. So I'd suggest you to use the TChart1.Series(i).asCandle.AddCandle XVal, OpenVal, HighVal, LowVal, CloseVal, Label, clTeeColor function, being:
XVal: TChart1.Series(i).Count, instead of the date retrieved from the system
Label: the date retrieved from the system, converted to string
If this doesn't solve the problem because you still think you must have DateTime XValues, please explain why.
Taking your snipped of code from here, I've created a simple example that seems to work fine for me here. Find it below:
Private Sub Form_Load()
Dim month, day, year, hour, minute, second, nums As Integer
Dim tmpDate As Date
month = 6
day = 7
year = 2012
hour = 6
minute = 15
second = 0
nums = 10
TChart1.Aspect.View3D = False
TChart1.AddSeries scCandle
TChart1.Axis.Bottom.Labels.Angle = 90
For i = 1 To nums
tmpDate = (DateValue(day & "," & month & "," & year) + TimeValue(hour & ":" & minute & ":" & second))
If Not IsWeekend(tmpDate) Then
With TChart1.Series(0)
.asCandle.AddCandle .Count, 5, 15, 0, 10, tmpDate, clTeeColor
End With
End If
day = day + 1
Next i
End Sub
Public Function IsWeekend(InputDate As Date) As Boolean
Select Case Weekday(InputDate)
Case vbSaturday, vbSunday
IsWeekend = True
Case Else
IsWeekend = False
End Select
End Function

Resources