Convert from erlang:system_time() to os:timestamp() - time

How can I convert erlang:system_time(), integer, to os:timestamp() {MegaSecs, Secs, MicroSecs} ?

In Erlang, we can convert with code below:
timestamp() ->
ErlangSystemTime = erlang:system_time(microsecond),
MegaSecs = ErlangSystemTime div 1000000000000,
Secs = ErlangSystemTime div 1000000 - MegaSecs*1000000,
MicroSecs = ErlangSystemTime rem 1000000,
{MegaSecs, Secs, MicroSecs}

Related

Python 'numpy.ndarray' object has no attribute 'split' while converting HH:MM:SS.MS TO MS

I have a string array of time which is in the format of hh:mm:ss.ms. I am writing a function to convert to milliseconds format. While the function work for individual entry but fails to output for the entire array.
Here is my code
Time1= np.array(['18:01:52.388','18:01:52.431','18:01:52.848'])
def get_msec(time_str):
"""Get milliseconds from time."""
h, m, s = time_str.split(':')
return int((int(h) * 3600 + int(m) * 60 + float(s))*1000)
print(get_msec(Time1))
Could someone please pinpoint me where I am doing mistake.
Thank you
I have tried with below code and its now working
Time1= np.array(['18:01:52.388','18:01:52.431','18:01:52.848'])
def get_msec(time_str):
"""Get Seconds from time."""
new=[]
for items in time_str:
h, m, s = items.split(':')
new.append(int((int(h) * 3600 + int(m) * 60 + float(s))*1000))
return new
print(get_msec(Time1))
Thank you

How to print 3600.125 seconds in "H:M:S.s" format in Julia

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"

MAC - AVAssetReader for TRIM - reading samples OUT OF ORDER

