arithmetic.ha (3224B)
1 // SPDX-License-Identifier: MPL-2.0 2 // (c) Hare authors <https://harelang.org> 3 4 use time; 5 6 // Returns true if two [[moment]]s represent the same time in the same locality, 7 // which is to say that their [[locality]] and [[time::instant]] are both equal. 8 // Their observed values and representations in a chronology should be the same 9 // in all cases. 10 // 11 // See [[simultaneous]] to determine if two moments represent the same moment in 12 // time regardless of locality. 13 export fn coincident(a: *moment, b: *moment) bool = { 14 return a.loc == b.loc && a.sec == b.sec && a.nsec == b.nsec; 15 }; 16 17 // Returns true if two [[moment]]s represent the same moment in time, regardless 18 // of locality. 19 // 20 // The moments are compared as [[time::instant]]s; their observed chronological 21 // values and representations are ignored. 22 // 23 // If the moments' associated [[timescale]]s are different, they will be 24 // converted to [[tai]] instants first. Any [[discontinuity]] occurence will be 25 // returned. If a discontinuity against TAI amongst the two timescales exist, 26 // consider converting such instants manually. 27 // 28 // See [[coincident]] to determine if two [[moment]]s are equal with respect to 29 // both time and locality. 30 export fn simultaneous(a: *moment, b: *moment) (bool | discontinuity) = { 31 return 0 == compare(a, b)?; 32 }; 33 34 // Compares two [[moment]]s. Returns -1 if a precedes b, 0 if a and b are 35 // simultaneous, or +1 if b precedes a. 36 // 37 // The moments are compared as [[time::instant]]s; their observed chronological 38 // values are ignored. 39 // 40 // If the moments' associated [[timescale]]s are different, they will be 41 // converted to [[tai]] instants first. Any [[discontinuity]] occurence will be 42 // returned. If a discontinuity against TAI amongst the two timescales exist, 43 // consider converting such instants manually. 44 export fn compare(a: *moment, b: *moment) (i8 | discontinuity) = { 45 const (ia, ib) = convertpair(a, b)?; 46 return time::compare(ia, ib); 47 }; 48 49 // Returns the [[time::duration]] between two [[moment]]s, from a to b. 50 // 51 // The moments are compared as [[time::instant]]s; their observed chronological 52 // values are ignored. 53 // 54 // If the moments' associated [[timescale]]s are different, they will be 55 // converted to [[tai]] instants first. Any [[discontinuity]] occurence will be 56 // returned. If a discontinuity against TAI amongst the two timescales exist, 57 // consider converting such instants manually. 58 export fn diff(a: *moment, b: *moment) (time::duration | discontinuity) = { 59 const (ia, ib) = convertpair(a, b)?; 60 return time::diff(ia, ib); 61 }; 62 63 // Adds a [[time::duration]] to a [[moment]] with [[time::add]]. 64 export fn add(m: *moment, x: time::duration) moment = { 65 return new(m.loc, time::add(*(m: *time::instant), x)); 66 }; 67 68 fn convertpair( 69 a: *moment, 70 b: *moment, 71 ) ((time::instant, time::instant) | discontinuity) = { 72 let ia = *(a: *time::instant); 73 let ib = *(b: *time::instant); 74 75 if (a.loc.timescale != b.loc.timescale) { 76 match (convert(ia, a.loc.timescale, &tai)) { 77 case let i: time::instant => 78 ia = i; 79 case => 80 return discontinuity; 81 }; 82 83 match (convert(ib, b.loc.timescale, &tai)) { 84 case let i: time::instant => 85 ib = i; 86 case => 87 return discontinuity; 88 }; 89 }; 90 91 return (ia, ib); 92 };