0

I've found a lot of good info on using Date() and getting timezones, but something just isn't working. I have my GraphQL (sourcing from Sanity) set to use formatString, like this:

export default function MinutesItemGrid() {
  const { minutes } = useStaticQuery(graphql`
    query {
      minutes: allSanityMinutes {
        nodes {
          endTime(formatString: "h:mma [on] MM/DD/YYYY")
         }
      }
   }
`);

Then calling it in a .map:

const allMinutes = minutes.nodes;
return (
    <CardStyles>
      {allMinutes.map((minute) => (
        <ItemStyles>
          <div className="card" key={minute.id}>
            <div className="content">Meeting began at: {minute.endTime}</div>
          </div>
        </ItemStyles>
     ))}
    </CardStyles>
  );

Which displays as 11:33pm on 10/14/2020. That is 6 hours ahead of what it should be.

I know this returns UTC time standardly. I know how to get the local time offset (new Date().getTimezoneOffset();) and get the local timezone (Intl.DateTimeFormat().resolvedOptions().timeZone), but I don't see an option to change the timezone to display to MST (or local time) instead of UTC. I have tried subtracting the 6 hours in various ways, tried using moment.js and moment.js timezone to change the timezones based on their docs. I've just found out that Luxon is a better option now, but even in their docs I don't see a resolution when pulling the data from GraphQL.

James Lin
  • 162
  • 3
  • 18

2 Answers2

0

If you plan to use Luxon, you can use DateTime to convert and format datetime to any given time zone.

For example, MDT is UTC-6. So, to convert datetime in ISO string format.

import { DateTime } from "luxon"

DateTime.fromISO(datetime, { zone: 'utc-6' }).toString()

This would output the datetime in MDT zone as 2021-04-21T07:36:04.529-06:00

Y.S.
  • 161
  • 1
  • 5
  • Thanks for responding @Y.S. This definitely has me on the right track. The one thing I don't understand is how to use my GraphQL as an argument within the DateTime. It looks like in your example datetime is the GraphQL argument, but I have two GraphQL arguments to declare: endTime & meetingStart. I definitely have to declare this within my function, so that the GraphQL is referencable; however, if I do this outside the `.map` then it returns undefined and if I do it within `.map` it breaks. What have I gotten wrong? Does this bit need to go in my Sanity or Gatsby folder? – Eric Phifer Apr 22 '21 at 10:50
0

I have discovered the answer after much trial & error in case this helps anyone in the future. The problem that I was running into is this bit: endTime(formatString: "h:mma [on] MM/DD/YYYY")

What this did is format the string before I called the DateTime.from(minute.endTime, { zone: 'utc-6',}) so that it returned an invalid entry because .fromISO is expecting this kind of format 2020-10-14T17:33:00.000. Once I removed that all was well except for the format, which I discovered instead of using the .toString() method I had to use the .toFormat() method. So this is the corrected code from my original question:

export default function MinutesItemGrid() {
  const { minutes } = useStaticQuery(graphql`
    query {
      minutes: allSanityMinutes {
        nodes {
          endTime
         }
      }
   }
`);

then .map over the graphql:

const allMinutes = minutes.nodes;
return (
<CardStyles>
  {allMinutes.map((minute) => {
    const endMDT = DateTime.fromISO(minute.endTime, {
      zone: 'utc-6',
    }).toFormat('h:mma MM/dd/yyyy');
    <ItemStyles>
      <div className="card" key={minute.id}>
        <div className="content">Meeting began at: {endMDT}</div>
      </div>
    </ItemStyles>
 ))}
</CardStyles>

);