{"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":"en","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,"last_verified":"2026-04-09T00:00:00.000Z","next_check":"2026-07-08T00:00:00.000Z"}