salesforce零基础学习(一百四十二)在Formula字段中如何通过Datetime字段显示Local Time(适配DST)

news/2025/1/9 18:05:08/文章来源:https://www.cnblogs.com/zero-zyq/p/18587389

背景:

我们需求是显示Date Time类型的Time信息,比如我们想要在report中基于Hour Of Created Date进行分组,从而想要了解到一段时间内什么时间是数据创建的高峰期,不同的running user可能时区不同,比如中国时区是GMT+8,日本的时区是GMT+9,美国可能不同的州对应的时区也不同,而且涉及到冬令时夏令时问题。目前的痛点是formula中的函数只能显示GMT时间,无法做到显示 user locale的时间,那么应该如何设计才可以保证不同运行的人可以显示不同时区的时间信息呢?

这里我们需要考虑几个问题点:

  1. 如何获取当前用户的时区以及相对GMT的偏移量?比如中国时区是GMT+8,代码上如何知道他想对GMT时间是+8的?
  2. 如果你的运行用户有欧美国家的时区,需要考虑冬令时和夏令时。欧美很多国家都有都有冬令时和夏令时的概念,我们以纽约为例,中国大陆所有地方的时区是GMT + 8, 纽约的夏令时时区是GMT-4,也就是说在每年的3月到11月,如果GMT时间是 12:00:00,则如果你的user时区是China Standard Time,则时间显示 20:00:00, 如果你的user时区是America/New_York,则时间显示8:00:00。然而等到了11月的某个时间节点以后,New_York的GMT便会变成GMT-5,同样的GMT时间,则时间显示成 7:00:00。
  3. 我们看report的数据可能跨年。举个例子,当前的时间如果是 25年1月,我所看的数据除了25年的数据,还可能看到24年的数据甚至23年的数据,如何显示不同年的数据?

分析:

针对这种需求情况,我们可能需要去看一下我们的org,然后确定几个点:

1. 当前的org针对当前需求的user有几个TimeZone。可以简单run一个sql,根据需求增加相关的filter:比如下面的结果,我们有两个时区。Asis/Shanghai 以及 America/New_York

SELECT TimeZoneSidKey, count(Id)
from user
where TimeZoneSidKey != null
and isactive = true
and Profile.UserLicense.Name != 'Guest User License'
group by TimeZoneSidKey

2.  判断当前Timezone的时区信息以及偏移量,这里我们可以进行很简单的方式来确定,即将admin的user切换成相关的时区,然后运行脚本就可以了,我们以一下面的代码来进行简单的确定偏移量。

Integer year = 2024;
Set<Decimal> offsetSet = new Set<Decimal>();
for(Integer month = 1; month<= 12; month++) {Date dt1 = Date.newInstance(year, month,1);Date dt2;if(month != 12) {dt2 = Date.newInstance(year, month + 1, 1);} else {dt2 = Date.newInstance(year + 1, 1, 1);}for(Integer day = 1; day <= dt1.daysBetween(dt2); day++) {Datetime gmtDate = Datetime.newInstanceGMT(year, month, day, 0,0,0);Datetime userLocaleDate = Datetime.newInstance(year,month,day,0,0,0);offsetSet.add((gmtDate.getTime() - userLocaleDate.getTime()) / (1000 * 60 * 60));}
}
system.debug(offsetSet);

我们如果以GMT + 8的时区来运行,则显示 8, 如果以GMT-4的New York Time来运行,则结果为 -4 -5(如果超过一个,说明包含DST时间)

3. 确定数据需要显示的年限范围。比如我们针对当前的表,只显示当前的年和显示近两年以及显示任何历史数据的解决方案都是不同的。在出具解决方案以前,我们需要确定一下用户需要查看的年限范围从而更好的设计。

解决方案

针对上面的三个分析的点,我们可以构建不同的解决方案,不同的分析结果会导向不同的解决方案,以下仅是个人的建议。

