Quellcode durchsuchen

feat: use user local timezone (#2407)

Nathan.fooo vor 2 Jahren
Ursprung
Commit
8cacfb1d07

+ 2 - 1
frontend/appflowy_flutter/lib/plugins/database_view/application/database_controller.dart

@@ -341,9 +341,10 @@ class RowDataBuilder {
     _cellDataByFieldId[fieldInfo.field.id] = num.toString();
     _cellDataByFieldId[fieldInfo.field.id] = num.toString();
   }
   }
 
 
+  /// The date should use the UTC timezone. Becuase the backend uses UTC timezone to format the time string.
   void insertDate(FieldInfo fieldInfo, DateTime date) {
   void insertDate(FieldInfo fieldInfo, DateTime date) {
     assert(fieldInfo.fieldType == FieldType.DateTime);
     assert(fieldInfo.fieldType == FieldType.DateTime);
-    final timestamp = (date.millisecondsSinceEpoch ~/ 1000);
+    final timestamp = (date.toUtc().millisecondsSinceEpoch ~/ 1000);
     _cellDataByFieldId[fieldInfo.field.id] = timestamp.toString();
     _cellDataByFieldId[fieldInfo.field.id] = timestamp.toString();
   }
   }
 
 

+ 2 - 0
frontend/appflowy_flutter/lib/plugins/database_view/calendar/application/calendar_bloc.dart

@@ -240,6 +240,8 @@ class CalendarBloc extends Bloc<CalendarEvent, CalendarState> {
         cellId: cellId,
         cellId: cellId,
       );
       );
 
 
+      // The timestamp is using UTC in the backend, so we need to convert it
+      // to local time.
       final date = DateTime.fromMillisecondsSinceEpoch(
       final date = DateTime.fromMillisecondsSinceEpoch(
         eventPB.timestamp.toInt() * 1000,
         eventPB.timestamp.toInt() * 1000,
       );
       );

+ 16 - 14
frontend/rust-lib/flowy-database/src/services/field/type_options/date_type_option/date_type_option.rs

@@ -8,7 +8,7 @@ use crate::services::field::{
 };
 };
 use bytes::Bytes;
 use bytes::Bytes;
 use chrono::format::strftime::StrftimeItems;
 use chrono::format::strftime::StrftimeItems;
-use chrono::NaiveDateTime;
+use chrono::{Local, NaiveDateTime};
 use database_model::{FieldRevision, TypeOptionDataDeserializer, TypeOptionDataSerializer};
 use database_model::{FieldRevision, TypeOptionDataDeserializer, TypeOptionDataSerializer};
 use flowy_derive::ProtoBuf;
 use flowy_derive::ProtoBuf;
 use flowy_error::{ErrorCode, FlowyError, FlowyResult};
 use flowy_error::{ErrorCode, FlowyError, FlowyResult};
@@ -60,22 +60,26 @@ impl DateTypeOptionPB {
 
 
   fn today_desc_from_timestamp(&self, cell_data: DateCellData) -> DateCellDataPB {
   fn today_desc_from_timestamp(&self, cell_data: DateCellData) -> DateCellDataPB {
     let timestamp = cell_data.timestamp.unwrap_or_default();
     let timestamp = cell_data.timestamp.unwrap_or_default();
-    let include_time = cell_data.include_time;
-
-    let naive = chrono::NaiveDateTime::from_timestamp_opt(timestamp, 0);
-    if naive.is_none() {
+    if timestamp == 0 {
       return DateCellDataPB::default();
       return DateCellDataPB::default();
     }
     }
-    let naive = naive.unwrap();
-    if timestamp == 0 {
+
+    let include_time = cell_data.include_time;
+    let native = chrono::NaiveDateTime::from_timestamp_opt(timestamp, 0);
+    if native.is_none() {
       return DateCellDataPB::default();
       return DateCellDataPB::default();
     }
     }
+
+    // Use the local timezone to calculate the formatted date string. We can use the timezone that
+    // specified by the user in the future.
+    let offset = Local::now().offset().clone();
+    let native = chrono::DateTime::<chrono::Local>::from_utc(native.unwrap(), offset);
     let fmt = self.date_format.format_str();
     let fmt = self.date_format.format_str();
-    let date = format!("{}", naive.format_with_items(StrftimeItems::new(fmt)));
+    let date = format!("{}", native.format_with_items(StrftimeItems::new(fmt)));
 
 
     let time = if include_time {
     let time = if include_time {
       let fmt = self.time_format.format_str();
       let fmt = self.time_format.format_str();
-      format!("{}", naive.format_with_items(StrftimeItems::new(fmt)))
+      format!("{}", native.format_with_items(StrftimeItems::new(fmt)))
     } else {
     } else {
       "".to_string()
       "".to_string()
     };
     };
@@ -97,13 +101,11 @@ impl DateTypeOptionPB {
       if !time_str.is_empty() {
       if !time_str.is_empty() {
         let naive_time = chrono::NaiveTime::parse_from_str(time_str, self.time_format.format_str());
         let naive_time = chrono::NaiveTime::parse_from_str(time_str, self.time_format.format_str());
 
 
-        match naive_time {
-          Ok(naive_time) => {
-            return Ok(naive_date.date().and_time(naive_time).timestamp());
-          },
+        return match naive_time {
+          Ok(naive_time) => Ok(naive_date.date().and_time(naive_time).timestamp()),
           Err(_e) => {
           Err(_e) => {
             let msg = format!("Parse {} failed", time_str);
             let msg = format!("Parse {} failed", time_str);
-            return Err(FlowyError::new(ErrorCode::InvalidDateTimeFormat, &msg));
+            Err(FlowyError::new(ErrorCode::InvalidDateTimeFormat, &msg))
           },
           },
         };
         };
       }
       }