1// Copyright (C) 2018 The Android Open Source Project 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15import {assertTrue} from '../base/logging'; 16 17// TODO(hjd): Combine with timeToCode. 18export function timeToString(sec: number) { 19 const units = ['s', 'ms', 'us', 'ns']; 20 const sign = Math.sign(sec); 21 let n = Math.abs(sec); 22 let u = 0; 23 while (n < 1 && n !== 0 && u < units.length - 1) { 24 n *= 1000; 25 u++; 26 } 27 return `${sign < 0 ? '-' : ''}${Math.round(n * 10) / 10} ${units[u]}`; 28} 29 30export function fromNs(ns: number) { 31 return ns / 1e9; 32} 33 34 35// 1000000023ns -> "1.000 000 023" 36export function formatTimestamp(sec: number) { 37 const parts = sec.toFixed(9).split('.'); 38 parts[1] = parts[1].replace(/\B(?=(\d{3})+(?!\d))/g, ' '); 39 return parts.join('.'); 40} 41 42// TODO(hjd): Rename to formatTimestampWithUnits 43// 1000000023ns -> "1s 23ns" 44export function timeToCode(sec: number) { 45 let result = ''; 46 let ns = Math.round(sec * 1e9); 47 if (ns < 1) return '0s'; 48 const unitAndValue = [ 49 ['m', 60000000000], 50 ['s', 1000000000], 51 ['ms', 1000000], 52 ['us', 1000], 53 ['ns', 1] 54 ]; 55 unitAndValue.forEach(pair => { 56 const unit = pair[0] as string; 57 const val = pair[1] as number; 58 if (ns >= val) { 59 const i = Math.floor(ns / val); 60 ns -= i * val; 61 result += i.toLocaleString() + unit + ' '; 62 } 63 }); 64 return result.slice(0, -1); 65} 66 67export class TimeSpan { 68 readonly start: number; 69 readonly end: number; 70 71 constructor(start: number, end: number) { 72 assertTrue(start <= end); 73 this.start = start; 74 this.end = end; 75 } 76 77 clone() { 78 return new TimeSpan(this.start, this.end); 79 } 80 81 equals(other: TimeSpan) { 82 return this.start === other.start && this.end === other.end; 83 } 84 85 get duration() { 86 return this.end - this.start; 87 } 88 89 isInBounds(sec: number) { 90 return this.start <= sec && sec <= this.end; 91 } 92 93 add(sec: number): TimeSpan { 94 return new TimeSpan(this.start + sec, this.end + sec); 95 } 96} 97