Contrary to the web, React Native does not run in a browser, so it gets tricky when trying to get timezone offsets and accounting for daylight savings time.

Recently I was tasked to convert all backend generated timestamps from the default UTC to our users’ device timezone. This is my process of how I encountered some issues along the way and how I solved my ticket.

Flowchart

This is the flow I went for:

  1. Get user UTC time offset in hours.
  2. Send backend timestamp & offset into a conversion function that returns the converted+formatted string to the frontend.

The function in step 2 would work like this:

params:

  • String: dateString
  • Int: offset

a) Parse the date string dateString.

b) Convert data into JS Date object.

c) Get the current hours of the date object by using JS Date built-in function getHours() method.

d) Set new hours on the Date object by using JS Date built-in function setHours(), where we pass in the current hours and add the offset passed into the function.

e) Format the string to the frontend.

f) Return the final converted timestamp.

Let’s see that happen in code:

Let’s imagine how we would like to use our function, it would probably look something like this

const convertedTimeStamp = formatTimeByOffset(utcStringFromBE, offset)

The function I build based on the steps above looks like this:

export const formatTimeByOffset = (dateString, offset) => {
  // Params:
  // How the backend sends me a timestamp
  // dateString: on the form yyyy-mm-dd hh:mm:ss
  // offset: the amount of hours to add.
// If we pass anything falsy return empty string
  if (!dateString) return ''
  if (dateString.length === 0) return ''
// Step a: Parse the backend date string
// Get Parameters needed to create a new date object
  const year = dateString.slice(0, 4)
  const month = dateString.slice(5, 7)
  const day = dateString.slice(8, 10)
  const hour = dateString.slice(11, 13)
  const minute = dateString.slice(14, 16)
  const second = dateString.slice(17, 19)
// Step: bMake a JS date object with the data
  const dateObject = new Date(`${year}-${month}-${day}T${hour}:${minute}:${second}`)
// Step c: Get the current hours from the object
  const currentHours = dateObject.getHours()
// Step d: Add the offset to the date object
  dateObject.setHours(currentHours + offset)
// Step e: stringify the date object, replace the T with a space and slice off the seconds.
  const newDateString = dateObject
    .toISOString()
    .replace('T', ' ')
    .slice(0, 16)
// Step f: Return the new formatted date string with the added offset
  return `${newDateString}`
}

Here’s the code on GitHub.

With some quick testing bypassing in random time offsets show that this function works correctly. Calling it and printing the result gives the following:

const convertedToLocalTime = formatTimeByOffset('2001-04-11 10:00:00', 7)

console.log(convertedToLocalTime)
// --> "2001-04-11 17:00:00"

Awesome! Now we just need to get the user UTC time offset and we are done 🚀 Well it might be simple in theory, but it takes some extra considerations.

#programming #react #javascript #react-native #algorithms

Getting user device timezone and converting UTC time-stamps with offset
74.80 GEEK