在Flutter中,处理特定于业务实体且与用户的本地时间无关的DateTime的最佳方法是什么?

axzmvihb  于 2023-03-31  发布在  Flutter
关注(0)|答案(2)|浏览(102)

我们一直在努力在我们的应用程序中设计一个强大的日期和时间值流。这是一个带有Flutter前端和Node.js后端以及PostgreSQL数据库的轮班调度应用程序。

业务逻辑

该应用程序允许企业主发布班次,员工注册轮班。
所有企业目前都在一个时区-“欧洲/柏林”。这个时区尊重冬季(CET - UTC+1)和夏季时间(CEST - UTC+2)。
无论设备的本地时间如何,显示给用户和用户输入的所有日期和时间都应假定为本地业务时区。

当前解决方案

Node.js从PostgreSQL的timestamptz列中以UTC(“2023-03- 30 T09:00:00.000Z”)表示日期/时间值。
Flutter应用程序使用注入的格式化程序转换显示器上的这些值,如下所示:

import 'package:intl/intl.dart';
import 'package:timezone/timezone.dart' as tz;

/// Display functions:
  DateTime toEuropeBerlinTime(DateTime utcDate) {
    final europeBerlin = tz.getLocation('Europe/Berlin');
    return tz.TZDateTime.from(utcDate, europeBerlin);
  }

  String display(String format, DateTime? utcDateTime) {
    if (utcDateTime == null) {
      return '';
    } else {
      final convertedToEuropeBerlin = toEuropeBerlinTime(utcDateTime);
      final dateFormatter = DateFormat(
        format,
        'de_DE',
      );
      final convertedAndFormatted =
          dateFormatter.format(convertedToEuropeBerlin);
      return convertedAndFormatted;
    }
  }

/// Example usage:
final exampleUtcTime = DateTime.parse('2023-03-30T09:00:00.000Z');
final displayValue =  display('d MMM y hh:mm', exampleUtcTime);
// displays 30 Marz 2023 11:00 - correct CEST
final exampleUtcTimeWinter = DateTime.parse('2023-01-30T09:00:00.000Z');
final displayValue =  display('d MMM y hh:mm', exampleUtcTimeWinter);
// displays 30 Jan 2023 10:00 - correct CET

对于用户输入具有类似的反向解决方案。

当前问题

我们不确定这是否是最好的解决方案。
1.有很多转换正在进行-比如,用户在应用程序中输入日期和时间,它被转换为UTC,发送到API,存储在数据库中。在显示器上,它被转换回欧洲/柏林时区并显示给用户。同时,UX必须接受用户输入,如果我们想在API调用之前向用户显示这个值,那么将它转换回欧洲/柏林时区。
1.因此,很难跟踪一个值所在的时区。我们必须在将值发送到API之前小心地将其转换为UTC,并在将其显示给用户之前将其转换回欧洲/柏林时区。这会导致难以跟踪的错误。
1.将转换器注入到UX小部件并不理想,因为构建多个小部件-每个小部件进行相同的转换-在例如刷新班次列表时会导致明显的性能延迟。
1.我们还没有找到一个解决方案的情况下,在夏季时间的转变显示在一月。
我甚至没有考虑过在这个时区之外进行任何形式的扩展。

我们考虑过的潜在解决方案

1.在API服务中将所有UTC日期/时间值转换为业务本地化值,反之亦然,从而使Flutter DateTime完全不受时区影响。
1.完全放弃时区感知的日期/时间,只使用没有意识到的对象,时间戳Postgres列-〉这意味着我们只需要在计算发生在时区更改当天的夜班的轮班长度时考虑时区。
1.将Flutter中的转换向下推到数据存储库级别,以便转换将绑定到fromJson / toJson方法。
由于我们都是自学成才的,而且这些解决方案中的每一个都对代码库非常重要,我们真的很感激来自社区的任何关于这个问题的建议。
非常感谢!

oxcyiej7

oxcyiej71#

IMO将所有内容存储在UTC中是正确的方法,所以你可以在后端进行UTC转换当从后端获取数据时,您可以在解析解码的JSON响应时在应用程序的模型层上应用转换(因为您将以UTC格式接收所有日期)。这样您就可以在前端和后端之间划分负载。

piah890a

piah890a2#

在组织方面,最好在fromJson/toJson中进行转换,因为您的转换将仅在一个地方进行,从而降低代码的复杂性并便于将来的维护。
希望我帮上忙了

相关问题