当前有几个timezone timezone中是否包含DST 用户所需要看到的年限范围 解决方案
1-4个 不包含 任意 在user上创建一个Number的字段用来存储偏移量,维护一下 timezone -> offset的关系,无论是hard code还是custom metadata / setting,然后user创建时更新当前字段或者对历史用户进行刷新。
很多,比如超过5个 不包含  任意  在user上创建一个Number的字段用来存储偏移量,通过login flow +  apex class获取当前user的偏移量信息,然后存储到当前字段。后续的formula可以通过加上当前偏移量进行解决。
 1-4个 包含 1-3年  创建 custom metadata,运行脚本设置timezone以及它对应的夏令时 start date 以及end date 以及冬夏的偏移量和年份,然后formula基于年份以及 start/end date去确认偏移量来动态展示。
很多,比如超过5个 包含 1-3年 创建 custom metadata,通过login flow + apex class获取当前user的偏移量信息以及timezone,然后动态维护custom metadata信息,然后formula基于年份以及start/end date去确认偏移量来动态展示。
1-4个 包含 任意  同上,但是有 formula编译失败风险,目前没想到更好的解决方案

 

给出解决方案以后相信开发人员可以基于解决方案进行开发,当前的博客只针对一个场景进行详细的介绍,我们选取包含 DST并且两个timezone以及用户想要看到去年和今年的数据的场景进行详细的展开。

实践

需求和问题汇总

Account上面有一个Datetime类型字段,名称为Test Date Time,还有两个formula字段,一个是使用TIMEVALUE函数返回当前的Time类型的字段,名称为 Time Of Test Date Time, 一个是使用 HOUR函数返回当前Time的Hour信息,名称为 Hour Of Test Date Time。 我们看一下数据展示。

1. 通过GMT + 8中国账号演示效果,通过下方GIF我们可以看出 Test Date Time字段的Time信息 减去8小时即为 Time Of Test Date Time, Hour 和 Time 两个formula字段均显示GMT时间,8为当前user的locale time偏移量。

2. 通过 GMT-4/5 纽约账号登陆显示效果。我们通过下方截图可以看到,Test Date Time是8点情况下,10月的Time Of Test Date Time的差值是 -4,然而11月确实-5. 原因是纽约11月初进入冬令时,user locale time从 GMT-4 变成了 GMT-5。

 我们这个demo需要完成的就是两个:

1. 针对中国区的客户访问report时可以显示中国区的user locale时间,针对美国区的客户访问report时可以显示美国区的user locale时间;

2. 针对美国区的客户访问report时,需要适配Daylight Saving Time(冬令时夏令时匹配)

实施

1. 创建custom metadata并且维护数据。

  • Summer Start Date: 记录夏令时开始时间
  • Summer End Date: 记录夏令时结束时间
  • Summer Offset: 记录夏令时用户区域的时间偏移量
  • Winter Offset:记录冬令时用户区域的时间偏移量
  • Year: 记录当前数据的年限

 我们上图中的所维护的数据如何填写或者如何实现的呢?我们分析2中有一个脚本可以确定user的timezone有几个用户区域的偏移量,如果结果只有一个,设置当年的Start Date为1月1日并且End Date为12月31日。 如果包含两个结果,可以运行这个脚本:

Integer year = 2025;String result = '\nyear: ' + String.valueOf(year);Datetime summerDatetime = Datetime.newInstance(year, 6, 1, 12, 0 , 0);
Integer summerHourOffset = summerDatetime.Hour() - summerDatetime.hourGMT();result += '\nSummer Offset : ' + summerHourOffset;Datetime winterDatetime = Datetime.newInstance(year, 12, 1, 12 , 0 ,0 );
Integer winterHourOffset = winterDatetime.Hour() - winterDatetime.hourGMT();
result += ' \n winter Offset : ' + winterHourOffset;

for(Integer i = 1; i <=31; i++) {Datetime marchDatetime = Datetime.newInstance(year, 3, i, 12, 0, 0);Integer currentDateOffset = marchDatetime.Hour() - marchDatetime.hourGMT();if(currentDateOffset != winterHourOffset) {result += '\n summer start time: ' + marchDatetime.date();break;}
}