I am trying to read and write the samples from a video file at a specific start point and end point for trimming a video. I am using AVAssetReader and AVAssetWriter.
The logic used here is -
STEP A:
Create asset reader instance with the specified asset.
Set the time range to the reader as per the start and end points. ( Say for example - start point = 5, end point = 15, file length = 55 sec )
Start reading the samples.
Get the sample's exact time stamp with respect to start point that we have passed in.
Store the time stamp of the sample that is accurate with the start point.( could be 5.13 or so ). Say ta = 5.13
Release the reader.
STEP B:
Create a new reader instance with the specified asset.
Set the time range to the reader as per the start and end points. ( Say for example - start point = 5, end point = 15, file length = 55 sec )
Start reading the samples.
Create a new sample buffer with sample timing info altered as
( sample buffer's time stamp t1- ta fetched from STEP A ) - This starts to write from 0
( sample buffer's time stamp t2- ta fetched from STEP A )
( sample buffer's time stamp t3- ta fetched from STEP A ) and so on till end point.
Release the reader.
The code sample for the same is:
STEP A:
while ([assetWriterInput isReadyForMoreMediaData] )
{
CMSampleBufferRef sampleBuffer = [assetReaderOutput copyNextSampleBuffer];
if (sampleBuffer != NULL)
{
CMTime originalTime = CMSampleBufferGetPresentationTimeStamp(sampleBuffer);
float time = CMTimeGetSeconds( originalTime );
// This is where we store the time stamp
fTimeTange = time;
[HelpMethods setCorrectEditTime:fTimeTange]; // This is stored globally
// This is to release the readers and writers and start a fresh call with the stored time stamp ta
[delegate resetTimeRange];
return;
}
}
STEP B:
while ([assetWriterInput isReadyForMoreMediaData] )
{
CMSampleBufferRef sampleBuffer = [assetReaderOutput copyNextSampleBuffer];
if (sampleBuffer != NULL)
{
CMSampleBufferRef finalBuffer = sampleBuffer;
CMSampleBufferRef newSampleBuffer;
CMSampleTimingInfo sampleTimingInfo;
CMTime cmm1 = CMSampleBufferGetOutputDuration(sampleBuffer);
CMTime originalTime = CMSampleBufferGetPresentationTimeStamp(sampleBuffer);
float time = CMTimeGetSeconds( originalTime );
// This is a helper method to get the stored ta at STEP A
fTimeTange = [HelpMethods getCorrectEditTime];
sampleTimingInfo.duration = cmm1;
float milliseconds = (time - fTimeTange) * 600;
NSLog( #"Timestamp in milliseconds = %f", milliseconds );
sampleTimingInfo.presentationTimeStamp = CMTimeMake(milliseconds, 600);
sampleTimingInfo.decodeTimeStamp = kCMTimeInvalid;
CMSampleBufferCreateCopyWithNewTiming(kCFAllocatorDefault,
sampleBuffer,
1,
&sampleTimingInfo,
&newSampleBuffer);
finalBuffer = newSampleBuffer;
BOOL success = YES;
success = [assetWriterInput appendSampleBuffer:finalBuffer];
CFRelease(sampleBuffer);
sampleBuffer = NULL;
}
Since the time stamps of the samples are read in out of order fashion, we end up getting an error saying
"(kFigFormatWriterError_InvalidTimestamp) (decode timestamp is less than previous sample's decode timestamp)"
and the values of time stamps are -
Timestamp in milliseconds = 0.000000
Timestamp in milliseconds = 79.999924
Timestamp in milliseconds = 39.999962
Timestamp in milliseconds = 119.999886
Timestamp in milliseconds = 200.000092
Timestamp in milliseconds = 160.000137
Timestamp in milliseconds = 280.000031
Timestamp in milliseconds = 240.000061
Timestamp in milliseconds = 319.999969
Timestamp in milliseconds = 399.999908
Timestamp in milliseconds = 359.999939
and so on
Any manipulation done to the presentation stamps results in out of order reading of samples.
Looking out a way to overcome this out of order reading of timestamps. Please let know.
Thanks in advance,
Champa

Calculating the difference between durations with milliseconds in Ruby

TL;DR: I need to get the difference between HH:MM:SS.ms and HH:MM:SS.ms as HH:MM:SS:ms
What I need:
Here's a tricky one. I'm trying to calculate the difference between two timestamps such as the following:
In: 00:00:10.520
Out: 00:00:23.720
Should deliver:
Diff: 00:00:13.200
I thought I'd parse the times into actual Time objects and use the difference there. This works great in the previous case, and returns 00:0:13.200.
What doesn't work:
However, for some, this doesn't work right, as Ruby uses usec instead of msec:
In: 00:2:22.760
Out: 00:2:31.520
Diff: 00:0:8.999760
Obviously, the difference should be 00:00:8:760 and not 00:00:8.999760. I'm really tempted to just tdiff.usec.to_s.gsub('999','') ……
My code so far:
Here's my code so far (these are parsed from the input strings like "0:00:10:520").
tin_first, tin_second = ins.split(".")
tin_hours, tin_minutes, tin_seconds = tin_first.split(":")
tin_usec = tin_second * 1000
tin = Time.gm(0, 1, 1, tin_hours, tin_minutes, tin_seconds, tin_usec)
The same happens for tout. Then:
tdiff = Time.at(tout-tin)
For the output, I use:
"00:#{tdiff.min}:#{tdiff.sec}.#{tdiff.usec}"
Is there any faster way to do this? Remember, I just want to have the difference between two times. What am I missing?
I'm using Ruby 1.9.3p6 at the moment.
Using Time:
require 'time' # Needed for Time.parse
def time_diff(time1_str, time2_str)
t = Time.at( Time.parse(time2_str) - Time.parse(time1_str) )
(t - t.gmt_offset).strftime("%H:%M:%S.%L")
end
out_time = "00:00:24.240"
in_time = "00:00:14.520"
p time_diff(in_time, out_time)
#=> "00:00:09.720"
Here's a solution that doesn't rely on Time:
def slhck_diff( t1, t2 )
ms_to_time( time_as_ms(t2) - time_as_ms(t1) )
end
# Converts "00:2:22.760" to 142760
def time_as_ms( time_str )
re = /(\d+):(\d+):(\d+)(?:\.(\d+))?/
parts = time_str.match(re).to_a.map(&:to_i)
parts[4]+(parts[3]+(parts[2]+parts[1]*60)*60)*1000
end
# Converts 142760 to "00:02:22.760"
def ms_to_time(ms)
m = ms.floor / 60000
"%02i:%02i:%06.3f" % [ m/60, m%60, ms/1000.0 % 60 ]
end
t1 = "00:00:10.520"
t2 = "01:00:23.720"
p slhck_diff(t1,t2)
#=> "01:00:13.200"
t1 = "00:2:22.760"
t2 = "00:2:31.520"
p slhck_diff(t1,t2)
#=> "00:00:08.760"
I figured the following could work:
out_time = "00:00:24.240"
in_time = "00:00:14.520"
diff = Time.parse(out_time) - Time.parse(in_time)
Time.at(diff).strftime("%H:%M:%S.%L")
# => "01:00:09.720"
It does print 01 for the hour, which I don't really understand.
In the meantime, I used:
Time.at(diff).strftime("00:%M:%S.%L")
# => "00:00:09.720"
Any answer that does this better will get an upvote or the accept, of course.
in_time = "00:02:22.760"
out_time = "00:02:31.520"
diff = (Time.parse(out_time) - Time.parse(in_time))*1000
puts diff
OUTPUT:
8760.0 millliseconds
Time.parse(out_time) - Time.parse(in_time) gives the result in seconds so multiplied by 1000 to convert into milliseconds.

Fast editing subtitles file

I like GNU/Linux and writing bash scripts to automatize my tasks. But I am a beginner and have a lot of problems with it. So, I have a subtitle file in format like I this(I'm Polish so it's a Polish subtitles):
00:00:27:W zamierzchłych czasach|ziemia pokryta była lasami.
00:00:31:Od wieków mieszkały|w nich duchy bogów.
00:00:37:Człowiek żył w harmonii ze zwierzętami.
I thing you understanding this simple format. The problem is that in the "movie file", before the movie starts is 1:15 of introduction. I want to add to each subtitle file's line 1:15. So the example should look like this:
00:01:43:W zamierzchłych czasach|ziemia pokryta była lasami.
00:01:46:Od wieków mieszkały|w nich duchy bogów.
00:01:52:Człowiek żył w harmonii ze zwierzętami.
Could you help me to write this script?
BTW I'm Polish and I'm still learning English. So if you cannot understand me, write.
Here's a solution in awk - probably easier than bash for this kind of problem:
#!/usr/bin/awk -f
BEGIN {
FS=":"
}
{
hr = $1
min = $2
sec = $3
sec = sec + 15
if (sec >= 60) {
sec = sec - 60
min = min + 1
}
min = min + 1
if (min >= 60) {
min = min - 60
hr = hr + 1
}
printf "%02d:%02d:%02d:%s\n", hr, min, sec, $4
}
Suggestions for improvement welcome!

Resources