Convert DateTime Field's UTC Value To The Correct Time Zone In An SPFx Webpart

Why convert UTC to correct TimeZone?

Any DateTime type of columns we create within SharePoint, are stored in UTC format internally. Any custom implementation which accesses the DateTime values programatically, will get the DateTime values returned in UTC as well. So, when a SPFx webpart tries to read list items with DateTime field values, using PnPjs, REST API or any other supported models, the DateTime values are always returned in UTC format. Due to this we might be seeing appropriate DateTime values within SPFx webparts. For example, below is a list which has some Events information with StartDate and EndDate. When we query this data using PnPjs within an SPFx webpart, the dates displayed within the webpart are different.
Check out this Video if you would like to understand how the Time Zone is determined and how we can easily display the correct DateTime values within an SPFx webpart.

How are DateTime values converted to the correct TimeZone?

When the DateTime field values are shown within the ListViews or any default sharepoint page, they are converted based on the Regional Settings. There are two possible Regional Settings which could effect which Time Zone is used for the site.
User's Regional Settings
A user can select their personal Regional Settings from their profile. Within their profile, the user can select which time zone they want to use. They can either use the Time Zone set by the Site Administrator or use their own Time Zone. If a user selects their own time zone, it always takes precedence over the Site's time zone.
Site's Regional Settings
A Site Administrator can select a time zone for the site from the Regional Settings of the site. This setting will be used only for those users who do not set their own time zone in their profile.
So, the DateTime fields are shown/displayed in the time zone selected by the user (in their profile) and when users have not set their time zones, the site's regional settings are used to determine the time zone.

Finding the correct Time Zone within a SPFx webpart

As we have seen,  the time zone is determined based on the user's and site's regional settings, so we might have to make at least 2 REST calls to find the correct timezone. An easier way to accomplish this is to use the 'FieldValuesAsText' property of the list items. When using PnPjs to query for list items, we can expand the FieldValuesAsText/StartDate and FieldValuesAsText/EndDate fields and get the converted date values as per the right time zone. Using this approach we can avoid making additional REST calls to find the correct Time Zone. Below is a example code snippet using PnPjs which can be used within an SPFx webpart.
  1. import { sp } from '@pnp/sp';  
  2. import '@pnp/sp/webs';  
  3. import '@pnp/sp/lists';  
  4. import '@pnp/sp/items';  
  6. const listName = "Events";  
  7. let items = await sp.web.lists.getByTitle(listName)  
  8. .items  
  9. .select("Title","Description","StartDate","EndDate","FieldValuesAsText/StartDate","FieldValuesAsText/EndDate")  
  10. .expand("FieldValuesAsText")  
  11. .get();  
  13. console.dir(items); 
Below is a sample JSON reponse using PnPjs query which returns the DateTime field values in both UTC format and in the correct TimeZone. 
Using this approach we can display the DateTime values in the correct time zone without making any additional REST calls to find the time zone of the user and site.
When a user changes the time zone within their profile, the change will take a couple of minutes to be reflected within the SharePoint site.