Mantid
Loading...
Searching...
No Matches
DateAndTime.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
10#include <boost/python.hpp>
11#include <memory>
12
13#define PY_ARRAY_UNIQUE_SYMBOL CORE_ARRAY_API
14#define NO_IMPORT_ARRAY
15#include <numpy/arrayobject.h>
16#include <numpy/arrayscalars.h>
17
19using Mantid::Types::Core::DateAndTime;
20
21namespace {
22// there is a different EPOCH for DateAndTime vs npy_datetime
23const npy_datetime UNIX_EPOCH_NS = DateAndTime("1970-01-01T00:00").totalNanoseconds();
24} // namespace
25
27
28npy_datetime to_npy_datetime(const DateAndTime &dateandtime) {
29 return static_cast<npy_datetime>(dateandtime.totalNanoseconds()) - UNIX_EPOCH_NS;
30}
31
32PyObject *to_datetime64(const DateAndTime &dateandtime) {
33 npy_datetime abstime = to_npy_datetime(dateandtime);
34 PyObject *ret = PyArray_Scalar(reinterpret_cast<char *>(&abstime), descr_ns(), nullptr);
35
36 return ret;
37}
38
39/* datetime64[ns] from 64bit integer - numpy's interface requires this to be
40 * non-const
41 * The parts of the string are
42 * M = NPY_DATETIMELTR
43 * 8 = 8 bit datasize because npy_datetime is a typedef for int64_t
44 * [ns] = units description for nanosecond resolution
45 */
46PyArray_Descr *descr_ns() { return func_PyArray_Descr("M8[ns]"); }
47
48// internal function that handles raw pointer
49std::shared_ptr<Types::Core::DateAndTime> to_dateandtime(const PyObject *datetime) {
50 GNU_DIAG_OFF("cast-qual")
51 if (!PyArray_IsScalar(datetime, Datetime)) {
52 GNU_DIAG_ON("cast-qual")
53 throw std::runtime_error("Expected datetime64");
54 }
55
56 const auto *npdatetime = reinterpret_cast<const PyDatetimeScalarObject *>(datetime);
57 npy_datetime value = npdatetime->obval;
58
59 // DateAndTime only understands nanoseconds
60 switch (npdatetime->obmeta.base) {
61 case NPY_FR_m: // minutes
62 value *= 60000000000;
63 break;
64 case NPY_FR_s: // second
65 value *= 1000000000;
66 break;
67 case NPY_FR_ms: // milli-second
68 value *= 1000000;
69 break;
70 case NPY_FR_us: // micro-second
71 value *= 1000;
72 break;
73 case NPY_FR_ns: // nanosecond
74 break;
75 default:
76 throw std::runtime_error("Not implemented time unit");
77 } // units
78 return std::make_shared<DateAndTime>(UNIX_EPOCH_NS + value);
79}
80
81std::shared_ptr<Types::Core::DateAndTime> to_dateandtime(const boost::python::api::object &value) {
82 boost::python::extract<Types::Core::DateAndTime> converter_dt(value);
83 if (converter_dt.check()) {
84 return std::make_shared<DateAndTime>(converter_dt());
85 }
86
87 boost::python::extract<std::string> converter_str(value);
88 if (converter_str.check()) {
89 return std::make_shared<DateAndTime>(converter_str());
90 }
91
92 boost::python::extract<double> converter_dbl(value);
93 if (converter_dbl.check()) {
94 return std::make_shared<DateAndTime>(static_cast<int64_t>(converter_dbl()));
95 }
96
97 boost::python::extract<int64_t> converter_int64(value);
98 if (converter_int64.check()) {
99 return std::make_shared<DateAndTime>(converter_int64());
100 }
101
102 boost::python::extract<int64_t> converter_int32(value);
103 if (converter_int32.check()) {
104 return std::make_shared<DateAndTime>(converter_int32());
105 }
106
107 // assume it is a numpy.datetime64
108 return to_dateandtime(value.ptr());
109}
110
111} // namespace Mantid::PythonInterface::Converters
double value
The value of the point.
Definition: FitMW.cpp:51
_PyArray_Descr PyArray_Descr
#define GNU_DIAG_ON(x)
#define GNU_DIAG_OFF(x)
This is a collection of macros for turning compiler warnings off in a controlled manner.
MANTID_PYTHONINTERFACE_CORE_DLL PyArray_Descr * func_PyArray_Descr(const char *datadescr)
MANTID_PYTHONINTERFACE_CORE_DLL PyArray_Descr * descr_ns()
Definition: DateAndTime.cpp:46
MANTID_PYTHONINTERFACE_CORE_DLL std::shared_ptr< Types::Core::DateAndTime > to_dateandtime(const boost::python::api::object &value)
Definition: DateAndTime.cpp:81
MANTID_PYTHONINTERFACE_CORE_DLL PyObject * to_datetime64(const Types::Core::DateAndTime &dateandtime)
Convert to numpy's datetime64. This is panda's name for the function.
MANTID_PYTHONINTERFACE_CORE_DLL npy_datetime to_npy_datetime(const Types::Core::DateAndTime &dateandtime)
Total nanoseconds since the unix epoch.