{"id":1957,"library":"cftime","title":"cftime - CF-Compliant Time Handling","description":"cftime is a Python library providing functionality for decoding time units and variable values in netCDF files that conform to the Climate and Forecasting (CF) conventions. It extends Python's standard datetime module to support various non-standard calendars commonly used in climate science, such as 'noleap', '365_day', '360_day', and 'julian'. The current version is 1.6.5, and the library maintains an active development and release cadence.","status":"active","version":"1.6.5","language":"python","source_language":"en","source_url":"https://github.com/Unidata/cftime","tags":["datetime","netcdf","climate","geoscience","cf-conventions","calendar","time-series"],"install":[{"cmd":"pip install cftime","lang":"bash","label":"Install with pip"}],"dependencies":[{"reason":"Required for array operations and core date/time representations.","package":"numpy","optional":false},{"reason":"Used for compiling performance-critical C extensions; required for building from source.","package":"Cython","optional":true}],"imports":[{"symbol":"datetime","correct":"from cftime import datetime"},{"symbol":"num2date","correct":"from cftime import num2date"},{"symbol":"date2num","correct":"from cftime import date2num"},{"note":"num2date now returns cftime.datetime by default since v1.1.0; use num2pydate for native python datetime objects.","wrong":"from cftime import num2date; # if expecting python datetime objects","symbol":"num2pydate","correct":"from cftime import num2pydate"}],"quickstart":{"code":"import cftime\nimport numpy as np\n\n# Create a cftime.datetime object with a specific calendar\ndate_obj = cftime.datetime(2000, 2, 29, 12, 0, 0, calendar='gregorian')\nprint(f\"Created cftime.datetime (Gregorian): {date_obj}\")\n\n# Convert to a numeric representation (e.g., 'days since 2000-01-01')\nunits = \"days since 2000-01-01\"\nnumeric_time = cftime.date2num(date_obj, units=units, calendar=date_obj.calendar)\nprint(f\"Numeric time ({units}): {numeric_time}\")\n\n# Convert back to a cftime.datetime object\nreconstructed_date = cftime.num2date(numeric_time, units=units, calendar=date_obj.calendar)\nprint(f\"Reconstructed cftime.datetime: {reconstructed_date}\")\n\n# Example with a non-standard calendar (360_day has Feb 30)\ndate_360_day = cftime.datetime(2000, 2, 30, calendar='360_day')\nprint(f\"360-day calendar date: {date_360_day}\")","lang":"python","description":"This quickstart demonstrates how to create `cftime.datetime` objects, convert them to numeric representations using `date2num`, and convert numeric times back to `cftime.datetime` objects using `num2date`, showcasing different calendar types."},"warnings":[{"fix":"If you require standard `python datetime` objects, use the `cftime.num2pydate` function instead. Otherwise, update your code to expect `cftime.datetime` objects.","message":"Since `cftime` v1.1.0, `cftime.num2date` defaults to returning `cftime.datetime` instances for all calendars. Previously, it would return standard `python datetime` objects when possible.","severity":"breaking","affected_versions":">=1.1.0"},{"fix":"Always explicitly specify the `calendar` argument in `cftime.date2num` calls to ensure consistent behavior, e.g., `cftime.date2num(dates, units, calendar='gregorian')`.","message":"In `cftime` v1.2.0, the default `calendar` argument for `cftime.date2num` changed from `'standard'` to `None`. This means the calendar is now inferred from the input `datetime` object(s).","severity":"breaking","affected_versions":">=1.2.0"},{"fix":"Replace usage of `JulianDayFromDate` and `DateFromJulianFromDate` with `cftime.datetime.toordinal` and `cftime.datetime.fromordinal` respectively. `cftime.utime` no longer has a direct replacement and refactoring may be needed based on its specific usage.","message":"The legacy functions `cftime.utime`, `cftime.JulianDayFromDate`, and `cftime.DateFromJulianDay` were removed in v1.5.0.","severity":"breaking","affected_versions":">=1.5.0"},{"fix":"Prefer using the base `cftime.datetime` class with the `calendar` keyword argument, e.g., `cftime.datetime(2000, 1, 1, calendar='noleap')`.","message":"The direct use of calendar-specific subclasses (e.g., `cftime.DatetimeNoLeap`) in operations like `cftime.num2date`, `cftime.datetime.__add__`, and `cftime.datetime.__sub__` is deprecated and will be removed in a future release.","severity":"deprecated","affected_versions":">=1.4.1 (deprecation started)"},{"fix":"Be mindful of performance for very distant dates. For highly performance-sensitive applications with extreme date ranges, consider profiling and optimizing accordingly, or ensuring your time 'units' define an origin closer to your data range.","message":"Performance may degrade when performing calculations with `cftime.datetime` instances that represent dates extremely far from the 1970-01-01 reference date. This is due to the complex leap year calculations across various supported calendars.","severity":"gotcha","affected_versions":"All versions"},{"fix":"If working with historical dates that span or predate this transition and require continuous date representation (e.g., for modeling without a break), use the 'proleptic_gregorian' calendar which applies the Gregorian rules universally and avoids this gap.","message":"The 'standard' calendar explicitly marks dates between October 5 and October 14, 1582, as invalid. These dates are skipped to account for the historical Julian-to-Gregorian calendar transition.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"search_vec":"'1.6.5':65 '360':57 '365':55 'activ':71 'cadenc':75 'calendar':46,83 'cf':3,31,81 'cf-compliant':2 'cf-convent':80 'cftime':1,7 'climat':28,50,78 'common':47 'compliant':4 'conform':25 'convent':32,82 'current':62 'datetim':38,76 'day':56,58 'decod':15 'develop':72 'extend':34 'file':23 'forecast':30 'function':13 'geoscienc':79 'handl':6 'julian':60 'librari':11,68 'maintain':69 'modul':39 'netcdf':22,77 'noleap':54 'non':44 'non-standard':43 'provid':12 'python':10,35 'releas':74 'scienc':51 'seri':86 'standard':37,45 'support':41 'time':5,16,85 'time-seri':84 'unit':17 'use':48 'valu':20 'variabl':19 'various':42 'version':63","created_at":"2026-04-09T18:37:24.141043+00:00","updated_at":"2026-04-16T01:51:21.377130+00:00","problems":[{"fix":"Install the necessary build tools and Python development headers. For Debian/Ubuntu-based systems: `sudo apt-get update && sudo apt-get install python3-dev gcc`. For systems using Anaconda/Miniconda, use `conda install cftime` which provides pre-compiled binaries.","cause":"This error typically occurs during installation on Linux systems when the required C/C++ compilers (like gcc) and Python development headers are missing, which are necessary to compile `cftime`'s C extensions.","error":"Failed building wheel for cftime"},{"fix":"For standard calendar types, ensure the `cftime.datetime` object is calendar-aware and try `cftime.datetime`'s own arithmetic or conversion methods. For non-standard calendars, it's often best to convert the `cftime.datetime` object to a numerical representation (e.g., days/seconds since an epoch) for arithmetic operations, and then convert back to a `cftime.datetime` object.","cause":"Direct arithmetic operations with `datetime.timedelta` are not universally supported by all `cftime.datetime` calendar types, especially non-standard ones, as `datetime.timedelta` assumes a standard Gregorian-like calendar system. The `cftime.datetime` instances are calendar-aware and require specific methods for time arithmetic.","error":"TypeError: unsupported operand type(s) for +: 'cftime._cftime.DatetimeNoLeap' and 'datetime.timedelta'"},{"fix":"If a native `datetime.datetime` object is absolutely required, you must first convert the `cftime.datetime` object to a compatible calendar (e.g., 'standard' or 'proleptic_gregorian') if the conversion is meaningful for your data, or manually extract its components (year, month, day, etc.) and handle them separately. The `cftime.num2pydate` function can convert `cftime.datetime` objects to Python `datetime` objects if the calendar is compatible.","cause":"Python's native `datetime.datetime` objects only support standard Gregorian and Julian calendars. `cftime.datetime` instances representing non-standard calendars (like '360_day', 'noleap', '365_day') cannot be directly converted to `datetime.datetime` because the native Python object lacks the capability to represent these calendar systems.","error":"TypeError: <class 'cftime._cftime.Datetime360Day'> is not convertible to datetime"},{"fix":"Use one of the valid CF-compliant calendar strings. The supported calendars are: `'standard'`, `'gregorian'`, `'proleptic_gregorian'`, `'noleap'`, `'365_day'`, `'360_day'`, `'julian'`, `'all_leap'`, `'366_day'`.","cause":"This error occurs when the `calendar` argument provided to `cftime.datetime` or related functions does not match one of the predefined and supported CF-compliant calendar strings.","error":"ValueError: given calendar 'invalid_calendar_name' is not a supported calendar"}],"ecosystem":"pypi","meta_description":null,"install_score":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":"1.6.5","cli_name":"","cli_version":null,"type":"library","homepage":null,"github":null,"docs":null,"changelog":null,"pypi":"https://pypi.org/project/cftime/","npm":null,"openapi_spec":null,"status_page":null,"smithery":null,"categories":["data","serialization"],"base_url":null,"auth_type":null,"provenance":{"verified_status":"passing","verified_at":"2026-06-28","last_verified":"2026-08-28","next_check":"2026-07-28","install_tag":null}}