1

I'm integrating a Front End built in React with an Api built with GraphQL.

I have the following text in the Api documentation for a DateTime field that I need to send in a Mutation:

timeRegistered: DateTime

A date-time string at UTC, such as 2007-12-03T10:15:30Z, compliant with the date-time format outlined in section 5.6 of the RFC 3339 profile of the ISO 8601 standard for representation of dates and times using the Gregorian calendar.

scalar DateTime

I'm also using Material UI and Date-FNS to get the Date Time picker to work. I need to show to the user the date in Brazil format:

janeiro 23º 12:35 p.m

How do I format the Date to that DateTime specific format present in the Docs (RFC 3339)? Because when sending the data to the api I need that format.

  • Perhaps see [*How to format a JavaScript date*](https://stackoverflow.com/questions/3552461/how-to-format-a-javascript-date?r=SearchResults&s=1|1684.5818). `new Date().toLocaleString('pt',{month:'long',day:'numeric',hour:'numeric',minute:'2-digit', hour12: true, timeZone:'America/Fortaleza'});` is close. – RobG Jan 23 '21 at 16:51

1 Answers1

0

This really is a duplicate of How to format a JavaScript date, however here's an example of how to go about it.

As luck would have it, the input timestamp format of YYYY-MM-DDTHH:mm:ssZ is supported by ECMA-262 and should be correctly parsed by all browsers in use so you can use the built–in parser to create a Date object:

let date = new Date('2007-12-03T10:15:30Z');

As for formatting, you can use the Intl.DateTimeFormat.prototype.formatToParts method to get the parts of the date in the language you want, then format them as required.

In the following example:

  1. Language code "pt" for Portuguese is used, I couldn't find a sub-tag for Brazil so I guess there's no variant
  2. In the OP example and in other places I checked, the degree symbol is used to indicate an ordinal for the day number so I've used Unicode +U00B0 degree symbol
  3. I've included the timezone name as Brazilian offsets range from -2 (America/Noronha) to -5 (America/Rio_Branco). Daylight saving was observed in some parts prior to 2019, so the choice of representative location is important if you're showing dates and times before then as DST may affect some locations and not others.

/* Get time in specifid location in Portuguese
 * @param {Date} date - date to format, default is the current date and time
 * @param {string} loc - IANA representative location for date
 * @returns {string} formatted timestamp
 */
function toPTString(date = new Date(), loc = 'America/Sao_Paulo') {

  // Formatter
  let formatPT = new Intl.DateTimeFormat('pt', {
    month: 'long',
    day: 'numeric',
    hour: 'numeric',
    minute: '2-digit',
    hour12: true,
    timeZone: loc,
    timeZoneName: 'short'
  });

  // Values for timestamp
  let {
    day,
    month,
    hour,
    minute,
    dayPeriod,
    timeZoneName
  } = formatPT.formatToParts(date)
    .reduce((acc, part) => {
      acc[part.type] = part.value;
      return acc;
    }, Object.create(null));
  // Reformat dayPeriod, e.g. PM to p.m
  let dP = dayPeriod.toLowerCase().replace(/[^apm]/g, '').split('').join('.');

  // '\u00B0' is the degree symbol for ordinal day number
  return `${month} ${day}\u00B0 ${hour}:${minute} ${dP} ${timeZoneName}`;
}

// Examples
[ null,                 // Defaults to -3
 'America/Noronha',     // -2
 'America/Sao_Paulo',   // -3
 'America/Porto_Velho', // -4
 'America/Rio_Branco'   // -5
].forEach(loc => console.log((loc || 'Default') + ': ' +
  (loc? toPTString(new Date(), loc) : toPTString())
));
  
RobG
  • 124,520
  • 28
  • 153
  • 188