code: def datetime_attribute_timeseries(
      time_index: Union[pd.DatetimeIndex, TimeSeries],
      attribute: str,
      one_hot: bool = False,
      cyclic: bool = False,
      until: Optional[Union[int, str, pd.Timestamp]] = None,
      add_length: int = 0,
      dtype=np.float64,
      with_columns: Optional[Union[List[str], str]] = None,
      tz: Optional[str] = None,
  ) -> TimeSeries:
      """
      Returns a new TimeSeries with index `time_index` and one or more dimensions containing
      (optionally one-hot encoded or cyclic encoded) pd.DatatimeIndex attribute information derived from the index.
  
  
      Parameters
      ----------
      time_index
          Either a `pd.DatetimeIndex` attribute which will serve as the basis of the new column(s), or
          a `TimeSeries` whose time axis will serve this purpose.
      attribute
          An attribute of `pd.DatetimeIndex`, or `week` / `weekofyear` / `week_of_year` - e.g. "month", "weekday", "day",
          "hour", "minute", "second". See all available attributes in
          https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DatetimeIndex.html#pandas.DatetimeIndex.
      one_hot
          Boolean value indicating whether to add the specified attribute as a one hot encoding
          (results in more columns).
      cyclic
          Boolean value indicating whether to add the specified attribute as a cyclic encoding.
          Alternative to one_hot encoding, enable only one of the two.
          (adds 2 columns, corresponding to sin and cos transformation)
      until
          Extend the time_index up until timestamp for datetime indexed series
          and int for range indexed series, should match or exceed forecasting window.
      add_length
          Extend the time_index by add_length, should match or exceed forecasting window.
          Set only one of until and add_length.
      dtype
          The desired NumPy dtype (np.float32 or np.float64) for the resulting series
      with_columns
          Optionally, specify the output component names.
          * If `one_hot` and `cyclic` are ``False``, must be a string
          * If `cyclic` is ``True``, must be a list of two strings. The first string for the sine, the second for the
              cosine component name.
          * If `one_hot` is ``True``, must be a list of strings of the same length as the generated one hot encoded
              features.
      tz
          Optionally, a time zone to convert the time index to before computing the attributes.
  
      Returns
      -------
      TimeSeries
          New datetime attribute TimeSeries instance.
      """
  
      time_index_ts, time_index = _process_time_index(
          time_index=time_index,
          tz=tz,
          until=until,
          add_length=add_length,
      )
  
      raise_if_not(
          hasattr(pd.DatetimeIndex, attribute)
          or (attribute in ["week", "weekofyear", "week_of_year"]),
          f"attribute `{attribute}` needs to be an attribute of pd.DatetimeIndex. "
          "See all available attributes in "
          "https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DatetimeIndex.html#pandas.DatetimeIndex",
          logger,
      )
  
      raise_if(
          one_hot and cyclic,
          "set only one of one_hot or cyclic to true",
          logger,
      )
  
      num_values_dict = {
          "month": 12,
          "day": 31,
          "weekday": 7,
          "dayofweek": 7,
          "day_of_week": 7,
          "hour": 24,
          "minute": 60,
          "second": 60,
          "microsecond": 1000000,
          "nanosecond": 1000,
          "quarter": 4,
          "dayofyear": 365,
          "day_of_year": 365,
          "week": 52,
          "weekofyear": 52,
          "week_of_year": 52,
      }
  
      if attribute not in ["week", "weekofyear", "week_of_year"]:
          values = getattr(time_index, attribute)
      else:
          values = (
              time_index.isocalendar()
              .set_index("week")
              .index.astype("int64")
              .rename("time")
          )
  
      if one_hot or cyclic:
          raise_if_not(
              attribute in num_values_dict,
              f"Given datetime attribute `{attribute}` not supported with one-hot or cyclical encoding. "
              f"Supported datetime attribute: {list(num_values_dict.keys())}",
              logger,
          )
  
      if one_hot:
          values_df = pd.get_dummies(values)
          # fill missing columns (in case not all values appear in time_index)
          for i in range(1, num_values_dict[attribute] + 1):
              if not (i in values_df.columns):
                  values_df[i] = 0
          values_df = values_df[
              range(1, num_values_dict[attribute] + 1)
          ]
  
          if with_columns is None:
              with_columns = [
                  attribute + "_" + str(column_name)
                  for column_name in values_df.columns
              ]
  
          raise_if_not(
              len(with_columns) == len(values_df.columns),
              "For the given case with `one_hot=True`,`with_columns` must be a list of strings of length "
              f"{values_df.columns}.",
              logger=logger,
          )
  
          values_df.columns = with_columns
      else:
          if cyclic:
              if attribute == "day":
                  periods = time_index.days_in_month.values
                  freq = (
                      2 * np.pi * np.reciprocal(periods.astype(dtype))
                  )
              else:
                  period = num_values_dict[attribute]
                  freq = 2 * np.pi / period
  
              if with_columns is None:
                  with_columns = [
                      attribute + "_sin",
                      attribute + "_cos",
                  ]
  
              raise_if(
                  len(with_columns) != 2,
                  "`with_columns` must be a list of two strings when `cyclic=True`. "
                  "The first string for the sine component name, the second for the cosine component name.",
                  logger=logger,
              )
              values_df = pd.DataFrame(
                  {
                      with_columns[0]: np.sin(freq * values),
                      with_columns[1]: np.cos(freq * values),
                  }
              )
          else:
              if with_columns is None:
                  with_columns = attribute
              raise_if_not(
                  isinstance(with_columns, str),
                  "`with_columns` must be a string specifying the output component name.",
                  logger=logger,
              )
              values_df = pd.DataFrame({with_columns: values})
  
      values_df.index = time_index_ts
      return TimeSeries.from_dataframe(values_df).astype(dtype)
  
file_path: darts/darts/utils/timeseries_generation.py
imports: import math
  from typing import List, Optional, Sequence, Tuple, Union
  import holidays
  import numpy
  import pandas
  from darts import TimeSeries
  from darts.logging import get_logger, raise_if, raise_if_not, raise_log
label_desc: Use image node_id 10 for calling a global function with example usage: datetime_attribute_timeseries(time_index, attribute, one_hot, cyclic, until, add_length, dtype, with_columns, tz) and returns: TimeSeries