Take the input number, assume it represents a fractional count of days. Convert it to a count of microseconds.
| 13949 | // Take the input number, assume it represents a fractional count of days. |
| 13950 | // Convert it to a count of microseconds. |
| 13951 | static SINT64 getDayFraction(const dsc* d) |
| 13952 | { |
| 13953 | dsc result; |
| 13954 | double result_days; |
| 13955 | thread_db* tdbb = JRD_get_thread_data(); |
| 13956 | |
| 13957 | result.dsc_dtype = dtype_double; |
| 13958 | result.dsc_scale = 0; |
| 13959 | result.dsc_flags = 0; |
| 13960 | result.dsc_sub_type = 0; |
| 13961 | result.dsc_length = sizeof(double); |
| 13962 | result.dsc_address = reinterpret_cast<UCHAR*>(&result_days); |
| 13963 | |
| 13964 | // Convert the input number to a double |
| 13965 | CVT_move(d, &result, tdbb->getAttachment()->att_dec_status); |
| 13966 | |
| 13967 | if (fb_utils::abs64Compare(result_days, TimeStamp::MAX_DATE - TimeStamp::MIN_DATE) > 0) |
| 13968 | ERR_post(Arg::Gds(isc_date_range_exceeded)); |
| 13969 | |
| 13970 | // There's likely some loss of precision here due to rounding of number |
| 13971 | |
| 13972 | // 08-Apr-2004, Nickolay Samofatov. Loss of precision manifested itself as bad |
| 13973 | // result returned by the following query: |
| 13974 | // |
| 13975 | // select (cast('01.01.2004 10:01:00' as timestamp) |
| 13976 | // -cast('01.01.2004 10:00:00' as timestamp)) |
| 13977 | // +cast('01.01.2004 10:00:00' as timestamp) from rdb$database |
| 13978 | // |
| 13979 | // Let's use llrint where it is supported and offset number for other platforms |
| 13980 | // in hope that compiler rounding mode doesn't get in. |
| 13981 | |
| 13982 | #ifdef HAVE_LLRINT |
| 13983 | return llrint(result_days * TimeStamp::ISC_TICKS_PER_DAY); |
| 13984 | #else |
| 13985 | const double eps = 0.49999999999999; |
| 13986 | if (result_days >= 0) |
| 13987 | return (SINT64)(result_days * TimeStamp::ISC_TICKS_PER_DAY + eps); |
| 13988 | |
| 13989 | return (SINT64) (result_days * TimeStamp::ISC_TICKS_PER_DAY - eps); |
| 13990 | #endif |
| 13991 | } |
| 13992 | |
| 13993 | // Take the input value, which is either a timestamp or a string representing a timestamp. |
| 13994 | // Convert it to a timestamp, and then return that timestamp as a count of isc_ticks since the base |
no test coverage detected