for(Integer i = 1; i <=30; i++) {Datetime marchDatetime = Datetime.newInstance(year, 11, i, 12, 0, 0);Integer currentDateOffset = marchDatetime.Hour() - marchDatetime.hourGMT();if(currentDateOffset != summerHourOffset) {result += '\n summer end time: ' + (marchDatetime.date() - 1);break;} }result += ' \n time zone: ' + UserInfo.getTimeZone().toString();system.debug(result);

3月作为冬令时的结束,11月作为冬令时的开始,只需要验证这两个月份即可。

2. 构建Formula字段

Offset Key: 将 User Local Time 以及Datetime字段绑定起来,获取指定模式下的字符串,用于后续逻辑使用。

TEXT($User.TimeZoneSidKey) + '_' + TEXT(YEAR( DATEVALUE(Test_Date_Time__c)))

GMT Offset: 记录 当前user locale time和GMT Time的偏移量。因为这里我们已经知道了CN没有时区,所以直接获取Summer Offset即可,好处是可以省编译的大小。

CASE(Offset_Key__c , 'America/New_York_2024', IF(AND(DATEVALUE(Test_Date_Time__c) >=  $CustomMetadata.Offset_Mapping__mdt.NY_2024.Summer_Start_Date__c ,DATEVALUE(Test_Date_Time__c) <=  $CustomMetadata.Offset_Mapping__mdt.NY_2024.Summer_End_Date__c ),$CustomMetadata.Offset_Mapping__mdt.NY_2024.Summer_Offset__c,$CustomMetadata.Offset_Mapping__mdt.NY_2024.Winter_Offset__c),'America/New_York_2025', IF(AND(DATEVALUE(Test_Date_Time__c) >=  $CustomMetadata.Offset_Mapping__mdt.NY_2025.Summer_Start_Date__c ,DATEVALUE(Test_Date_Time__c) <=  $CustomMetadata.Offset_Mapping__mdt.NY_2025.Summer_End_Date__c ),$CustomMetadata.Offset_Mapping__mdt.NY_2025.Summer_Offset__c,$CustomMetadata.Offset_Mapping__mdt.NY_2025.Winter_Offset__c),'Asia/Shanghai_2024', $CustomMetadata.Offset_Mapping__mdt.CN_2024.Summer_Offset__c,'Asia/Shanghai_2025', $CustomMetadata.Offset_Mapping__mdt.CN_2025.Summer_Offset__c,null
)

Time Of Test Date Time:  使用TimeValue函数基础上,增加偏移量从而返回User Locale Time.

TIMEVALUE( Test_Date_Time__c ) +  GMT_Offset__c * 60 * 60 * 1000

Hour Of Test Date Time: 直接使用Hour函数,返回time中的hour时间从而实现local time显示。

HOUR( Time_Of_Test_Date_Time__c )

效果展示:

当用户时区为中国时区,可以看到Time和Test Date Time 中的Time信息相同

当用户为美国时区,可以看到Time和Test Date Time 中的Time信息相同

总结:篇中主要介绍当我们使用Formula字段想要显示 Local Time并且可能涉及到多个区域以及东夏令时场景下的解决方案以及指定个例的实施。篇中有错误地方欢迎指出,有不懂欢迎留言。你们项目中遇到这类需求的时候有什么更好的解决方案吗? 欢迎留言一起讨论和学习。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/866657.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

官宣!通义灵码 AI 程序员全面上线

通义灵码2.0 你的AI程序员来了!速来领取你的全新魔法搭档吧! 通义灵码AI程序员成为全球首个同时支持 VS Code、JetBrains IDEs 开发工具的AI程序员产品。此次上线的AI程序员相比传统AI辅助编程工具,能力更全面,可以让开发者以更高效、更沉浸的方式完成编码任务,通过全程对…

htb Escape

