I am using Observable.interval to schedule code execuiton at specified times:
let obs = Observable.interval(50).subscribe(()=>{
console.log(this.currentFrame+" "+new Date().getTime());
this.currentFrame++
});
This is the output. As you can see, after 6 iterations I already have a 10ms drift. How can I use Observable.interval, but also specify that it needs to recalculate next iteration based on the current drift?
0 1513972329849
1 1513972329901
2 1513972329952
3 1513972330004
4 1513972330057
5 1513972330110
Until #cartant's fix gets repulled, you could use expand and create the behavior yourself. Assuming delay will always drift forward, try the following:
function correcting_interval(interval) {
const start_time = new Date().getTime();
return Observable.of(-1)
.expand(v => Observable.of(v + 1).delay(interval - (new Date().getTime() - start_time) % interval))
.skip(1);
}
I got some time intervals using the tic() and toc() functions which are in seconds.
Let's suppose I have a time interval dt=3600.125 seconds. How can I print it in "H:M:S.s" format using Julia?
If you convert it to Dates formats then you can use this method.
julia> t1 = now()
2017-11-10T10:00:51.974
# Wait
julia> t2 = now()
2017-11-10T10:10:07.895
julia> x = Dates.canonicalize(Dates.CompoundPeriod(t2-t1))
9 minutes, 15 seconds, 921 milliseconds
julia> x.periods
3-element Array{Base.Dates.Period,1}:
9 minutes
15 seconds
921 milliseconds
julia> x.periods[2]
15 seconds
julia> x.periods[2].value
18
You can make your own function. The main function to know is divrem which gives you the divisor as well as the remainder in one convenient function call.
dt=3600.125
function hmss(dt)
(h,r) = divrem(dt,60*60)
(m,r) = divrem(r, 60)
#(s,r) = divrem(r, 60)
string(Int(h),":",Int(m),":",r)
end
hmss(dt)
hmss(3452.98)
Have a look at the dates section in the manual.
Not sure if this is the most efficient way, but this works for instance:
julia> Dates.format(DateTime("2017-10-01T01:02:03"), "H:M:S.s")
"1:2:3.0"
""" working properly only if 0<= sec <=86400 otherwise truncating """
function fmtsec(sec, fmt::Dates.DateFormat)
# nanos = Dates.Nanosecond(sec * 1e9) # we could get InexactError here!
nanos = Dates.Nanosecond(trunc(Int, sec * 1e9))
mytime = Dates.Time(nanos)
Dates.format(mytime, fmt)
end
fmt = dateformat"H:M:S.s" # Creating a DateFormat object is expensive. (see doc)
fmtsec(3600.125, fmt) # "1:0:0.125"
EDIT: Without truncating nanoseconds we could get error ->
julia> tic();sleep(1);old_fmtsec(toc(), dateformat"S.s")
elapsed time: 1.002896514 seconds
ERROR: InexactError()
Stacktrace:
[1] convert(::Type{Int64}, ::Float64) at ./float.jl:679
[2] fmtsec(::Float64, ::DateFormat{Symbol("S.s"),Tuple{Base.Dates.DatePart{'S'},Base.Dates.Delim{Char,1},Base.Dates.DatePart{'s'}}}) at ./REPL[47]:2
julia> tic();sleep(1);old_fmtsec(toc(), dateformat"S.s")
elapsed time: 1.002857122 seconds
"1.002"
tic & toc are deprecated. toc could bring rounding error because it internally use time_ns but nanoseconds convert to seconds dividing by 1e9.
This date from toc() and time() in Julia uses UNIX timestamp, i.e., seconds elapsed since January 1, 1970
The same occurs with the function ctime(f) that returns timestamp from a file path f.
The conversion is very straightforward.
tic()
....
dif = toc()
# My local is Brazil, one should replace for its local format
Dt = DateTime(LibC.strftime(dif),"d/m/y H:M:S")
LibC does not have to be imported explicitly
I had a go now, but doing the carry over is a bit messy sorry:
using Dates
using Printf
function formatDuration(duration::Period, types::Vector{DataType}=[Hour, Minute, Second]; addUnit::Bool=false)
periods = canonicalize(Dates.CompoundPeriod(duration)).periods
missingTypes = Vector{DataType}(types)
newPeriods = vcat(periods, map(t->t(0), missingTypes))
sort!(newPeriods; rev=true)
newPeriods1 = Vector{Period}()
carryover = nothing
for (i, p) in enumerate(newPeriods)
typeofp = typeof(p)
if !isnothing(carryover)
newPeriod = convert(typeofp, floor(Millisecond(p) + Millisecond(carryover), typeofp(1)))
carryover = nothing
else
newPeriod = p
end
if (typeof(newPeriod) in types)
push!(newPeriods1, newPeriod)
filter!(e->e≠typeofp,missingTypes)
else
carryover = newPeriod
end
end
m = map(types) do t
f = findfirst(x -> typeof(x) == t, newPeriods1);
r = isnothing(f) ? 0 : newPeriods1[f].value;
#sprintf("%02d",r) * (addUnit ? lowercase("$t"[1]) : "")
end
join(m, ":")
end
Usage examples:
#show formatDuration(Millisecond(3600.125*1000))
# returns "01:00:00"
#show formatDuration(Day(2), [Hour, Minute, Second])
# returns "48:00:00"
#show formatDuration(Second(100000000), [Hour, Minute, Second])
# returns "27777:46:40"
#show formatDuration(Second(100000001), [Day, Hour, Minute, Second, Millisecond])
# returns "1157:09:46:41:00"
#show formatDuration(Millisecond(10000000001),
[Week, Day, Hour, Minute, Second, Millisecond]; addUnit=true)
#returns "16w:03d:17h:46m:40s:01m"
I've got a strange issue.
I use a custom command to share, via FB api, some url.
Now this command is scheduled to a fixed cron configuration but I would like this to be randomic, maybe between time ranges.
I tried using a random sleep function inside command, but I got strange behavior.
Did anyone already have to face this problem?
One solution is to put the code you want to run into a Queued Job, and then delay that job a random amount. For example, this code will run at a random time every hour (the same can easily be extrapolated to random time every day or on some other interval):
$schedule
->call(function () {
$job = new SomeQueuedJob();
// Do it at some random time in the next hour.
$job->delay(rand(0, 60 * 59));
dispatch($job);
})
->hourly();
You can generate random time at beginning.
protected function schedule(Schedule $schedule)
{
$expression = \Cache::get('schedule:expressions:inspire');
if (!$expression) {
$randomMinute = random_int(0, 59);
// hour between 8:00 and 19:00
$hourRange = range(8, 19);
shuffle($hourRange);
// execute twice a day
$randomHours = array_slice($hourRange, 0, 2);
$expression = $randomMinute . ' ' . implode($randomHours, ',') . ' * * * *';
\Cache::put('schedule:expressions:inspire', $expression, Carbon::now()->endOfDay());
}
$schedule->command('inspire')->cron($expression);
}
I have to make a random numer (1 and 2) in .lua, and change this value every 3 seconds.
I have a variable = randomMode, this randomMode have to change every 3 seconds (1 or 2)
You could try making a kind of timer that changes the value. For example the main program loop could to change the variable every 3 seconds by using time stamps.
If you cant use a good way to implement a timer, maybe just checking time stamps since last call is good enough. For example this function randomizes the number on each call to GetRandomMode if more than 3 seconds has passed:
local lastChange = os.time()
local mode = math.random(1, 2)
function GetRandomMode()
local now = os.time()
if os.difftime(now, lastChange) > 3 then
lastChange = now
mode = math.random(1, 2)
end
return mode
end
I want to read a file using shell script and here want to calculate the time required to read a file. I have created below method to get the time in milliseconds at the start and end of the file reading and I will calculate the time difference, but it is not adding the hour+minute+seconds and showing me that the required numeric input.
Method
getCurrentTimeInMili()
{
hourTime=$(($(date +%H)*3600))
minuteTime=$(($(date +%m)*60))
secondTime=$(date +%S)
timeInMili= $(($hourTime + $minuteTime + $secondTime));
return timeInMili
}
Error
./testshell.sh: line 17: return: timeInMili: numeric argument required
omit the space between timeInMili= and $
timeInMili= $(($hourTime + $minuteTime + $secondTime));
^
This to
timeInMili=$(($hourTime + $minuteTime + $secondTime));
Invoking date multiple times means that their return values can be a bit out of sync with each other -- which could be bad if we're invoked just before a second boundary. Better is to call date only once and retrieve all the information desired, like so:
getCurrentTimeInMili() {
date +'%H 3600 * %M 60 * + %S + 1000 * %N 1000000 / + p' | dc
}
startTime=$(getCurrentTimeInMili)
sleep 5
endTime=$(getCurrentTimeInMili)
If you don't need this much accuracy, you can simply use the time builtin, as in:
time sleep 5