我们一直在努力在我们的应用程序中设计一个健壮的日期和时间值流。它是一个班次调度应用程序,前端是Flutter,后端是Node.js和PostgreSQL数据库。
<标题>业务逻辑该应用程序允许企业主发布班次,员工注册班次。
所有企业目前都在一个时区-"欧洲/柏林"。此时区尊重冬季时间(CET - UTC+1)和夏季时间(CEST - UTC+2)。
无论设备的本地时间如何,用户显示和输入的所有日期和时间都应假定为本地业务时区。
<标题>当前解决方案Node.js从PostgreSQL的timestamptz列中显示UTC格式的日期/时间值("2023-03-30T09: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
对于用户输入,使用类似的反向解决方案。
<标题>当前问题我们不确定这是否是最好的解决方案。
- 有很多转换正在进行-说,用户在应用程序中输入日期和时间,它被转换为UTC,发送到API,存储在数据库中。在显示时,它被转换回欧洲/柏林时区并显示给用户。与此同时,UX必须接受用户输入,将其存储在UTC中,如果我们想在API调用之前将值显示给用户,则将其转换回欧洲/柏林时区。
- 因此,很难跟踪一个值所在的时区。在将值发送到API之前,我们必须小心地将它们转换为UTC,并在将它们显示给用户之前返回到欧洲/柏林时区。这将导致难以跟踪的bug。
- 将转换器注入UX小部件是不理想的,因为构建多个小部件——每个小部件都做相同的转换——会导致明显的性能延迟,例如刷新一个轮班列表。
- 对于1月份显示夏令时的情况,我们还没有找到解决方案。
我现在甚至没有考虑到这个时区以外的任何形式的扩展。
我们考虑过的潜在解决方案
- 在API服务中将所有UTC日期/时间值转换为业务本地化值,反之亦然,从而使Flutter DateTime完全不受时区影响。
- 完全抛弃时区感知的日期/时间,只使用不感知的时间戳对象Postgres列->这意味着只有在计算发生在时区更改当天的夜班的移位长度时才需要考虑时区。
- 将Flutter中的转换下推到数据存储库级别,以便将转换绑定到fromJson/toJson方法。
因为我们都是自学成才的,而且这些解决方案对代码库都很重要,所以我们非常感谢社区对这个问题的任何建议。
非常感谢!
标题>标题>标题>IMO在UTC中存储所有内容是正确的方式,所以您如何处理此问题是ok的。您可以在后端进行UTC转换(这将使前端远离处理此转换)。当从后端获取数据时,您可以在解析解码的JSON响应时在应用程序的模型层上应用转换(因为您将以UTC格式接收所有日期)。这样就可以在前端和后端之间分配负载。
在组织方面,最好在fromJson/toJson中进行转换,因为您的转换将只在一个地方进行,从而降低了代码的复杂性并便于将来的维护。
希望对你有所帮助