# 多时区
FlowPortal BPM支持多时区,多时区主要应用于中国公司跨国型集团企业、外国公司在中国、未来可能开展海外业务的企业。
# 多时区的具体内容
- 发起流程、处理任务的时间显示,不同时区显示正确的本地时间
- 系统日志等,不同时区显示正确的本地时间
- 流程表单上填写的时间,不同时区显示正确的本地时间
- 微应用表单上填写的时间、列表中显示的时间
- 系统中填写的时间,如外出设置中时间,支持多时区
- 工作日历、定时开始节点等设置应有时区设置
- 不宜按时区显示的时间,如生日、入职时间等日期型数据
使用者无需进行额外设置,使用者的时区以电脑时区为准进行转换,比如:同样一张表单,不同时区的人,看到的是自己时区对应的时间。
数据库存储数据的时区在appsettins.json中的Persistence: TimeZone指定
"TimeZone": "China Standard Time",
用 system-time-zones命令列出所有时区
Windows时区名和Iana(Linux用)时区名字不同,系统已做了处理,都能识别。
部署程序时可以根据自己的需要进行设置,默认是中国标准时间,如图:在Server端appseting.json文件中设置。
# 开发
# 一般开发者
注意邮件中的时间格式即可
yyyy-MM-dd HH:mmzzz格式(2024-06-06 09:30+08:00)
# 应用开发者
自定义开发的应用支持多时区
应用搜索中的时间如何支持多时区
1、让控件返回带时区的时间
时间控件增加了timeZone属性,想返回带时区的时间,将timeZone属性设置为true
{
XClass:’Ext.Date.Time’,
timeZone:true
}
检测提交数据与服务器返回json数据时间格式是否正确
不带时区: ShipDate: 2026-06-06T09:00:00
带时区: ShipDate: 2026-06-06T09:00:00+08:00
带时区(也正常,但不是我们系统产生和推荐的): ShipDate: 2026-06-06T01:00:00Z
注意:日期控件缺省false,带时间的控件缺省true
2、后台存储数据时要转化为数据库时间
用EFCore存数据,无需处理,Yiez框架已处理,会自动转化为数据库时区
用自己的sql存数据库,用TimePersistenceService的ToDbTime转化为数据库时区
timePersistenceService.ToDbTime(t1);
3、后台查询数据时要转化为数据库时间再比较
用EFCore存数据,无需处理,Yiez框架已处理,会自动转化为数据库时区
var appLogs = dbContext.AppLogs
.Where(x => x.Day >= dayFrom && x.Day <= dayTo)
.Where(x => x.Time >= timeFrom && x.Time < timeTo);
用自己的sql存数据库,用TimePersistenceService的ToDbTime转化为数据库时区
timeTo = timePersistenceService.ToDbTime(timeTo);
# 不要带时区的时间处理
Web端时间控件
{
XClass:’Ext.Date.Time’,
timeZone: false
}
后端使用EFCore,设置相应字段属性UnspecifiedTimeZone
[Column("birthday")]
[UnspecifiedTimeZone]
public DateTime? Birthday { get; set; }
后端使用自己代码操作数据库,则无需转换时间
注意:
如果数据通过Grpc传输,不带时区的时间不能使用google.protobuf.Timestamp, Timestamp传递时间将失去时间的非特定时区属性,导致传到后台时间变成了带时区的时间而错误,建议使用ISO8601格式字符串传时间,对应的API为 DateTime. ToISO8601String和String. ISO8601ToDateTime
# 时间数据格式
Js – 带时区
mydate.timeZone = true
Json ISO8601
2024-06-06T09:00:00 (非特定时区)
2024-06-06T09:00:00+08:00 (时间和时区)
2024-06-06T09:00:00Z (utc时间)
.Net c#
myDate.Kind == DateTimeKind.Local
myDate.Kind == DateTimeKind.Unspecified
myDate.Kind == DateTimeKind.Utc
Grpc传输时间
Timestamp 传输UTC时间,用秒和纳秒记录,无法传输C#中Unspecified时间
ISO8601字符串,可以转递任何类型的C#时间
数据库时间
不带时区,存储和查询时需先将时间转化为数据库时区再做存储和查询
# 时间格式转换前台到后台
Js -> Json
mydate.timeZone == true => 2024-06-06T09:00:00+08:00
mydate.timeZone == false => 2024-06-06T09:00:00
Json -> C#
2024-06-06T09:00:00+08:00 => DateTimeKind.Local
2024-06-06T09:00:00 => DateTimeKind.Unspecified
C# -> Grpc
DateTimeKind.Local => Timestamp(utc)
DateTimeKind.Unspecified => ISO8601字符串
Grpc -> C#
Timestamp(utc) => DateTimeKind.Local
ISO8601字符串 => DateTimeKind.Unspecified
C# -> 数据库时间
DateTimeKind.Local 2024-06-06 09:00:00+08:00 => 转为数据库存储时间 2024-06-06 08:00:00(西伯利亚时间)
DateTimeKind. Unspecified 2024-06-06 09:00:00 => 不转换 2024-06-06 09:00:00(西伯利亚时间)
# 时间格式转换后台到前台
数据库 -> C#
Unspecified 转时区=> DateTimeKind.Local
Unspecified 不转时区=> DateTimeKind.Unspecified
C# -> Grpc
DateTimeKind.Local => Timestamp(utc)
DateTimeKind.Unspecified => ISO8601字符串
Grpc -> C#
Timestamp(utc) => DateTimeKind.Local (我们的系统里面转化为Local也缺省转utc)
ISO8601字符串 => DateTimeKind.Unspecified
C# -> Json
DateTimeKind.Local => 2024-06-06T09:00:00+08:00
DateTimeKind.Unspecified => 2024-06-06T09:00:00
Json -> JS
2024-06-06T09:00:00+08:00 => 转为用户本地时间 2024-06-06T10:00:00+09:00(东京时间)
2024-06-06T09:00:00 => 原封不动变为用户本地时间 2024-06-06T09:00:00+09:00