扫描端口 nmap -sC -sV -p- -v -Pn -T4 10.10.11.202 Host is up (0.39s latency). Not shown: 65515 filtered tcp ports (no-response) PORT STATE SERVICE VERSION 53/tcp open domain Simple DNS Plus 88/tcp open kerberos-sec Microsoft Wind…

2025年销售攻略

随着2024年的落幕,我们迎来了全新的2025年,新一轮的业绩争夺战已经悄然打响。面对新的挑战与机遇,我们该如何在销售领域脱颖而出,实现业绩的稳步增长呢? 一、明确目标,勇往直前 销售工作离不开明确的目标。设定清晰、可行的销售目标,并将其分解为具体的时间节点和任务,…

杭州铭师堂的云原生升级实践

杭州铭师堂,是一个致力于为人的全面发展而服务的在线教育品牌。杭州铭师堂秉持“用互联网改变教育,让中国人都有好书读”的使命,致力于用“互联网+教育”的科技手段让更多的孩子都能享有优质的教育,促进他们的全面成长。作者:升学e网通研发部基建团队 公司介绍 杭州铭师堂…

新年餐饮业营销攻略:数据驱动,精准营销!

餐饮业借助项目管理软件开展新年营销,可以更加高效、精准地管理营销活动,提升销售业绩和用户体验。通过选择合适的软件工具、制定详细的营销计划、设置可视化的任务列表和进度跟踪、促进团队协作和沟通、收集和分析数据以优化营销策略、评估和调整项目计划以及总结经验和教训…

解锁新应用:探索GPU扩展是如何提升渲染农场的工作效率

联瑞GPU扩展方案在渲染农场的应用,是在原有计算机设备的基础上增加GPU的数量,不用额外购买GPU服务器,有效的帮助企业降本增效渲染农场是一种基于计算机GPU集群的渲染解决方案,主要用于分布式渲染。它将渲染任务分发到多个计算机(渲染节点)上,通过GPU并行计算和协同工作,实…

Task实战

一:场景描述 在一个文件下查找js文件中指定的关键字,并记录完成查找所需时间。完成此任务使用了3种写法,分别为: 1.仅使用一个task,在任务中进行for循环,循环调用异步业务处理方法,只利用一个后台线程进行业务处理。2.先查找出文件路径,然后对每一个文件路径创建一个ta…

多网卡配置bond模式4(Ubuntu22.04)

编辑网卡配置文件 vim /etc/netpla/00-installer-config.yaml示例一:示例二:

中考英语优秀范文-013 Computer in my life 电脑在我的生活中

中考英语优秀范文-013 Computer in my life 电脑在我的生活中 1 写作要求 假设某中学生英文报开展关于计算机与学生生活的征文活动,请你根据下表所提示的要点,以Computer in my life为题,用英语为该报写一篇短文,简述计算机在你生活中的用途,并就计算机对你生活的影响谈谈…

BAPI

预制发票:BAPI_INCOMINGINVOICE_PARKDATA: ls_header TYPE bapi_incinv_create_header,lt_itemdata TYPE TABLE OF bapi_incinv_create_item,ls_itemdata TYPE bapi_incinv_create_item,lt_taxdata TYPE TABLE OF bapi_incinv_create_tax,ls_taxdata TYPE bapi_…

车云远程诊断系统 - DRS

INTEWORK-DRS(Diagnostic Remote-Service System)是由经纬恒润自主研发的一款基于车云远程的诊断解决方案产品,具备整车级或单ECU级的如参数读写、故障读清、例程标定、动作测试和程序升级等传统常见诊断功能,并且支持基于云任务的车端主动诊断如车辆故障主动预警、关键数据…

Kubernetes集群运维生产常见问题解析与解决方案

前言:在Kubernetes集群的日常运维工作中,我们难免会遇到各种各样的问题。这些问题可能涉及到集群的部署、配置、监控、性能优化等多个方面。为了解决这些问题,我们需要不断地学习和积累经验。在这里,我打算收集并整理一些网友曾经提出的问题,并提供相应的解析和解决方案,…