diff --git a/libraries/Zigbee/examples/Zigbee_Temperature_Sensor/Zigbee_Temperature_Sensor.ino b/libraries/Zigbee/examples/Zigbee_Temperature_Sensor/Zigbee_Temperature_Sensor.ino
index 27aa2db97bd..ad007abbbaa 100644
--- a/libraries/Zigbee/examples/Zigbee_Temperature_Sensor/Zigbee_Temperature_Sensor.ino
+++ b/libraries/Zigbee/examples/Zigbee_Temperature_Sensor/Zigbee_Temperature_Sensor.ino
@@ -36,6 +36,11 @@
 #define TEMP_SENSOR_ENDPOINT_NUMBER 10
 uint8_t button = BOOT_PIN;
 
+// Optional Time cluster variables
+struct tm timeinfo;
+struct tm *localTime;
+int32_t timezone;
+
 ZigbeeTempSensor zbTempSensor = ZigbeeTempSensor(TEMP_SENSOR_ENDPOINT_NUMBER);
 
 /************************ Temp sensor *****************************/
@@ -66,6 +71,9 @@ void setup() {
   // Optional: Set tolerance for temperature measurement in °C (lowest possible value is 0.01°C)
   zbTempSensor.setTolerance(1);
 
+  // Optional: Time cluster configuration (default params, as this device will revieve time from coordinator)
+  zbTempSensor.addTimeCluster();
+
   // Add endpoint to Zigbee Core
   Zigbee.addEndpoint(&zbTempSensor);
 
@@ -85,6 +93,19 @@ void setup() {
   }
   Serial.println();
 
+  // Optional: If time cluster is added, time can be read from the coordinator
+  timeinfo = zbTempSensor.getTime();
+  timezone = zbTempSensor.getTimezone();
+
+  Serial.println("UTC time:");
+  Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
+
+  time_t local = mktime(&timeinfo) + timezone;
+  localTime = localtime(&local);
+
+  Serial.println("Local time with timezone:");
+  Serial.println(localTime, "%A, %B %d %Y %H:%M:%S");
+
   // Start Temperature sensor reading task
   xTaskCreate(temp_sensor_value_update, "temp_sensor_update", 2048, NULL, 10, NULL);
 
diff --git a/libraries/Zigbee/examples/Zigbee_Thermostat/Zigbee_Thermostat.ino b/libraries/Zigbee/examples/Zigbee_Thermostat/Zigbee_Thermostat.ino
index a4720feeba4..7cdf45ef711 100644
--- a/libraries/Zigbee/examples/Zigbee_Thermostat/Zigbee_Thermostat.ino
+++ b/libraries/Zigbee/examples/Zigbee_Thermostat/Zigbee_Thermostat.ino
@@ -45,6 +45,8 @@ float sensor_max_temp;
 float sensor_min_temp;
 float sensor_tolerance;
 
+struct tm timeinfo = {};  // Time structure for Time cluster
+
 /****************** Temperature sensor handling *******************/
 void recieveSensorTemp(float temperature) {
   Serial.printf("Temperature sensor value: %.2f°C\n", temperature);
@@ -71,6 +73,19 @@ void setup() {
   //Optional: set Zigbee device name and model
   zbThermostat.setManufacturerAndModel("Espressif", "ZigbeeThermostat");
 
+  //Optional Time cluster configuration
+  //example time January 13, 2025 13:30:30 CET
+  timeinfo.tm_year = 2025 - 1900;  // = 2025
+  timeinfo.tm_mon = 0;             // January
+  timeinfo.tm_mday = 13;           // 13th
+  timeinfo.tm_hour = 12;           // 12 hours - 1 hour (CET)
+  timeinfo.tm_min = 30;            // 30 minutes
+  timeinfo.tm_sec = 30;            // 30 seconds
+  timeinfo.tm_isdst = -1;
+
+  // Set time and gmt offset (timezone in seconds -> CET = +3600 seconds)
+  zbThermostat.addTimeCluster(timeinfo, 3600);
+
   //Add endpoint to Zigbee Core
   Zigbee.addEndpoint(&zbThermostat);
 
diff --git a/libraries/Zigbee/src/ZigbeeEP.cpp b/libraries/Zigbee/src/ZigbeeEP.cpp
index adc87540b83..6a2ace0b90c 100644
--- a/libraries/Zigbee/src/ZigbeeEP.cpp
+++ b/libraries/Zigbee/src/ZigbeeEP.cpp
@@ -238,4 +238,129 @@ void ZigbeeEP::zbIdentify(const esp_zb_zcl_set_attr_value_message_t *message) {
   }
 }
 
+void ZigbeeEP::addTimeCluster(tm time, int32_t gmt_offset) {
+  time_t utc_time = 0;
+
+  // Check if time is set
+  if (time.tm_year > 0) {
+    // Convert time to UTC
+    utc_time = mktime(&time);
+  }
+
+  // Create time cluster server attributes
+  esp_zb_attribute_list_t *time_cluster_server = esp_zb_zcl_attr_list_create(ESP_ZB_ZCL_CLUSTER_ID_TIME);
+  esp_zb_time_cluster_add_attr(time_cluster_server, ESP_ZB_ZCL_ATTR_TIME_TIME_ZONE_ID, (void *)&gmt_offset);
+  esp_zb_time_cluster_add_attr(time_cluster_server, ESP_ZB_ZCL_ATTR_TIME_TIME_ID, (void *)&utc_time);
+  // Create time cluster client attributes
+  esp_zb_attribute_list_t *time_cluster_client = esp_zb_zcl_attr_list_create(ESP_ZB_ZCL_CLUSTER_ID_TIME);
+  // Add time clusters to cluster list
+  esp_zb_cluster_list_add_time_cluster(_cluster_list, time_cluster_server, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
+  esp_zb_cluster_list_add_time_cluster(_cluster_list, time_cluster_client, ESP_ZB_ZCL_CLUSTER_CLIENT_ROLE);
+}
+
+void ZigbeeEP::setTime(tm time) {
+  time_t utc_time = mktime(&time);
+  esp_zb_lock_acquire(portMAX_DELAY);
+  esp_zb_zcl_set_attribute_val(_endpoint, ESP_ZB_ZCL_CLUSTER_ID_TIME, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_TIME_TIME_ID, &utc_time, false);
+  esp_zb_lock_release();
+}
+
+void ZigbeeEP::setTimezone(int32_t gmt_offset) {
+  esp_zb_lock_acquire(portMAX_DELAY);
+  esp_zb_zcl_set_attribute_val(_endpoint, ESP_ZB_ZCL_CLUSTER_ID_TIME, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_TIME_TIME_ZONE_ID, &gmt_offset, false);
+  esp_zb_lock_release();
+}
+
+tm ZigbeeEP::getTime(uint8_t endpoint, int32_t short_addr, esp_zb_ieee_addr_t ieee_addr) {
+  /* Read peer time */
+  esp_zb_zcl_read_attr_cmd_t read_req;
+
+  if (short_addr >= 0) {
+    read_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT;
+    read_req.zcl_basic_cmd.dst_addr_u.addr_short = (uint16_t)short_addr;
+  } else {
+    read_req.address_mode = ESP_ZB_APS_ADDR_MODE_64_ENDP_PRESENT;
+    memcpy(read_req.zcl_basic_cmd.dst_addr_u.addr_long, ieee_addr, sizeof(esp_zb_ieee_addr_t));
+  }
+
+  uint16_t attributes[] = {ESP_ZB_ZCL_ATTR_TIME_TIME_ID};
+  read_req.attr_number = ZB_ARRAY_LENTH(attributes);
+  read_req.attr_field = attributes;
+
+  read_req.clusterID = ESP_ZB_ZCL_CLUSTER_ID_TIME;
+
+  read_req.zcl_basic_cmd.dst_endpoint = endpoint;
+  read_req.zcl_basic_cmd.src_endpoint = _endpoint;
+
+  // clear read time
+  _read_time = 0;
+
+  log_v("Reading time from endpoint %d", endpoint);
+  esp_zb_zcl_read_attr_cmd_req(&read_req);
+
+  //Wait for response or timeout
+  if (xSemaphoreTake(lock, ZB_CMD_TIMEOUT) != pdTRUE) {
+    log_e("Error while reading time");
+    return tm();
+  }
+
+  struct tm *timeinfo = localtime(&_read_time);
+  if (timeinfo) {
+    return *timeinfo;
+  } else {
+    log_e("Error while converting time");
+    return tm();
+  }
+}
+
+int32_t ZigbeeEP::getTimezone(uint8_t endpoint, int32_t short_addr, esp_zb_ieee_addr_t ieee_addr) {
+  /* Read peer timezone */
+  esp_zb_zcl_read_attr_cmd_t read_req;
+
+  if (short_addr >= 0) {
+    read_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT;
+    read_req.zcl_basic_cmd.dst_addr_u.addr_short = (uint16_t)short_addr;
+  } else {
+    read_req.address_mode = ESP_ZB_APS_ADDR_MODE_64_ENDP_PRESENT;
+    memcpy(read_req.zcl_basic_cmd.dst_addr_u.addr_long, ieee_addr, sizeof(esp_zb_ieee_addr_t));
+  }
+
+  uint16_t attributes[] = {ESP_ZB_ZCL_ATTR_TIME_TIME_ZONE_ID};
+  read_req.attr_number = ZB_ARRAY_LENTH(attributes);
+  read_req.attr_field = attributes;
+
+  read_req.clusterID = ESP_ZB_ZCL_CLUSTER_ID_TIME;
+
+  read_req.zcl_basic_cmd.dst_endpoint = endpoint;
+  read_req.zcl_basic_cmd.src_endpoint = _endpoint;
+
+  // clear read timezone
+  _read_timezone = 0;
+
+  log_v("Reading timezone from endpoint %d", endpoint);
+  esp_zb_zcl_read_attr_cmd_req(&read_req);
+
+  //Wait for response or timeout
+  if (xSemaphoreTake(lock, ZB_CMD_TIMEOUT) != pdTRUE) {
+    log_e("Error while reading timezone");
+  }
+
+  return _read_timezone;
+}
+
+void ZigbeeEP::zbReadTimeCluster(const esp_zb_zcl_attribute_t *attribute) {
+  /* Time cluster attributes */
+  if (attribute->id == ESP_ZB_ZCL_ATTR_TIME_TIME_ID && attribute->data.type == ESP_ZB_ZCL_ATTR_TYPE_UTC_TIME) {
+    log_v("Time attribute received");
+    log_v("Time: %lld", *(uint32_t *)attribute->data.value);
+    _read_time = *(uint32_t *)attribute->data.value;
+    xSemaphoreGive(lock);
+  } else if (attribute->id == ESP_ZB_ZCL_ATTR_TIME_TIME_ZONE_ID && attribute->data.type == ESP_ZB_ZCL_ATTR_TYPE_S32) {
+    log_v("Timezone attribute received");
+    log_v("Timezone: %d", *(int32_t *)attribute->data.value);
+    _read_timezone = *(int32_t *)attribute->data.value;
+    xSemaphoreGive(lock);
+  }
+}
+
 #endif  //SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED
diff --git a/libraries/Zigbee/src/ZigbeeEP.h b/libraries/Zigbee/src/ZigbeeEP.h
index ac22143c4d7..eae81fafbc3 100644
--- a/libraries/Zigbee/src/ZigbeeEP.h
+++ b/libraries/Zigbee/src/ZigbeeEP.h
@@ -82,16 +82,27 @@ class ZigbeeEP {
     _allow_multiple_binding = bind;
   }
 
-  // Manufacturer name and model implemented
+  // Set Manufacturer name and model
   void setManufacturerAndModel(const char *name, const char *model);
-  void setPowerSource(zb_power_source_t power_source, uint8_t percentage = 255);
-  void setBatteryPercentage(uint8_t percentage);
-  void reportBatteryPercentage();
 
   // Methods to read manufacturer and model name from selected endpoint and short address
   char *readManufacturer(uint8_t endpoint, uint16_t short_addr, esp_zb_ieee_addr_t ieee_addr);
   char *readModel(uint8_t endpoint, uint16_t short_addr, esp_zb_ieee_addr_t ieee_addr);
 
+  // Set Power source and battery percentage for battery powered devices
+  void setPowerSource(zb_power_source_t power_source, uint8_t percentage = 255);
+  void setBatteryPercentage(uint8_t percentage);
+  void reportBatteryPercentage();
+
+  // Set time
+  void addTimeCluster(tm time = {0}, int32_t gmt_offset = 0);  // gmt offset in seconds
+  void setTime(tm time);
+  void setTimezone(int32_t gmt_offset);
+
+  // Get time from Coordinator or specific endpoint (blocking until response)
+  struct tm getTime(uint8_t endpoint = 1, int32_t short_addr = 0x0000, esp_zb_ieee_addr_t ieee_addr = {0});
+  int32_t getTimezone(uint8_t endpoint = 1, int32_t short_addr = 0x0000, esp_zb_ieee_addr_t ieee_addr = {0});  // gmt offset in seconds
+
   bool epAllowMultipleBinding() {
     return _allow_multiple_binding;
   }
@@ -104,6 +115,7 @@ class ZigbeeEP {
   virtual void zbAttributeRead(uint16_t cluster_id, const esp_zb_zcl_attribute_t *attribute) {};
   virtual void zbReadBasicCluster(const esp_zb_zcl_attribute_t *attribute);  //already implemented
   virtual void zbIdentify(const esp_zb_zcl_set_attr_value_message_t *message);
+  virtual void zbReadTimeCluster(const esp_zb_zcl_attribute_t *attribute);  //already implemented
 
   virtual void zbIASZoneStatusChangeNotification(const esp_zb_zcl_ias_zone_status_change_notification_message_t *message) {};
 
@@ -120,6 +132,8 @@ class ZigbeeEP {
   char *_read_manufacturer;
   char *_read_model;
   void (*_on_identify)(uint16_t time);
+  time_t _read_time;
+  int32_t _read_timezone;
 
 protected:
   uint8_t _endpoint;
diff --git a/libraries/Zigbee/src/ZigbeeHandlers.cpp b/libraries/Zigbee/src/ZigbeeHandlers.cpp
index bccb27da7f8..3b4992d81db 100644
--- a/libraries/Zigbee/src/ZigbeeHandlers.cpp
+++ b/libraries/Zigbee/src/ZigbeeHandlers.cpp
@@ -105,6 +105,8 @@ static esp_err_t zb_cmd_read_attr_resp_handler(const esp_zb_zcl_cmd_read_attr_re
         if (variable->status == ESP_ZB_ZCL_STATUS_SUCCESS) {
           if (message->info.cluster == ESP_ZB_ZCL_CLUSTER_ID_BASIC) {
             (*it)->zbReadBasicCluster(&variable->attribute);  //method zbReadBasicCluster implemented in the common EP class
+          } else if (message->info.cluster == ESP_ZB_ZCL_CLUSTER_ID_TIME) {
+            (*it)->zbReadTimeCluster(&variable->attribute);  //method zbReadTimeCluster implemented in the common EP class
           } else {
             (*it)->zbAttributeRead(message->info.cluster, &variable->attribute);  //method zbAttributeRead must be implemented in specific EP class
           }
diff --git a/libraries/Zigbee/src/ep/ZigbeeCarbonDioxideSensor.cpp b/libraries/Zigbee/src/ep/ZigbeeCarbonDioxideSensor.cpp
index 5def43f4199..b4386b80386 100644
--- a/libraries/Zigbee/src/ep/ZigbeeCarbonDioxideSensor.cpp
+++ b/libraries/Zigbee/src/ep/ZigbeeCarbonDioxideSensor.cpp
@@ -11,7 +11,6 @@ esp_zb_cluster_list_t *zigbee_carbon_dioxide_sensor_clusters_create(zigbee_carbo
   esp_zb_cluster_list_add_carbon_dioxide_measurement_cluster(
     cluster_list, esp_zb_carbon_dioxide_measurement_cluster_create(carbon_dioxide_meas_cfg), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE
   );
-  esp_zb_cluster_list_add_identify_cluster(cluster_list, esp_zb_zcl_attr_list_create(ESP_ZB_ZCL_CLUSTER_ID_IDENTIFY), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
   return cluster_list;
 }
 
diff --git a/libraries/Zigbee/src/ep/ZigbeeFlowSensor.cpp b/libraries/Zigbee/src/ep/ZigbeeFlowSensor.cpp
index 75196e78543..36d66840967 100644
--- a/libraries/Zigbee/src/ep/ZigbeeFlowSensor.cpp
+++ b/libraries/Zigbee/src/ep/ZigbeeFlowSensor.cpp
@@ -9,7 +9,6 @@ esp_zb_cluster_list_t *zigbee_flow_sensor_clusters_create(zigbee_flow_sensor_cfg
   esp_zb_cluster_list_add_basic_cluster(cluster_list, esp_zb_basic_cluster_create(basic_cfg), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
   esp_zb_cluster_list_add_identify_cluster(cluster_list, esp_zb_identify_cluster_create(identify_cfg), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
   esp_zb_cluster_list_add_flow_meas_cluster(cluster_list, esp_zb_flow_meas_cluster_create(flow_meas_cfg), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
-  esp_zb_cluster_list_add_identify_cluster(cluster_list, esp_zb_zcl_attr_list_create(ESP_ZB_ZCL_CLUSTER_ID_IDENTIFY), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
   return cluster_list;
 }
 
diff --git a/libraries/Zigbee/src/ep/ZigbeeOccupancySensor.cpp b/libraries/Zigbee/src/ep/ZigbeeOccupancySensor.cpp
index 3a7acee040c..dec7910ac03 100644
--- a/libraries/Zigbee/src/ep/ZigbeeOccupancySensor.cpp
+++ b/libraries/Zigbee/src/ep/ZigbeeOccupancySensor.cpp
@@ -9,7 +9,6 @@ esp_zb_cluster_list_t *zigbee_occupancy_sensor_clusters_create(zigbee_occupancy_
   esp_zb_cluster_list_add_basic_cluster(cluster_list, esp_zb_basic_cluster_create(basic_cfg), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
   esp_zb_cluster_list_add_identify_cluster(cluster_list, esp_zb_identify_cluster_create(identify_cfg), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
   esp_zb_cluster_list_add_occupancy_sensing_cluster(cluster_list, esp_zb_occupancy_sensing_cluster_create(occupancy_meas_cfg), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
-  esp_zb_cluster_list_add_identify_cluster(cluster_list, esp_zb_zcl_attr_list_create(ESP_ZB_ZCL_CLUSTER_ID_IDENTIFY), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
   return cluster_list;
 }
 
diff --git a/libraries/Zigbee/src/ep/ZigbeePressureSensor.cpp b/libraries/Zigbee/src/ep/ZigbeePressureSensor.cpp
index 24b4efb127e..b887680076d 100644
--- a/libraries/Zigbee/src/ep/ZigbeePressureSensor.cpp
+++ b/libraries/Zigbee/src/ep/ZigbeePressureSensor.cpp
@@ -9,7 +9,6 @@ esp_zb_cluster_list_t *zigbee_pressure_sensor_clusters_create(zigbee_pressure_se
   esp_zb_cluster_list_add_basic_cluster(cluster_list, esp_zb_basic_cluster_create(basic_cfg), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
   esp_zb_cluster_list_add_identify_cluster(cluster_list, esp_zb_identify_cluster_create(identify_cfg), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
   esp_zb_cluster_list_add_pressure_meas_cluster(cluster_list, esp_zb_pressure_meas_cluster_create(pressure_meas_cfg), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
-  esp_zb_cluster_list_add_identify_cluster(cluster_list, esp_zb_zcl_attr_list_create(ESP_ZB_ZCL_CLUSTER_ID_IDENTIFY), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
   return cluster_list;
 }