12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394open!Core_kernelopen!ImportmoduleF0=structopenFuncallletfloat_time="float-time"<:Value.Type.value@->returnfloatendincludeValue.Make_subtype(structletname="time"lethere=[%here]letis_in_subtypevalue=matchF0.float_timevaluewith|exception_->false|(_:float)->true;;end)lett=type_letformat_time_string=Funcall.("format-time-string"<:string@->t@->returnstring)letformatt~format_string=format_time_stringformat_stringtletsexp_of_tt=[%sexp(formatt~format_string:"%F %T.%N%z":string)]let(<)=Funcall.("time-less-p"<:t@->t@->returnbool)let(>)t1t2=t2<t1letcomparet1t2=ift1<t2then-1elseift1>t2then1else0letof_time_nstime_ns=tryletnanos=time_ns|>Time_ns.to_int_ns_since_epochinletnegate,nanos=ifInt.(<)nanos0thentrue,-nanoselsefalse,nanosinletsub_micro_nanos=nanos%1_000inletpicos=sub_micro_nanos*1_000inletsec_and_micros=(nanos-sub_micro_nanos)/1_000inletmicros=sec_and_micros%1_000_000inletsec=(sec_and_micros-micros)/1_000_000inletsec_low=secland0xFFFFinletsec_high=(sec-sec_low)lsr16in(ifnegatethen[-sec_high;-sec_low;-micros;-picos]else[sec_high;sec_low;micros;picos])|>Value.Type.(listint|>to_value)|>of_value_exnwith|exn->raise_s[%message"[Elisp_time.of_time_ns]"(time_ns:Time_ns.Alternate_sexp.t)~error:(exn:exn)];;letmin_time_ns_value=lazy(of_time_nsTime_ns.min_value_for_1us_rounding)letmax_time_ns_value=lazy(of_time_nsTime_ns.max_value_for_1us_rounding)letunexpected_time_valuevalue=raise_s[%message"[Elisp_time] got unexpected time value"(value:Value.t)];;letto_int_ns_since_epoch_exnt=letmin_time_ns_value=forcemin_time_ns_valueinletmax_time_ns_value=forcemax_time_ns_valueinift<min_time_ns_valuethenraise_s[%message"[Elisp_time.to_int_ns_since_epoch] got too small time"~_:(t:t)(min_time_ns_value:t)];ift>max_time_ns_valuethenraise_s[%message"[Elisp_time.to_int_ns_since_epoch] got too large time"~_:(t:t)(max_time_ns_value:t)];letvalue=t|>to_valueinifValue.is_integervaluethen1_000_000_000*(value|>Value.to_int_exn)elseifValue.is_floatvaluethenFloat.iround_nearest_exn(1e9*.(value|>Value.to_float_exn))else(letsec_high,sec_low,micros,picos=matchvalue|>Value.Type.(listint|>of_value_exn)with|exception_->unexpected_time_valuevalue|[sec_high]->sec_high,0,0,0|[sec_high;sec_low]->sec_high,sec_low,0,0|[sec_high;sec_low;micros]->sec_high,sec_low,micros,0|[sec_high;sec_low;micros;picos]->sec_high,sec_low,micros,picos|_->unexpected_time_valuevaluein(((sec_highlsl16)+sec_low)*1_000_000_000)+(micros*1_000)+(picos/1_000));;letto_time_ns_exnt=t|>to_int_ns_since_epoch_exn|>Time_ns.of_int_ns_since_epoch