DivFloat returns a Duration representing a time length of d/x.
(x float64)
| 843 | |
| 844 | // DivFloat returns a Duration representing a time length of d/x. |
| 845 | func (d Duration) DivFloat(x float64) Duration { |
| 846 | // Have a couple of special cases to avoid rounding errors with very large |
| 847 | // intervals. |
| 848 | // TODO(#26932): once we correctly error out on intervals out of range, this |
| 849 | // could be removed. |
| 850 | switch x { |
| 851 | case 1: |
| 852 | return d |
| 853 | case -1: |
| 854 | return MakeDuration(-d.nanos, -d.Days, -d.Months) |
| 855 | } |
| 856 | // In order to keep it compatible with PostgreSQL, we use the same logic. |
| 857 | // Refer to https://github.com/postgres/postgres/blob/e56bce5d43789cce95d099554ae9593ada92b3b7/src/backend/utils/adt/timestamp.c#L3266-L3304. |
| 858 | month := int32(float64(d.Months) / x) |
| 859 | day := int32(float64(d.Days) / x) |
| 860 | |
| 861 | remainderDays := (float64(d.Months)/x - float64(month)) * DaysPerMonth |
| 862 | remainderDays = secRoundToEven(remainderDays) |
| 863 | secRemainder := (float64(d.Days)/x - float64(day) + |
| 864 | remainderDays - float64(int64(remainderDays))) * SecsPerDay |
| 865 | secRemainder = secRoundToEven(secRemainder) |
| 866 | if math.Abs(secRemainder) >= SecsPerDay { |
| 867 | day += int32(secRemainder / SecsPerDay) |
| 868 | secRemainder -= float64(int32(secRemainder/SecsPerDay) * SecsPerDay) |
| 869 | } |
| 870 | day += int32(remainderDays) |
| 871 | microSecs := float64(time.Duration(d.nanos).Microseconds())/x + secRemainder*MicrosPerMilli*MillisPerSec |
| 872 | retNanos := time.Duration(int64(math.RoundToEven(microSecs))) * time.Microsecond |
| 873 | |
| 874 | return MakeDuration( |
| 875 | retNanos.Nanoseconds(), |
| 876 | int64(day), |
| 877 | int64(month), |
| 878 | ) |
| 879 | } |
| 880 | |
| 881 | // secRoundToEven rounds the given float to the nearest second, |
| 882 | // assuming the input float is a microsecond representation of |
no test coverage detected